【汇编】GNU编译器常见伪操作(定义变量、定义函数、条件编译)

伪操作不会生成机器码,只是在编译阶段告诉编译器怎么做。类似于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 FUNC

FUNC:
    MOV R1, #1
    MOV 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 FUNC
    MOV R1, #0xFF
    MOV R2, #0x01
.endm

6、.if  ...  .endif(条件编译)

使用方法和C语言一样,只是把“ # ”换成了“ . ”

格式:

         .if   条件

               ...

        .endif

.if 0                   @该段不会参与编译
    MOV R1,  0xFF
    MOV R2, 0x01
.endif

7、.rept  ...  .endr(重复生成机器码)

可以看作是将其范围内的指令重复执行了多次。

格式:

        .rept   重复次数             

                ...

        .endr

.rept  3                @ 生成三段重复的机器码
    MOV R1,  0xFF
    MOV R2, 0x01
.endr

8、.arm / .thumb / .text / .end

.arm:告诉编译器,这之后的指令都是ARM指令

.thumb:告诉编译器,这之后的指令都是THUMB指令

.text:表示之后是代码段

.end:表示汇编结束

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值