版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/
这种方式直接将立即数作为操作数,适合小数据或常量。ARM64的立即数在指令中直接编码。
使用寄存器中的地址作为内存地址。适合基于寄存器值进行偏移的简单访问方式。
在基地址寄存器的基础上添加一个偏移量来确定目标地址,偏移量可以是立即数或寄存器值。
使用基地址加上偏移量来访问内存,访问完成后,将偏移量更新到基地址寄存器中。
先使用基地址来访问内存,再将偏移量加到基地址寄存器中。这样偏移的效果在读取数据后才生效。
偏移量用另一个寄存器指定,便于灵活的偏移操作,特别适合对数据结构的访问。
将偏移寄存器的值进行左移,然后加到基地址中。这个方式常用于访问数组中的元素,因为它可以按数据大小自动调整偏移。
LSL:逻辑左移,将寄存器的值向左移位指定的位数,右侧用 0 填充。
LSR:逻辑右移,将寄存器的值向右移位指定的位数,左侧用 0 填充。
ASR:算术右移,和逻辑右移类似,但左侧用符号位填充。即,如果值为负,左侧填充 1,如果为正,填充 0。
UXTX:执行零扩展,同时可以左移指定的位数。
SXTW/SXTX:执行符号扩展,并可以左移指定的位数。这些用于在 32 位和 64 位数据之间进行转换的场合,特别适合混合宽度数据操作。
ROR:循环右移,将寄存器的值向右旋转指定的位数,即右移的位会从左侧填入。
使用栈指针 SP 作为基地址,加上偏移量来访问栈中的数据。例如,存储和加载局部变量
存储数据到栈
从栈加载数据
STP(Store Pair) 指令用于将两个寄存器的值存储到内存中(通常是栈上)。
LDP(Load Pair)指令用于从内存中同时加载两个寄存器的值。
指令中的寄存器类型决定了要读取或存储的数据大小。在上面的例子中,由于使用的是 64 位的 X 寄存器,每个寄存器占 8 字节(64 位),所以 STP 和 LDP 指令会操作两个 8 字节的数据。
MOV:用于寄存器和常量间的数据传递,不涉及内存访问。适合在不需要访问内存的情况下使用,如加载常数或在寄存器之间传递数据。
LDR:用于从内存中加载数据到寄存器,需要指定内存地址。支持多种寻址方式,例如偏移寻址、基地址寄存器加偏移等,非常适合访问内存中的数据,如全局变量、数组元素等。
两者主要区别在于是否需要访问内存。
ARM64 指令集具有固定长度(每条指令均为 32 位)。ARM64 包含 31 个通用寄存器(X0-X30),用于存储数据和地址;一个零寄存器(XZR),用于返回零值;以及专门的栈指针(SP)和程序计数器(PC)寄存器,用于管理函数调用和指令执行。
- B:无条件跳转到指定的地址。
- BL:无条件跳转到指定地址并将返回地址存储在链接寄存器(LR)中,用于函数调用。
- BR:跳转到寄存器中存储的地址。
- CBZ/CBNZ:根据寄存器值是否为零进行跳转。
- TBZ/TBNZ:根据寄存器中指定位的值(0或1)进行跳转。
- MOV:将一个值或寄存器的内容传送到另一个寄存器中。
- MVN:将寄存器值按位取反,并传送到目标寄存器。
- AND/ORR/EOR:对寄存器数据进行按位与、或、异或运算。
- LSL/LSR:逻辑左移或右移寄存器内容。
- BIC:对寄存器值进行按位与取反运算,用于清除特定位。
- ADD/ADDS:对两个寄存器内容相加,ADDS会更新条件标志。
- SUB/SUBS:对两个寄存器内容相减,SUBS会更新条件标志。
- MUL:对两个寄存器内容相乘。
- UDIV/SDIV:无符号/有符号除法,将结果存储在目标寄存器中。
- NEG:对寄存器中的值取反并加1,相当于求负。
- LDR:从内存加载一个值到寄存器。
- STR:将寄存器的值存储到内存中。
- LDUR/STUR:使用偏移量从内存加载或存储数据,不会影响基址寄存器。
- LDXR/STXR:用于原子操作的加载和存储指令,用于处理并发数据。
- LDP/STP:从内存加载或存储两个连续的寄存器内容,常用于函数调用保存/恢复寄存器。
打开 ARM 官方网站 ,路径 Home / Documentation / Architectures / CPU Architecture 找到 ARM64 指令集文档
可以在线查看,也可以点击左边的下载按钮下载 pdf 到本地
以 MOV(bitmask immediate) 指令为例,文档中搜索 MOV 可以找到该指令的编码格式说明。
MOV(bitmask immediate) 指令的 32 位二进制格式,其中各字段的含义如下:
- sf(位 31):size flag,指定操作数的位宽。sf=0 表示 32 位操作,sf=1 表示 64 位操作。
- opc(位 29-23):操作码字段,用于区分不同的操作类型。对于 MOV 指令,其操作码固定为 0。
- N(位 22):与立即数编码相关,用于调整立即数的生成规则。
- immr 和 imms(位 21-10):立即数字段,用于构造一个特定的位掩码。
- Rn(位 9-5):源寄存器字段。在 MOV(bitmask immediate)中,该字段固定为 11111,表示使用零寄存器(WZR 或 XZR),以便执行立即数到寄存器的移动操作。
- Rd(位 4-0):目标寄存器字段,指定立即数写入的目标寄存器编号。
以下面汇编指令为例
32 位指令编码中的各字段定义如下
将以上字段组合,我们得到完整 32 位二进制编码如下
十六进制值为 E0,转换为小端模式值为 E0030032
在 https://armconverter.com/?disasm 验证一下是否正确
相关文章:详解ARM64可执行程序的生成过程
到此这篇ldr指令(ldr指令是什么意思)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/rfx/33988.html