ARM汇编伪指令

ARM 174浏览


1 伪指令的意义

  • 伪指令不是指令,伪指令和指令的根本区别是经过编译后会不会生成机器码(有些伪指令会被转换成对应的汇编指令,再生成相应的机器码,比如ldr伪指令)。
  • 伪指令的意义在于指导编译过程。
  • 伪指令是和具体的编译器相关的,我们使用gnu工具链,因此学习gnu环境下的汇编伪指令。

2 gnu汇编中的一些符号

  • @ 用来做注释。可以在行首也可以在代码后面同一行直接跟,和C语言中//类似
  • # 做注释,一般放在行首,表示这一行都是注释而不是代码。
  • :以冒号结尾的是标号
  • . 点号在gnu汇编中表示当前指令的地址
flag:
    b flag

    b .
  • # 立即数前面要加#或$,表示这是个立即数

3 常用gnu伪指令

  • .global _start @ 给_start外部链接属性
  • .section .text @ 指定当前段为代码段
  • .ascii .byte .short .long .word
  • .quad .float .string @ 定义数据
IRQ_STACK_START:
    .word   0x0badc0de
等价于 unsigned int IRQ_STACK_START = 0x0badc0de;
  • .align 4 @ 以16字节对齐

.align 4 @ 16字节对齐
2^4 .align 2 @ 4字节对齐

  • .balignl 16 0xabcdefgh @ 16字节对齐填充

.balignl 16, 0xdeadbeef @ 对齐 + 填充
b表示位填充;align表示要对齐;l表示long,以4字节为单位填充;16表示16字节对齐;0xdeadbeef是用来填充的原料。

0x00000008: .balignl 16, 0xdeadbeef 0x0000000c 0xdeadbeef
0x00000010: 下一条指令

  • .equ @ 类似于C中宏定义

4 偶尔会用的gnu伪指令

  • .end @标识文件结束
  • .include @ 头文件包含
  • .arm / .code32 @声明以下为arm指令
  • .thumb / .code16 @声明以下为thubm指令

5 adr与ldr

  • adr编译时会被1条sub或add指令替代,而ldr编译时会被一条mov指令替代或者文字池方式处理;
  • adr总是以PC为基准来表示地址,因此指令本身和运行地址有关,可以用来检测程序当前的运行地址在哪里
  • ldr加载的地址和链接时给定的地址有关,由链接脚本决定。

ldr指令: ldr r0, #0xff
伪指令: ldr r0, =0xfffl @涉及到合法/非法立即数,涉及到ARM文字池

adr和ldr的差别:ldr加载的地址在链接时确定,而adr加载的地址在运行时确定;所以我们可以通过adr和ldr加载的地址比较来判断当前程序是否在链接时指定的地址运行。