跳转至

第五章、ARM汇编语言编程⚓︎

约 984 个字 40 行代码 预计阅读时间 5 分钟

Chapter1、数据处理指令⚓︎

功能:完成寄存器数据的算术和逻辑操作
原则:操作数32位,来源寄存器/立即数,结果存放寄存器,三地址模式

算数操作

Text Only
1
2
3
4
5
6
- ADD r0,r1,r2    ; r0:=r1+r2
- ADC r0,r1,r2    ; r0:=r1+r2+C
- SUB r0,r1,r2    ; r0:=r1-r2
- SBC r0,r1,r2    ; r0:=r1-r2+C-1
- RSB r0,r1,r2    ; r0:=r2-r1
- RSC r0,r1,r2    ; r0:=r2-r1+C-1
按位逻辑操作
Text Only
1
2
3
4
- AND r0,r1,r2    ; r0:=r1 and r2
- ORR r0,r1,r2    ; r0:=r1 or r2
- EOR r0,r1,r2    ; r0:=r1 xor r2
- BIC r0,r1,r2    ; r0:=r1 and not r2
寄存器传送操作
Text Only
- MOV r0,r2    ; r0:=r2
- MVN r0,r2    ; r0:=not r2

比较操作:不产生输出,只影响 CPSR 标志位(条件码)

Text Only
1
2
3
4
- CMP r1,r2    ; 根据 r1-r2 的结果设置 cc
- CMN r1,r2    ; 根据 r1+r2 的结果设置 cc
- TST r1,r2    ; 根据 r1 and r2 的结果设置 cc
- TEQ r1,r2    ; 根据 r1 xor r2 的结果设置 cc

立即数操作: 通过“#”表示,编码方式,立即数=$ (0 \sim 255) \times 2^{2n} ) ( 0 \leq n \leq 12 )$

移位操作

Text Only
1
2
3
4
5
- ASR #n    算术右移 n 位(补最左边一位)
- LSL #n    逻辑左移 n 位(补零)
- ROR #n    循环右移 n 位
- LSR #n    逻辑右移 n 位(补零)
- RRX       带扩展的循环右移 1 位(带进位)

Chapter2、数据传送指令⚓︎

功能:完成寄存器数据与存储器数据的传送

单寄存器 Load/Store 指令 支持寻址方式:寄存器间接寻址、基址偏移寻址、基址变址寻址

Text Only
- LDR r0,[r1]    ; r0:=mem32[r1](寄存器间接寻址)
- STR r0,[r1]    ; mem32[r1]:=r0

前变址寻址

Text Only
1
2
3
- LDR r0, [r1, #4]    ; r0:=mem32[r1+4]
- LDR r0, [r1, #4]!   ; r0:=mem32[r1+4], r1:=r1+4
感叹号实现基址寄存器自动变址,表示将最后的地址写回到 r1 中。

后变址寻址

Text Only
- LDR r0, [r1], #4    ; r0:=mem32[r1], r1:=r1+4
不能使用感叹号,通过立即数来实现基址寄存器的自动变址
多寄存器 Load/Store 指令
Text Only
- LDMIA r1, {r0,r2,r5}    ; r0:=mem32[r1], r2:=mem32[r1+4], r5:=mem32[r1+8]
传输次序按照 r0-r15 增大顺序,可以用一条指令同时存取多个寄存器、寻址模式更加有限
最近用于: 堆栈寻址(F: full; E: empty; A: ascend; D: download)空/满,递增/递减

  • 满递增:堆栈向上增长,堆栈指针指向内含有有效数据项的最高地址。如 LDMFA、STMFA 等;
  • 空递增:堆栈向上增长,堆栈指针指向堆栈上的第一个空位置。指令如 LDMEA、STMEA 等;
  • 满递减:堆栈向下增长,堆栈指针指向内含有有效数据项的最低地址。如 LDMPD、STMPD 等;
  • 空递减:堆栈向下增长,堆栈指针向堆栈下的第一个空位置。指令如 LDMED、STMED 等。

块拷贝寻址: 多寄存器传送指令用于将一块数据从存储器的某一位置拷贝到另一位置

Text Only
STM(UD)(A/B)>> (I: increase; D: download; A: after; B: before)向上/下增长,在之前/之后变址

Chapter3、控制流指令⚓︎

功能:使指令执行切换到不同的地址

永久转移——转移指令(B): 使处理器由顺序执行指令转移到 Label 处,利用的寻址方式是 PC 相对寻址。

Text Only
1
2
3
B Label
...
Label ...

转移可以有条件进行一条件转移:通过 CPSR 条件码判断转移条件是否满足。

保存返回地址以恢复原来的执行顺序(BL): 在转移到子程序的同时,保存返回地址 r14

Text Only
1
2
3
4
5
6
BL SUBR    ; 转移到 SUBR
...
; 返回到这里

SUBR ...    ; 子程序入口
MOV pc,r14    ; 返回
注意:如果存在子程序嵌套,则必须先保存好 r14!

软件中断指令(SWI): 处理器进入管理(监控)模式,从固定向量地址 0x00000008 取指 通过特定的监控调用才能访问系统级函数,实现受控的保护机制 这些函数包括对外界硬件寄存器的访问,大量的 I/O 操作

Chapter4、指示符与伪指令⚓︎

指示符(ppt41 页): - 符号定义指示符:定义 ARM 汇编程序中的变量、对变量赋值以及定义寄存器的别名等操作。 - 数据定义指示符 - 汇编控制指示符

伪指令: 不属于 ARM 指令集中的指令,是为了编程方便而定义的。伪指令可以像其它 ARM 指令一样使用,但在编译时这些指令将被等效的 ARM 指令代替。

  • ADR 小范围地址读取伪指令:将基于 PC 相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。
    Text Only
      LOOP MOV R1, #0xF0
      ADR R2, LOOP    ; 将 LOOP 的地址放入 R2
    
  • ADRL 中等范围的地址读取伪指令:比 ADR 有更大的取地址范围
  • LDR 大范围的地址读取伪指令:用于加载 32 位的立即数或一个地址值到指定寄存器
    Text Only
    LDR R0, =0x12345678    ; 加载 32 位立即数 0x12345678
    
  • NOP 伪指令

Chapter5、汇编语言的程序结构⚓︎

注释用:打头,ENTRY 伪指令标识程序的入口点,接下来为指令序列。结尾用到 END 伪代码,每一个汇编程序段都必须有一条 END 伪指令,指示代码段的结束。

以程序段为单位组织代码。段是相对独立,具有特定的名称。可以分为代码段和数据段,代码段的内容为执行代码,数据段存放代码运行时需要用到的数据。一个汇编程序至少应该有一个代码段。