ARM常用汇编指令集
我们经常在调试ARM芯片的时候遇到这样那样问题,
但大部分时间需要去看反汇编代码。
这时汇编的功底不行就很难看懂里面具体讲的是什么,
今天我们需要讲解一些调试过程中常用的汇编指令。
常用汇编指令:
(1)相对跳转指令
b ;跳转
bl ;除了跳转之外,还将返回(bl下一条指令的地址)保存在lr寄存器中。
注:b bl这两条指令跳转范围是前后2MB
(2)数据传送指令MOV,地址读取伪指令ldr
mov r1, r2 ;mov把一个寄存器的值赋给另一个寄存器 r1 = r2
mov r1, #4096 ;mov传送的常数必须能用立即数表示 r1 = 4096
ldr r1, =4097 ;伪指令,并不是真实存在的指令。编译器会把它扩展成真正的指令。
;r1 = 4097
ldr r1, =label ;获取代码的绝对地址
label:
…
(3)内存访问指令:ldr、str、ldm、stm
注:ldr既可以当读取地址的伪指令,也可以是内存访问指令。当第二个参数前面有”=”时,表示伪指令。否则表示内存访问指令。操作数都是32bits的。
ldr r1, [r2, #4] ;将r2+4的内存单元数据读取到r1中
ldr r1, [r2] ;将地址为r2的内存单元数据读取到r1中
ldr r1, [r2], #4 ;将r2内存单元中的数据读取到r1中,然后r2 = r2+4(值+4)
str r1, [r2, #4] ;将r1内存单元中的数据保存到[r2+4]中
str r1,[r2] ;将r1内存单元的数据保存到r2中
str r1, [r2], #4 ;将r1的数据保存到地址为r2的内存单元中,然后r2=r2+4
ldm和stm属于批量内存访问指令,只用一条指令就可以读写多个数据。
ldm{cond}<addressing_mode> <rn>{!} <register list>{^}
stm{cond}<addressing_mode> <rn>{!} <register list>{^}
{cond}表示指令执行条件。
<addressing_mode>表示地址变化模式,以下4种方式:
<1>ia(increment after): 事后递增方式
<2>ib(increment brefore): 事先递增方式
<3>da(decrement after): 事后递减方式
<4>db(decrement before): 事先递减方式
<rn>中保存内存的地址,如果后面加了感叹号,指令执行后,rn的值会更新,等于下一个特内存单元的地址
<register_list>表示寄存器列表,对于ldm指令,<rn>所对应的内存块中取出数据,写入这些寄存器;对于stm指令,把这些寄存器的值写入到<rn>所对应的内存块中。
{^}有两种含义:
(1)如果<register list>中有PC寄存器,{^}表示指令执行后,spsr寄存器的值将自动复制到cpsr寄存器中----这常用于从终端处理函数的返回;
(2)如果<register list>中没有PC寄存器,{^}表示操作的是用户模式下的寄存器,而不是当前特权模式下的寄存器。
在上述stm,ldm指令中寄存器列表和内存单元的对应关系为:编号低的寄存器对应内存中的低地址单元,编号高的寄存器对应内存中的高地址单元。
协处理器指令:
mrc/mcr
<MCR|MRC>{cond} p#,<expression1>,Rd,cn,cm{,<expression2>}
MRC 从协处理器移到ARM7寄存器(L=1)
MCR 从ARM7寄存器移到协处理器(L=0)
{cond} 两个字符的条件代码
p# 被请求得协处理器的惟一标识苻
<expression1> 计算一个常量并放到CP Opc域
Rd 是一个表达式计算ARM7有效寄存器序号
cn 和cm 是计算有效协处理器寄存器CRn CRm序号
<expression2> 计算一个常量,并放到CP域
举例说明一下:
MRC 2,5,R3,c5,c6 ;请求协处理器2 执行操作5 ,操作数为c5和c6,
; 传送结果到R3 (单次32位字)
MCR 6,0,R4,c6 ; 请求协处理器6执行操作0,操作数为R4
;结果送到c6
(4)加减指令:add、sub
add r1, r2, #1 ;r1 = r2 + 1,r2的值+1
sub r1, r2, #1 ;r1 = r2 – 1
(5)程序状态寄存器的访问指令:msr、mrs
Arm中有一个程序状态寄存器(cpsr),它用来控制处理器的工作模式、设置中断的总开关。
msr cpsr, r0 ;复制r0到cpsr中
mrs r0, cpsr ;复制cpsr到r0中
(6)其他伪指令格式
.extern :定义一个外部符号(可以是变量或者函数)。
.text:表示下面的语句都属于代码段。
.global:将本文件中的某个程序标号定义为全局的。
(7)汇编指令执行条件