内容简介:Web狗的临时抱佛脚——ARM汇编笔记
pwnable上的leg那一题的gdb调试记录,就使用了ARM汇编的知识,作为一个有自知之明的Web狗,立马滚去谷歌ARM汇编的基础知识去了。这边记录一下。
顺便插一句,这是从另外一位仁兄那里总结过来的,他的笔记很不错,回来继续学习一下。
0X01 寻址方式
1. 立即寻址
mov r0, #1234
相当于: r0=#1234
。 #
开头。表示16进制时,以 0x
开头,如 #0x1f
2. 寄存器寻址
mov r0, r1
执行后,r0=r1。
NOP操作通常为 mov r0, r0
,对应的HEX为 00 00 a0 e1
3. 寄存器你移位寻址
寄存器移位寻址支持以下5种位移操作:
- LSL:逻辑左移,移位后寄存器空出的低位补0;
- LSR:逻辑右移,移位后寄存器空出的高位补0;
- ASR:算数右移,移位过程中,符号位保存不变,如果源操作数为正数,则移位后空出的高位补0,否则补1。
- ROR:循环右移,移位后,移出的低位,填入移位空出的高位
- RRX:带扩展的循环右移,操作数右移一位,移位空出的高位,用C标志的值填充。
mov r0, r1, lsl #2
相当于: r0 = r1<<2 = r1*4
。
4. 寄存器间接寻址
ldr r0, [r1] //取值
相当于: r0 = *r1
。
5. 基址寻址
ldr r0, [r1, #-4]
相当于: r0 = *(r1-4)
。
6. 多寄存器寻址
lmdia r0, {r1, r2, r3, r4}
LDM是数据加载指令,指令的后缀IA表示,每次执行完成加载操作后,R0寄存器的值自增1个字。
R1=[R0],R2=[R0+#4],R3=[R0+#8],R4=[R0+#12]
字表示一个32位的数值。
7. 堆栈寻址
它需要特定的指令完成:
LMDFA/STMFA,LDMEA/STMEA,LDMFD/SDMFD,LDMED/STMED。
LMD/STM表示多寄存器寻址,一次可以传送多个寄存器值。
stmfd sp!, {r1-r7, lr} @将 r1~r7, lr压栈。多用于保存子程序现场。 ldmfd sp!, {r1-r7, lr} @将 r1~r7, lr出栈,放入r1~r7,lr。多用于恢复子程序现场。
8. 块拷贝寻址
可实现连续地址数据从存储器的某一位置拷贝至另一位置。
LDMIA/STMIA,LDMDA/STMDA,LDMIB/STMIB,LDMDB/STMDB。
LDM/SDM表示多寄存器寻址,一次可以传送多个寄存器值。
ldmia r0!, {r1-r3} @ 从r0指向的区域的值取出来,放到r1-r3中。 stmia r0!, {r1-r3} @ 将r1-r3的值取出来,放入r0指向的区域。
9. 相对寻址
相对寻址以PC的当前值为基址,与偏移值相加,得到最终的地址。
0x02 寄存器
ARM汇编有16个寄存器:
- r0-r3 主要用来传递函数调用第1到第4个参数(a0-a3),更多的参数须通过栈来传递。
- r0-r1 也作为结果寄存器,保存函数返回结果;被调用的子程序在返回前无须恢复这些寄存器的内容。
- r4-r9 为被调保存(callee-save)寄存器,一般保存内部局部变量(local variables)。
- r7 大部分情况用来保存系统调用号(syscall number)。
- r9 某些变体可能当作特殊寄存器。
- r10(SL)被调保存寄存器,Stack Limit。
- r11(FP)被调保存寄存器, 帧指针(Flame Pointer)。
- r12(IP)特殊寄存器,栈寄存器(Intra Procedure)。
- r13(SP)特殊寄存器,栈指针,类似x86_64中的RSP。
- r14(LR)特殊寄存器。Link Register.
- r15(PC)特殊寄存器。Program Counter (like RIP in x86_64 & EIP in x86).
被调保存寄存器是指,如果这个寄存器被调用/使用之前,需要被保存。
1. 特殊寄存器
-
r7/r11:FP或Flame Pointer(帧指针)
通常ARM模式下r11会作为帧指针,THUMB模式下r7则作为帧指针。但在系统有可能根据自己的需要改变这个约定。
-
r12:IP或Intra-Procedure 栈寄存器(stack register)
该寄存器会被链接器当做擦写寄存器在工程调用之间使用。
可擦除寄存器是指数据寄存器r0,r1,r2,r3。
一个过程在返回时,不能修改它的值。这个寄存器不会被Linux gcc或glibc使用,但是另外一个系统可能会。
-
r14:LR 或 Link Register(链接寄存器)
寄存器R14用于从子程序存储返回地址。在其他时间,LR可以用于其他目的。
-
r15:PC 或 Program Counter(程序计数器)
该寄存器保存目前正在执行的内存地址。
PC和LR都是跟代码有关的寄存器,一个是Where you are,另一个是Where you were。
-
r13: SP 或 Stack Pointer(栈指针)
该寄存器指向栈顶。
该栈是一块用来存储本地函数的内存区域。当函数被返回时,存储空间会被回收。
在堆栈上分配空间,需要从栈寄存器减去。
分配一个32位的值,需要从堆栈指针减去4
ARM堆栈结构是从高向低压栈的。
因为处理器是32位的ARM,所以每压一次栈,SP就会移动4个字节(32位),也就是sp=sp-4。
2. SP、FP详解
SP和FP都是跟本地数据相关的寄存器。一个是"Where local data is",另外一个是"Where the last local data is"。
栈帧就是一个函数所在的栈的一部分,所有函数的栈帧串起来就组成了一个完整的栈。
栈帧的两个边界分别由FP和SP来限定,它们2个指向的是当前函数的栈帧。
该图为main函数条用fun1函数的情形,观察func1的栈帧,它的SP和FP之间指向的栈帧就是main函数的栈帧。main函数产生调用时,PC、LR、SP、FP会第一时间压栈。
3. PC与相对取址
ARM 不能像单片机那样,想取某个标签地址,就可以 mov r1,#标签。
因为ARM立即数寻址有限制,最大是4096,再大就只能相对寻址,显然所有的指针都会超过限制,只能间接寻址,所以需要用另一种方式直接算出寻址位置的地址和全局变量位置的相对地址。
ARM7和ARM9都是3级流水线,取指,译指,执行时同时执行的:
- Fetch(从存储器装载一条指令)
- Decode(识别将要被执行的指令)
- Execute(处理指令并将结果写回寄存器)
而R15(PC)总是指向“正在取指”指令,而不是指向“正在执行”的指令或正在“译码”的指令,那么CPU正在译指的指令地址是PC-4(当ARM状态时,每条指令为4字节),CPU正在执行的指令地址是PC-8,也就是说PC所指向的地址和现在所执行的指令地址相差8,即:PC实际值=当前程序执行位置+8。
也就是说:
PC, 总是指向当前正在被取指的指令的地址,
PC-4,总是指向当前正在被译指的指令的地址,
PC-8,总是指向当前的那条指令,即一般说的,正在被执行的指令的地址。
指令的Execute执行阶段,如果用到PC的值,那么PC那一时刻,就是PC=PC+8。
0x03 指令集
1. 分支
当程序需要一些循环、过程(procedures)和函数的时候,会用到分支指令。
实现程序跳转的方法,还可以直接给PC寄存器直接赋值实现跳转。
op1{cond}{.W} label
op2{cond} Rm
其中:
op1
是下列项之一:
B
跳转。
BL
带链接跳转
BLX
带链接跳转并切换指令集。
op2
是下列项之一:
BX
跳转并切换指令集。
BLX
带链接跳转并切换指令集。
BXJ
跳转并转换为 Jazelle 执行。
cond
是一个可选的条件代码。 cond 不能用于此指令的所有形式。
.W
是一个可选的指令宽度说明符,用于强制要求在 Thumb-2 中使用 32 位 B 指令。
label
是一个程序相对的表达式。
Rm
是一个寄存器,包含要跳转到的目标地址。
-
操作
所有这些指令均会引发跳转,或跳转到 label,或跳转到包含在 Rm 中的地址处。 此外:
-
BL 和 BLX 指令可将下一个指令的地址复制到 lr(r14,链接寄存器)中。
-
BX 和 BLX 指令可将处理器的状态从 ARM 更改为 Thumb,或从 Thumb 更改为 ARM。
-
BLX label 无论何种情况,始终会更改处理器的状态。
-
BX Rm 和 BLX Rm 可从 Rm 的位 [
-
如果 Rm 的位 [
-
如果 Rm 的位 [
-
-
BXJ 指令会将处理器的状态更改为 Jazelle。
-
-
ARM有两种工作模式:
- 32位,该状态执行字对准的arm指令;
- 16位,该状态执行半字对准的Thumb指令
-
ARM/thumb之间 函数调用:
-
在同一状态时直接:BL function即可
-
返回也直接用MOV PC,LR
-
不在同一状态要注意以下几点:
-
要用BX,而不用BL
-
BX之前要保存好LR
-
要用BX LR来返回
-
-
2. 数据处理
-
算术:
ADD op1+op2 ADC op1+op2+carry SUB op1-op2+carry-1 syntax : <operation> {<cond>}{S} Rd,Rn,operand examples : ADD r0,r1,r2 SUB R1,R2,#1
-
比较:
CMP op1-op2 TST op1 & op2 TEQ op1 ^ op2 Syntax : <operation> {<cond>} Rn,Op examples : CMP R0,R1 CMP R0,#2
-
逻辑运算:
AND op1,op2 EOR op1,op2 ORR op1,op2
-
移动:
MOV op1,op2 syntax : <Operation>{<cond>}{S} Rn, Op2 Examples: MOV r0, r1
以上所述就是小编给大家介绍的《Web狗的临时抱佛脚——ARM汇编笔记》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- iOS汇编入门教程(一)ARM64汇编基础
- iOS 汇编入门教程(一):ARM64 汇编基础
- iOS汇编入门教程(三)汇编中的 Section 与数据存取
- iOS汇编入门教程(二)在Xcode工程中嵌入汇编代码
- 汇编语言8086笔记
- python编程(反汇编)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
测出转化率:营销优化的科学与艺术
【美】高尔德(Goward,C.) / 谭磊、唐捷译 / 电子工业出版社 / 2014-10-1 / 68.00元
本书作者通过已成功实现大幅提升转化率的案例,展示了大量以营销为核心的电子商务网站的测试设计方法及转化优化方案。书中作者强调了测试及优化思维的重要性,并就实现方法做了详细讲解。 通过本书,读者将学到如何能够在网站遇到发展和收入瓶颈时,测试出存在的问题并找到解决方案;如何可以深入地了解客户需求,并以此为基础优化网站,使其达到提升转化率的目的;如何提升网站的竞争优势,把在线营销渠道变成高效的转化通......一起来看看 《测出转化率:营销优化的科学与艺术》 这本书的介绍吧!