基础的汇编指令学习
转载请标注出处:CSDN
ADD R11, SP, #4 //R11 = SP+4 // 相加运算
SUB SP, SP, #0x9 // sp=sp-9;// 减法运算
STR R3, [R11, #a] //把值加载到内存
MOV R0, #0X1 ;初始化R0=1
MOV R1, #0X3 ;初始化R1=3
CMP R0, R1 ;判断R0>R1? CMP是比较的意思应该等同于if语句
MOVHI R2, #100 ;成立(R0>R1) R2 = 100
MOVLS R2, #10 ;不成立(R0
ARM 指令记录
助记符 指令功能描述
ADC 带进位加法指令
ADD 加法指令
AND 逻辑与指令
B 跳转指令
BIC 位清零指令
BL 带返回的跳转指令
BLX 带返回和状态切换的跳转指令
BX 带状态切换的跳转指令
CDP 协处理器数据操作指令
CMN 比较反值指令
CMP 比较指令
EOR 异或指令
LDC 存储器到协处理器的数据传输指令
LDR 存储器到寄存器的数据传输指令 与STR相反
LDM 加载多个寄存器指令
MCR 从ARM寄存器到协处理器寄存器的数据传输指令
MRC 从协处理器寄存器到ARM寄存器的数据传输指令
MLA 乘加运算指令
MOV 数据传送指令
MRS 传送CPSR或SPSR的内容到通用寄存器指令
MSR 传送通用寄存器到CPSR或SPSR的指令
MUL 32位乘法指令
MLA 32位乘加指令
MVN 数据取反传送指令
ORR 逻辑或指令
RSB 逆向减法指令
RSC 带借位的逆向减法指令
SBC 带借位减法指令
STC 协处理器寄存器写入存储器指令
STM 批量内存字写入指令
STR 寄存器到存储器的数据传输指令 与LDR相反
SUB 减法指令
SWI 软件中断指令
SWP 交换指令
TEQ 相等测试指令
TST 位测试指令
指令的条件域
条件码 助记符后缀 标志 含义
0000 EQ Z置位 相等
0001 NE Z置位 不相等
0010 CS C置位 无符号数大于或等于
0011 CC C清零 无符号数小于
0100 MI N置位 负数
0101 PL N清零 正数或零
0110 VS V置位 溢出
0111 VC V清零 未溢出
1000 HI C置位Z清零 无符号数大于
1001 LS C清零Z置位 无符号数大于或等于
1010 GE N等于V 带符号数大于或等于
1011 LT N不等于V 带符号数大于
1100 GT Z清零且(N等于V) 带符号数大于
1101 LE Z位置或(N不等于V) 带符号数小于或等于
1110 AL 忽略 无条件执行
寄存器学习
寄存器
R0-Rn 每一个都代表一个独立的32位信息
SP 代表当前堆栈位置,堆栈内保存的是临时信息
LR 带有返回值的跳转指令
PC 当前程序执行的位置
N Z C V Q F T MODE 标志寄存器,用于表是否跳转
显示opcode(指令助记符)的位二进制
IDA -> Options -> Gengral -> Disassembly[Number for opcode bytes(non-graph)] 输入4 点 ok
指令
PUSH {R7,LR} 代表把RL和R7的地址压入堆栈中
SUB SP,SP,#0x10 代表把SP减去10 【SP = SP - 10】 可以说是开辟SP的堆栈空间
用于存放临时变量
ADD R7,SP,#0 代表改变R7的位置【R7 = SP + 0 / R7 = SP】
var_4 = -4
var_8 = -8
STR R0,[R7,0x10+var_4] 代表修改R0的位置等于R7的位置加上0x10再加4 (R0=R7+(0x10-4))
STR R1,[R7,0x10+var_8] 代表修改R1的位置等于R7的位置加上0x10再加8 (R0=R7+(0x10-8))
LDR R0,[R7,0x10+var_4] 代表把R7+0x10+var_4的地址加载到R0上
LDR R3,=(aFunction-0x75792E18) 代表R3是一个方法的地址
ADD R3,PC 指令上的意思是R3=R3+PC 实际意思是重定位,把当前位置移动到R3上,也就是aFunction的位置
MOV R1,R3 代表把R3的值赋给R1
BL bFunction;代表BL可以执行bFunction的功能
MOV R3,R0 上一条语句使用到的是BL指令(带结果的跳转) R0代表aFunction的地址赋值给R3
NOP 什么都不做
MOV R0,R3
ADDS R7,#0x10 R7+10
MOV SP,R7 R7的值赋给SP,资源释放
POP {R7,PC} 出栈
R7,栈帧指针;指向前一个保存的栈帧(stack frame)和链接寄存器(link register,lr)在栈上的地址。
R13,又叫SP(stack pointer)是栈顶指针。
R14,又叫LR(link register)存放函数的返回值
R15,又叫PC(program counter)指向当前指令地址
mov r0, r1 // r0 = r1;
mov r0, #10 // r0 = 10
ldr r0, [sp] // r0 = *sp 磁盘数据加载到内存
str r0, [sp] // *sp = r0 内存数据保存到磁盘
STR 把寄存器内容存到栈上去
ldr 把栈上内容载入一寄存器中
add r0, r1, r2 // r0 = r1+r2
add r0, r1 // r0 = r0+r1
push {r0, r1, r2} // 将r0,r1,r2压栈
pop {r0, r1, r2} // 将r0,r1,r2出栈,结果存储到r0,r1,r2中
b_label // pc = _label
bl_label // lr = pc + 4; pc = _label
self和_cmd占用了r0和r1寄存器。
arm寻址方式
1). 寄存器: MOV R1,R2 ; R2->R1
2). 立即数: SUBS R0,R1,#1; R0=R1-1
3). 寄存器移位:MOV R0,R2,LSL #3 ;R2左移三位->R0
4). 间接寻址: LDR R1,[R2] ; 装载R2指向的内存数值至R1
5). 基址寻址: LDR R2,[R3,#0x0F] ;R3+0x0F作为地址,将所
指向的值装入R2、R3的值不改变
6). 多寄存器寻址: LDMIA R1!,{R2-R7,R12} ; 将R1所指向的内
存块依次装入{}中的寄存器。
STMIA R0!,{R3-R6,R10} ;将{}列出的寄存器里的值依次填入R0所指向的内存块。
7). 相对寻址: BL XXX ;跳转
BEQ XXX ;条件跳转
!的作用:
ldmia r0, {r2 - r3}ldmia r0!, {r2 - r3}
感叹号的作用就是r0的值在ldm过程中发生的增加或者减少最后写回到r0去,也就是说ldm时会改变r0的值。
^的作用:
ldmfd sp!, {r0 - r6, pc}ldmfd sp!, {r0 - r6, pc}^
^的作用:在目标寄存器中有pc时,会同时将spsr写入到cpsr,一般用于从异常模式返回。