Label

目录

基本概念

标签是汇编语言中的符号名称,用于标记代码或数据在内存中的位置。它代表一个地址,让程序员可以通过名称而不是硬编码的地址来引用位置。

语法格式

标签名称:
    指令

标签示例

代码标签

main:
    MOV R0, #10
    B   exit        @ 跳转到exit标签

loop:
    ADD R0, R0, #1
    CMP R0, #20
    BNE loop        @ 跳转回loop标签

exit:
    BX LR

数据标签

data_area:
    .word 0x12345678    @ 定义一个字数据
    .byte 0xAA          @ 定义一个字节数据

text_string:
    .asciz "Hello"      @ 定义字符串

标签的特点

地址替代

@ 编译器会将标签转换为实际地址
start:              @ 假设地址为0x08001000
    MOV R0, #1
    B   target      @ 实际编译为 B 0x08001008

target:             @ 地址0x08001008
    MOV R1, #2

作用域

  • 局部标签:通常在当前文件内可见
  • 全局标签:使用.global声明,对其他文件可见
.global main        @ 声明为全局标签,链接器可见

main:
    @ 程序入口

标签的实际用途

流程控制

    CMP R0, #0
    BEQ zero_case   @ 如果等于0跳转到zero_case标签
    B   non_zero    @ 否则跳转到non_zero标签

zero_case:
    MOV R1, #0
    B   end

non_zero:
    MOV R1, #1

end:
    @ 继续执行...

循环结构

    MOV R0, #0          @ 计数器
loop_start:             @ 循环开始标签
    ADD R0, R0, #1
    CMP R0, #10
    BLT loop_start      @ 如果R0 < 10,继续循环

函数定义

calculate_sum:          @ 函数标签
    ADD R0, R0, R1
    BX  LR

main:
    MOV R0, #5
    MOV R1, #3
    BL  calculate_sum   @ 调用函数

数据访问

    LDR R0, =data_table @ 获取数据表地址
    LDR R1, [R0]        @ 加载第一个数据

data_table:
    .word 100, 200, 300 @ 数据定义

标签的类型

代码标签

标记可执行代码的位置,用于跳转和调用。

数据标签

标记数据存储的位置,用于加载和存储操作。

局部标签

某些汇编器支持数字局部标签:

1:
    @ 代码...
    B   1b      @ 向后跳转到最近的1标签
    B   1f      @ 向前跳转到下一个1标签
1:
    @ 另一个1标签
    B   1b      @ 跳转到前一个1标签

标签的命名规则

有效标签名

main:
loop1:
_data_start:
_function_123:

无效标签名

1label:        @ 不能以数字开头
my-label:      @ 不能包含连字符
my.label:      @ 不能包含点号除非特殊用途

标签在反汇编中的表现

反汇编显示

; 有标签的情况
0x08001000 main:
0x08001000 200A          MOVS    R0, #10
0x08001002 E002          B       exit

0x08001004 loop:
0x08001004 3001          ADDS    R0, #1

0x08001006 exit:
0x08001006 4770          BX      LR

; 无标签的情况
0x08001000 200A          MOVS    R0, #10
0x08001002 E002          B       0x08001006
0x08001004 3001          ADDS    R0, #1
0x08001006 4770          BX      LR

特殊用途标签

段标签

.text                   @ 代码段开始
.global _start
_start:
    @ 代码...

.data                   @ 数据段开始
variables:
    .word 0, 0, 0

.bss                    @ 未初始化数据段
buffer:
    .space 256

对齐标签

    .align 2            @ 4字节对齐
aligned_data:
    .word 0x12345678

    .align 3            @ 8字节对齐
double_aligned:
    .dword 0x123456789ABCDEF0

标签与地址计算

地址差计算

start:
    @ 一些代码...
end:
    @ 计算代码大小
    LDR R0, =end
    LDR R1, =start
    SUB R2, R0, R1      @ R2 = 代码大小

相对地址引用

    ADR R0, data_table  @ 获取相对地址
    LDR R1, [R0]        @ 加载数据

data_table:
    .word 0x12345678

常见标签使用模式

条件分支

    CMP R0, #100
    BGT greater_than    @ 如果大于跳转
    BLT less_than       @ 如果小于跳转
    BEQ equal           @ 如果等于跳转

greater_than:
    MOV R1, #1
    B   end_compare

less_than:
    MOV R1, #-1
    B   end_compare

equal:
    MOV R1, #0

end_compare:
    @ 继续执行...

跳转表实现

    CMP R0, #3
    BHS default_case    @ 如果>=3跳转到默认情况
    LDR PC, [PC, R0, LSL #2]  @ 跳转到对应处理程序
    B   end_switch

jump_table:
    .word case0, case1, case2

case0:
    @ 情况0处理
    B   end_switch

case1:
    @ 情况1处理
    B   end_switch

case2:
    @ 情况2处理
    B   end_switch

default_case:
    @ 默认处理

end_switch:
    @ 继续执行...

调试信息中的标签

带调试符号

.LFB0:                  @ 函数开始标签
    .loc 1 10 0         @ 文件110
    push    {r7, lr}

.LBB2:                  @ 基本块开始
    .loc 1 11 0
    movs    r0, #10

.LBE2:                  @ 基本块结束
    .loc 1 12 0
    pop     {r7, pc}
.LFE0:                  @ 函数结束标签

标签是汇编编程的基础构建块,它们使代码更易读、易维护,并提供了地址引用的抽象层。