ARM GNU中汇编器指令.endr的详细用法
好的,我们来专门讲解 ARM 汇编语言(GNU 汇编器语法)中 .endr 伪指令的用法。它的作用非常简单,但至关重要。
1. .endr 的核心作用:结束一个重复块
.endr 伪指令有且仅有一个功能:标记一个重复代码块的结束边界。
它自己没有任何独立的功能,必须与 .rept 或 .irp/.irpc 伪指令成对出现,就像编程语言中的 } 必须与 { 配对一样。
简单比喻:
.rept 5像是说:“开始复印,复印 5 份”。.endr像是说:“好了,就复印到这里为止”。- 它们之间的所有代码就是需要被复印的内容。
 
2. 语法和用法
.endr 的语法极其简单,它不需要任何参数:
.rept <number_of_times>   @ 重复块的开始
    @ 这里是要被重复的代码或数据
    nop                  @ 例如,重复生成 nop 指令
    .word 0xDEADBEEF     @ 或者重复生成数据
.endr                    @ 重复块的结束(这就是 .endr 的用法)
关键规则:
- 必须成对出现:每一个 
.rept都必须有一个对应的.endr来关闭它。 - 位置:
.endr独自占一行,标志着重复块的结束。 - 嵌套:
.rept/.endr块可以嵌套使用,但必须像括号一样正确匹配。 
3. 与不同指令的配对使用
.endr 主要用于结束以下两种重复伪指令定义的块:
1. 与 .rept 配对 (固定次数重复)
这是最常见的使用场景,用于将一段代码重复汇编指定的次数。
@ 示例 1:生成软件延时循环
.text
delay_cycles:
    .rept 100        @ 开始重复块,指定重复100次
        nop          @ 这是被重复的内容
    .endr            @ 结束重复块。此处生成了100条nop指令
    bx lr
@ 示例 2:初始化一个数据数组
.data
my_array:
    .rept 64         @ 开始重复块,指定重复64次
        .word 0      @ 这是被重复的内容
    .endr            @ 结束重复块。此处分配了64个全0的字
2. 与 .irp 或 .irpc 配对 (参数化重复)
.irp ( iterate by argument list) 和 .irpc (iterate by string) 是更高级的重复指令,它们会遍历一个参数列表或字符串,为每次遍历执行一次重复块。
@ 使用 .irp - 遍历参数列表
@ 这将依次为 'r0', 'r1', 'r2' 生成代码
.irp reg, r0, r1, r2     @ 开始迭代重复块,参数列表为 r0, r1, r2
    push {\reg}          @ 这是被重复的内容,使用 \reg 引用当前参数
.endr                    @ 结束迭代重复块。此处生成了 push {r0}; push {r1}; push {r2}
@ 使用 .irpc - 遍历字符串中的字符
@ 这将依次为 'a', 'b', 'c' 生成代码
.irpc letter, abc        @ 开始迭代重复块,字符串为 "abc"
    .byte '\letter'      @ 这是被重复的内容,使用 \letter 引用当前字符
.endr                    @ 结束迭代重复块。此处生成了 .byte 'a'; .byte 'b'; .byte 'c'
在这些例子中,.endr 的作用完全相同:标记由 .irp 或 .irpc 开始的迭代重复块的结束。
4. 常见错误和注意事项
- 
缺少
.endr:如果只有.rept而没有对应的.endr,汇编器会报错,因为它不知道重复块在哪里结束。错误:
open repeat at end of file(文件结束时仍有未关闭的重复块) - 
多余的
.endr:如果使用了.endr却没有对应的.rept、.irp或.irpc,汇编器也会报错。错误:
.endr without .reptor similar - 
错误的嵌套:嵌套的
.rept/.endr块必须像括号一样正确匹配。内层的块必须在外层的块结束之前结束。@ 正确嵌套 .rept 2 @ 外层重复开始 .rept 3 @ 内层重复开始 nop .endr @ 内层重复结束 .endr @ 外层重复结束 @ 错误嵌套 (会导致汇编错误) .rept 2 @ 外层重复开始 .rept 3 @ 内层重复开始 nop .endr @ 错误!这个 .endr 试图关闭外层 .rept,但内层 .rept 还未关闭 .endr @ 
总结
| 要点 | 描述 | 
|---|---|
| 核心作用 | 标记一个重复块的结束。它是一个边界标记符,本身不执行任何操作。 | 
| 必须配对 | 必须与 .rept、.irp 或 .irpc 伪指令成对出现。 | 
| 语法 | 单独一行,写上 .endr即可,无任何参数。 | 
| 主要用途 | 结束由上述指令定义的重复块,告诉汇编器:“重复到此为止”。 | 
| 重要性 | 缺少或错配 .endr 会导致严重的汇编错误,编译无法通过。 | 
简单来说:.endr 就像是重复块的“关闭标签”。 它的用法非常单一和固定,但却是构建复杂重复结构不可或缺的一部分。只要你使用 .rept 或其他迭代指令,就一定要记得在合适的位置写上 .endr 来结束它。
                    
                
                
            
        
浙公网安备 33010602011771号