伪操作不会生成机器码,只是在编译阶段告诉编译器怎么做。类似于C语言中的 #if、#define 等带“#”的,#if 告诉编译器哪段不需要被编译,#define 告诉编译器哪些宏需要替换。
不同编译器,伪操作的语法不一样,这里主要介绍GNU编译器的伪操作。GNU伪操作一般以 “ . ” 开头。括号里的内容表示当前伪操作可被理解成C语言中的哪些内容 或者 该伪操作的含义。
目录
1、.global / .local(全局 / 局部变量)
2、.equ(宏定义)
3、.byte / .word / .space(动态申请空间)
4、.weak(符号弱化)
5、.macro ... .endm(函数定义)
6、.if ... .endif(条件编译)
7、.rept ... .endr(重复生成机器码)
8、.arm / .thumb / .text / .end
1、.global / .local(全局 / 局部变量)
.global 用于定义全局符号,以便于被其他文件引用;.local 用于定义局部符号, 仅在当前文件使用。类似于C语言中的全局变量或者局部变量的声明。
全局符号声明格式:.global 符号
局部符号声明格式:.local 符号
@ 全局 / 局部
@ .local FUNC
.global FUNCFUNC:MOV R1, #1MOV R2, #2
2、.equ(宏定义)
.equal 类似于C语言中的宏定义,达到的效果是一样的。如果操作寄存器时,有多个地方要用到同一个值,这时可以使用 .equal
格式:.equ 符号名, 值
.equ DATA, 0x01 @ 类似于C中的 #define DATA 0x01
MOV R1, #DATA
3、.byte / .word / .space(动态申请空间)
这三个伪操作的含义如下:
- .byte 申请一个字节的空间并初始化;
- .word 申请一个字(4个字节)的空间并初始化;
- .space 申请任意字节的空间并初始化
这里和C语言不一样,在哪使用了.byte/.word,就会直接在上一条指令的后面申请相应大小的空间,编译器在把指令放到内存中时,会自动跳过这块空间。
(1) .word
格式:.word 初始值
MOV R1, #1
.word 0xFFFFFFFF @ 申请一个字的空间,并初始化为0xFFFFFFFF
MOV R2, #2
“ MOV R1, #1 ”生成的指令放在了 0x00000000 的位置;
.word申请的空间紧跟其后,起始地址为 0x00000004;(编译器在存放指令时跳过了该空间)
“ MOV R2, #2 ”生成的指令放在了 0x00000008 的位置
(2) .byte
格式:.byte 初始值
指令在被放到内存的时候,需要满足对齐原则,即起始地址必须是 4 的整数倍,这里如果只申请一个字节的空间,放在了 0x00000004 的位置,下一条指令就会放在 0x00000005 的位置,很显然不满足对齐原则。
因此,使用.byte不能照搬上面的写法。
MOV R1, #1
.byte 0xFF @ 申请一个字节的空间,并初始化为0xFF
.align 2 @ 表示该语句后续的语句自动对齐
MOV R2, #2
注意: .align N 表示按照 2的N次方自动对齐
(3) .space
.space 可以申请任意字节的空间并初始化。
格式:.space 字节数, 初始值
MOV R1, #1
.space 12, 0x34
MOV R2, #2
4、.weak(符号弱化)
.weak 表示弱化一个符号,如果在程序里使用了一个未被定义的符号,让编译器不要报错。此时编译器会对用到该符号的语句做一个特殊操作,该语句会替换为NOP,也就是做一个空操作
格式:.weak 符号
.weak FUNC
B FUNC @ FUNC 未被定义(编译时,该句会执行一个空操作,相当于sleep(10))
5、.macro ... .endm(函数定义)
.macro 和 .endm是成对存在的,其作用相当于定义一个函数。
格式:
.macro 函数名
...
.endm
.macro FUNCMOV R1, #0xFFMOV R2, #0x01
.endm
6、.if ... .endif(条件编译)
使用方法和C语言一样,只是把“ # ”换成了“ . ”
格式:
.if 条件
...
.endif
.if 0 @该段不会参与编译MOV R1, 0xFFMOV R2, 0x01
.endif
7、.rept ... .endr(重复生成机器码)
可以看作是将其范围内的指令重复执行了多次。
格式:
.rept 重复次数
...
.endr
.rept 3 @ 生成三段重复的机器码MOV R1, 0xFFMOV R2, 0x01
.endr
8、.arm / .thumb / .text / .end
.arm:告诉编译器,这之后的指令都是ARM指令
.thumb:告诉编译器,这之后的指令都是THUMB指令
.text:表示之后是代码段
.end:表示汇编结束