关于汇编语言主要需要理解两个问题,一个是寻址方式,用来知道指令传达的是什么内容,另一个就是指令,需要知道实现了什么功能。先从寻址方式讲起,ARM9中需要理解的寻址方式有8种(考试只考7种)。指令根据英语意思可以大致理解含义,主要就是加,减,乘四种运算,但是运算的方向和指令有关。
寻址方式
名称 | 表达式 | 含义 |
---|---|---|
寄存器寻址 | MOV R1,R2 | 把R1寄存器的内容移送到R2中去 |
立即数寻址 | MOV R0,#0xFF00 | 把立即数0xFF00移到R0中去,立即数前需要加# |
寄存器移位寻址 | MOV R0,R2,LSL #3 | R2寄存器的内容逻辑左移三位之后送入R0寄存器 |
寄存器间接寻址 | LDR R0,[R2] | 将R2表示的存储单元中的字送入R0寄存器 |
基址寻址 | LDR R2,[R3,#0x0C] | 把R3寄存器内容对应的地址加上0x0C之后的地址的内容加载到R2寄存器 |
多寄存器寻址 | LDR R1!,{R2-R4,R6} | 解释看指令 |
堆栈寻址 | LDMIA R0!,{R1-R7} | 将R0指向的数据保存到R1~R7中 |
指令格式
ARM指令格式是32位的,机器码表示可以参考下图
其中四位的cond表示条件码,通过检测状态位判断是否执行某条程序,可以作为循环,判断等条件的底层表示
cond表示图
下面我们看看汇编语言的格式
<opcode> {<cond>} {S} <Rd>,<Rn>,{<operand2>}
其中,尖括号内(<>)表示必须,大括号内({})表示可选。
opcode:指令助记符
cond(condition):执行条件
S(State):是否影响状态寄存器
Rd(Register Destination):目标寄存器
Rn:第一个操作数的寄存器
operand2:第二个操作数
‘!’:结果写回
‘^’:改变状态寄存器
最先需要学习的
最先需要学习的是从存储器到寄存器的加载(load)指令,和寄存器到存储器的存储(store)指令。他们的汇编也很好记,LDR和STR。如果要存储或者加载多个就是multiple,所以加一个m变成LDM和SDM就好了
需要注意的是有个时候指令后面会加B或者H,什么意思呢?就是字节(Byte)和半字(Half)的意思。ARM是32位体系结构,所以字长为32位。一个字节为8位,一个半字为16位。后面加B或者H就表示按照字节或者半字来执行指令。只用在加载和存储中。
关于为什么不用MOV而是用LDR,是因为MOV是同类介质中的,在ARM体系里MOV是用在寄存器和寄存器(或者8位图立即数)之间,而LDR是用在寄存器和存储器之间。
关于加
ADD
ADC
C是带进位的意思
关于减
SUB
RSB
SBC
RSC
R表示Reverse,即用operand2减去Rn
关于乘
MUL
MLA
UMULL
UMLAL
SMULL
SMLAL
后缀带A表示乘加(add)指令,例如MLA Rd,Rm,Rs,Rn
表示Rd=Rm*Rs+Rn 。注意后缀不带L(Large)的都是32位乘法,会舍弃乘法结果的高32位。U和S前缀表示无符号(unsigned)和有符号(signed)
关于逻辑运算
AND
ORR
EOR
BIC
与,或,异或没什么好说的。最后一个是比特清零,bit clear BIC Rd, Rn, operand2
表示Rd=Rn&(~operand2)
关于分支指令B
B
BL
BX
Branch
Branch Link
Branch Change
BX表示状态切换的指令,后面跟的是寄存器表示的地址BX Rm
,ARM指令是字对齐的,最低两位通常为0(字节为单位),此时如果最低位为1表示进入Thumb状态。伪指令ADR可以把地址存到寄存器中来
关于更改状态寄存器
MSR
MRS
State——Register
Register——State
因为第一个是目的地址,所以MSR是写,MRS是读。注意如果要更改状态寄存器的话,要先读入在改写以免破坏系统
关于汇编和c语言的互相调用
c语言里面加一个_asm{}
汇编里面IMPORT或者EXPORT