iOS汇编之ARM64基础介绍
大小端
计算机电路先处理低位字节,效率比较高,因为计算都是从低位开始的。所以,计算机的内部处理都是小端字节序。
但是,人类还是习惯读写大端字节序。所以,除了计算机的内部处理,其他的场合几乎都是大端字节序,比如网络传输和文件储存。
0x1234567的大端字节序和小端字节序的写法如下图:
ARM64寄存器
可以通过register read查看
通用寄存器
arm64提供了31个64位通用寄存器。参数寄存器是x0 ~ x7,大于8个会通过堆栈传参,x0一般表示返回值。
x8:间接寻址结果,当返回值(比如结构体size)大于16个字节的时候,该返回内容会被存到一个内存地址当中,然后这个内存地址的值会存入寄存器x8。
w0表示x0的低32位。
浮点寄存器
v0 ~ v31,一共有32个浮点寄存器,每个寄存器大小是128位。分别可以用的方式来访问不同的位数。可以通过Bn、Hn、Sn、Dn、Qn来访问不同的位数。
Bn:8位
Hn:16位
Sn:32位
Dn:64位
Qn:128位
参数寄存器:v0 ~ v7
特殊寄存器
WZR(word zero rigiser)或者XZR(64位)
寄存器r31是一个特殊的寄存器: Zero Register: 在大多数情况下,作为源寄存器使用时, r31读出来的值 是0; 作为目标寄存器使用时, 丢弃结果。 WZR(word zero rigiser)或者XZR(64位) Stack Register: 当 用作load/store 的base register时, 或者 一些算术指令中, r31提供当前的stack pointer WSP或者 SP
堆栈指针sp
sp,即x31,指向堆栈的顶部。每一个异常级别都有一个专用的SP寄存器。
程序计数器pc
pc,保存着当前CPU执行指令的地址。
链接寄存器lr
lr,既x30,存储着函数的返回地址。
FP栈帧地址
fp,即x29。保存当前栈帧的栈底为止。
寻址方式
立即寻址
操作数直接包含在指令中,把该操作数称为立即数。
MOV AL, 6 ;(AL)=6
MOV AX, 3064H ;(AX)=3064
复制代码
直接寻址
操作数的有效地址直接包含在指令中的寻址方式。这种寻址方式常用于存取简单变量。
MOV AL, [78H]
复制代码
寄存器寻址
操作数直接包含在寄存器中,由指令指定寄存器号的寻址方式。
MOV BX, AX ;(BX)=(AX)
复制代码
寄存器间接寻址
操作数的有效地址在基址寄存器中,而操作数在存储器中的寻址方式。
MOV AL, [BX]
复制代码
寄存器相对寻址
也称为直接变址寻址方式。操作数的有效地址是一个基址(BX、BP)或变址(SI、DI)寄存器的内容和指令中给定的一个位移量(disp)之和。有效地址由2部分组成。
即:EA=(基址<或变址>寄存器)+disp
或:EA=(32位通用寄存器)+disp(386型号以上)
MOV AL, 8[BX]
MOV AL, [BX+8]
复制代码
基址变址寻址
操作数的有效地址是一个基址寄存器(BX、BP)和一个变址寄存器(SI、DI)的内容之和
MOV AL,[BX][SI]
MOV AL,[BX+SI]
复制代码
汇编指令介绍
参考链接
.MACRO/.ENDM
用.MACRO指令可以定义一个宏,可以把需要重复执行的一段代码,或者是一组指令缩写成一个宏。
str/ldr指令
str(store register):写入指令,将数据从寄存器中读出来,写入到内存中。
ldr(load register):读取指令,将数据从内存中读取出来,存到寄存器中。
str(条件) 源寄存器, <存储器地址>
ldr(条件) 目的寄存器, <存储器地址>
复制代码
ldp/stp指令
是ldr/str的衍生,可以同时读/写两个寄存器。
b/bl/blr指令
b指令:最简单的跳转指令。一旦遇到一个b指令,ARM处理器将立即跳转到给定的目标地址,从那里继续执行。
bl指令:同样是跳转指令,但是在跳转之前,会将下一条指令保存到LR寄存器中,因此,可以通过将lr的内容重新加载到pc中,来返回到跳转指令之后的那个指令处执行。
blr指令:与BL指令相似,但是跳转地址是从特定的寄存器中取得。
bl _hook_objc_msgSend_after
blr x17
复制代码
mov指令
mov指令可完成从另一个寄存器、被移位的寄存器或将一个l立即数加载到目的寄存器。其中s选项决定指令的操作是否影响CPSR中条件标志位的值,当没有s时指令不更新CPSR中条件标志位的值。
mov{条件}{s} 目的寄存器,源操作数
复制代码
adr/adrp伪指令
adr指令:小范围的地址读取指令。ADR指令将基于PC相对偏移的地址读取到寄存器。
原理:将有符号的21位的偏移,加上PC,结果写入到通用寄存器,可用来计算+/-1MB范围的任意字节的有效地址。
adrp指令:以页为单位的大范围的地址读取指令。
原理:将有符号的21位偏移,向左移动12位,PC的值低12位清零,然后把两者相加,结果写入到寄存器。范围:+/-4KB * 1M = +/-4GB。
adrp x17, _origin_objc_msgSend@PAGE #label页偏移
ldr x17, [x17, _origin_objc_msgSend@PAGEOFF] #label页内偏移
blr x17
复制代码
栈帧布局
参考链接
developer.arm.com/documentati…
cloud.tencent.com/developer/a…
相关文章
- 【技术种草】cdn+轻量服务器+hugo=让博客“云原生”一下
- CLB运维&运营最佳实践 ---访问日志大洞察
- vnc方式登陆服务器
- 轻松学排序算法:眼睛直观感受几种常用排序算法
- 十二个经典的大数据项目
- 为什么使用 CDN 内容分发网络?
- 大数据——大数据默认端口号列表
- Weld 1.1.5.Final,JSR-299 的框架
- JavaFX 2012:彻底开源
- 提升as3程序性能的十大要点
- 通过凸面几何学进行独立于边际的在线多类学习
- 利用行动影响的规律性和部分已知的模型进行离线强化学习
- ModelLight:基于模型的交通信号控制的元强化学习
- 浅谈Visual Source Safe项目分支
- 基于先验知识的递归卡尔曼滤波的代理人联合状态和输入估计
- 结合网络结构和非线性恢复来提高声誉评估的性能
- 最佳实践丨云开发CloudBase多环境管理实践
- TimeVAE:用于生成多变量时间序列的变异自动编码器
- 具有线性阈值激活的神经网络:结构和算法
- 内网渗透之横向移动 -- 从域外向域内进行密码喷洒攻击