sub 减 sub sp.sp,#16
str 存 str r0,[sp,#12]
ldr 取 ldr r0,[sp ,#12]
add 加 add ro,ro,r1
bx 返回
arm把程序返回结果放在r0
寄存器
在32位的用户模式下,处理器可以访问的寄存器为不分组寄存器r0~r7,分组寄存器r8 ~r14,程序计数器r15m及当前程序状态寄存器cpsr
在arm63-v8a(也就是arm64位)zhon:
1.有异常等级 el0~el3
2.基于5位寄存器说明符的简洁解码表
3,指令语义与aarch32中大致相同
4.提供31个可以随时访问的通用64位寄存器x0~x30
5.提供了无模式GP寄存器组
6.提供了程序计数器(pc)(eip?)和堆栈指针(sp)(esp?)非通用寄存器
7.提供了可用于大多数指令的专用0寄存器xzr/wzr
aarch64的寄存器名为x0~x30,x0 ~x7用于传递参数与计算结果,x8为直接结果位置寄存器,x9 ~ x15为临时寄存器,x16与x17为内部过程调用寄存器,x18为临时寄存器,x19 ~ x28 为调用备份寄存器 x29为帧指针寄存器 , x30为过程链接寄存器PLR使用
lr寄存器存返回地址的
处理器寻址方式
1.立即寻址
MOV R0,#1234 #为前缀0x 表示16进制
2.寄存器寻址
MOV R0,R1 R0=R1
3.寄存器移位寻址
LSL:逻辑左移
LSR:逻辑右移
ASR:算术右移 //最高位不变呗 正还是正 负还是负
ROR:循环右移
RRX;带扩展的循环右移? 没看懂
MOV R0,R1, LSL #2 R0=R1*4
4.寄存器间接寻址
LDR R0,[R1] x86一看就懂
5.基址寻址
LDR R0,[R1, #-4]
6.多寄存器寻址(nb 没见过)
LDMIA R0,{R1,R2,R3,R4} 表示R1=[R0],R2=[R0+#4],R3=[R0+#8],R4=[R0+#12]
7.堆栈寻址(比x86 nb多了)
STMFD SP!,{R1 - R7,LR} @将R1 ~ R7。LR寄存器入栈,多用于保存子程序现场
LDMFD SP!,{R1 - R7,LR} @将数据出栈,,放入R1~R7,LR,多用于恢复子程序现场
8.块拷贝寻址(nb 比86 nb)
LDMIA R0!,{R1 - R3} @从R0寄存器指向的存储单元中读取3个字,将其分别放到R1 -R3寄存器
STMIA R0!,{R1-R3} @将R1 ~ R3寄存器的内容存到R0寄存器指向的存储单元中
9.相对寻址
BL NEXT
...
NEXT:
... BL是相对寻址 next是偏移量
子程序参数传递
armebi(32位):
R0 ~ R3 传递第1个到第4个参数,多出来的用堆栈传递,r0用于存放子程序的返回结果 >32位 R0 R1 (比x86容易记多了。。。)
arm指令编码
感觉没什么必要,没看
常见arm指令
mov
mvn 为数据非传送指令,将8位的立即数或寄存器按位取反后传送到目标
寄存器
MVN R0 ,#0xff @RO=0xffffff00
MVN R1,R2 @将R2寄存器中的数据取反后存入R1寄存器
add,adc,sujb,mul,SDIV(有符号除法指令),UDIV(无符号的除法指令),ASR位算术右移指令,AND,ORR,EOR(异或)
LDR:将数据从存储器加载到寄存器中(load)
STR(store)
(跳转指令B)
B