前言
又是快乐的学习汇编的一天,时间如白驹过隙,抓紧时间,在学习能力最好的年纪多学习一些知识,朝着美好生活而奋斗!哈哈哈
参考文章:
https://blog.csdn.net/Z_H_Z_0/article/details/106574292
知识补充以及简单应用
寄存器方面
R0-R3 用作传入函数参数,传出函数返回值。在子程序调用之间,可以将 r0-r3 用于任何用途。
被调用函数在返回之前不必恢复 r0-r3。如果调用函数需要再次使用 r0-r3 的内容,则它必须保留这些内容。
R4-R11 被用来存放函数的局部变量。如果被调用函数使用了这些寄存器,它在返回之前必须恢复这些寄存器的值。
R12 是内部调用暂时寄存器 ip。它在过程链接胶合代码(例如,交互操作胶合代码)中用于此角色。在过程调用之间,可以将它用于任何用途。被调用函数在返回之前不必恢复 r12。
R13 是栈指针 sp。它不能用于任何其它用途。sp 中存放的值在退出被调用函数时必须与进入时的值相同。
R14 是链接寄存器 lr。如果您保存了返回地址,则可以在调用之间将 r14 用于其它用途,程序返回时要恢复
R15 是程序计数器 PC。它不能用于任何其它用途,可以用于指示当前程序运行到的位置。
ARM处理器的几种模式
- 用户模式,运行应用程序的普通模式。限制你的内存访问并且你不能直接读取硬件设备。
- 超级用户模式(SVC 模式),主要用于 SWI(软件中断)和 OS(操作系统)。这个模式有额外的特权,允许你进一步控制计算机。例如,你必须进入超级用户模式来读取一个插件(podule)。这不能在用户模式下完成。
- 中断模式(IRQ 模式),用来处理发起中断的外设。这个模式也是有特权的。导致 IRQ的设备有键盘、 VSync (在发生屏幕刷新的时候)、IOC 定时器、串行口、硬盘、软盘、等等...
- 快速中断模式(FIQ 模式),用来处理发起快速中断的外设。这个模式是有特权的。导致 FIQ 的设备有处理数据的软盘,串行端口(比如在 82C71x 机器上的 A5000)和 Econet。
简单的寄存器的装载使用
*LDR是加载的意思,也就是把地址里面的内容保存到寄存器当中;STR是存储的意思,也就是吧寄存器里面的值保存到地址里面的意思。
LDR{条件} Rd, <地址>
STR{条件} Rd, <地址>
LDR{条件}B Rd, <地址>
STR{条件}B Rd, <地址>
STR 和 LDR
使用方法
- STR Rd, [Rbase] 存储 Rd 到 Rbase 所包含的有效地址。
- STR Rd, [Rbase, Rindex] 存储 Rd 到 Rbase + Rindex 所合成的有效地址。
- STR Rd, [Rbase, #index] 存储 Rd 到 Rbase + index 所合成的有效地址。index 是一个立即值。
STR Rd, [Rbase, #index]! 存储 Rd 到 Rbase + index 所合成的有效地址,并且并且把这个新地址写回到 Rbase。
LDR R0,=0x23 LDR R1,=0x20000000 STR R0,[R1]
上述操作就可以把 0x12 这个数值保存在地址0x2000000中
反过来 LDR用法也是一样。
传送多个数据
栈 | 其他 |
LDMED LDMIB | 预先增加装载 |
LDMFD LDMIA | 过后增加装载 |
LDMEA LDMDB | 预先减少装载 |
LDMFA LDMDA | 过后减少装载 |
STMFA STMIB | 预先增加存储 |
STMEA STMIA | 过后增加存储 |
STMFD STMDB | 预先减少存储 |
STMED STMDA | 过后减少存储 |
FD、ED、FA、和 EA 指定是满栈还是空栈,是升序栈还是降序栈。一个满栈的栈指针指向上次写的最后一个数据单元,而空栈的栈指针指向第一个空闲单元。
在把 R15 存储到内存中的时候,还保存了 PSR 位。在重新装载 R15 的时候,
除非你要求否则不恢复 PSR 位。要求的方法是在寄存器列表后跟随一个‘^’。
STMFD R13!, {R0-R12, R14}
...
LDMFD R13!, {R0-R12, PC}
这保存所有的寄存器,做一些事情,接着重新装载所有的寄存器。从 R14 装载 PC ,它由
一个 BL 或此类指令所设置。不触及 PSR 标志。
STMFD R13!, {R0-R12, R14}
...
LDMFD R13!, {R0-R12, PC}^
使用这些操作可以极大地方便我们保存调用函数时的数据。