arm64汇编学习-(1)加载存储指令1
本篇博客是基于对苯叔的第三季视频的学习整理而得,大家如果想深入学习可以购买《arm64体系结构编程与实践》以及购买苯叔出品的第三季视频。
1 ldr 地址偏移模式测试
1.1 ldr指令解析
ldr分为三种不同不同的指令,分别为LDR (immediate);LDR (literal);LDR (register)。
1.1.1 LDR (immediate)
ldr(immediate)从内存中加载一个word或doubleword,并将其写入一个寄存器。用于加载的地址是由base寄存器和立即数偏移量计算出来的。无符号偏移变量在将其添加到基本寄存器值之前,根据访问的值的大小缩放立即数偏移值。
1.1.1.1 ldr 后变基模式
1.1.1.2 ldr 前变基模式
1.1.1.3 ldr 无符号偏移模式
1.1.2 LDR (literal)
ldr(标签)根据PC值和一个直接偏移量计算一个地址,从该内存地址中加载一个word,并将其写入一个寄存器。
1.1.3 LDR (register)
ldr(register)从base寄存器值和偏移寄存器值计算一个地址,从内存中加载一个word,并将其写入寄存器。偏移寄存器值可以选择进行移位和扩展。
1.2 ldr register
1.3 ldr前变基和后变基模式
1.3.1 执行前变基和后变基模式之前
1.3.2 执行前变基之后
1.3.3 执行后变基之后
1.4 str指令
1.4.1 STR (immediate)
Store Register (immediate) stores a word or a doubleword from a register to memory. The address that is used for the store is calculated from a base register and an immediate offset.
1.4.1.1 Post-index
1.4.1.2 Pre-index
1.4.1.3 Unsigned offset
1.4.2 STR (register)
Store Register (register) calculates an address from a base register value and an offset register value, and stores a 32-bit word or a 64-bit doubleword to the calculated address, from a register.
1.5 str前变基和后变基
1.5.1 执行变基模式之前的状态
1.5.2 执行前变基模式之后的状态
1.5.3 后变基执行之前的寄存器状态
1.5.4 后变基执行之前的寄存器状态
1.6 ldr指令加载label
1.6.1 ldr指令加载label之前
在ldr指令加载label之前的时候,定义了MY_LABEL 的值为0x20,PC的寄存器值为0x802e4,
#define MY_LABEL 0x20
1.6.2 ldr指令加载label之后
- ldr x6, MY_LABEL 由执行之后的结果可以看出,在执行ldr x6, MY_LABEL之后,x6的值变为内存地址0x80304的内容了,而0x80304是PC + 0x20之后的地址。由此可以看出,ldr x6 MY_LABEL是将PC + MY_LABEL之后内存地址的数据加载到x6中了。
- ldr x7 =MY_LABEL 这条指令是一条伪指令,其目的就是要将MY_LABEL的值赋值给x7寄存器。
1.7 总的汇编程序
1.7.1 测试程序的主处理函数
extern void ldr_test(void);
void my_ldr_str_test(void)
{
ldr_test();
}
void kernel_main(void)
{
uart_init();
uart_send_string("Welcome BenOS!\r\n");
//my ldr str test
my_ldr_str_test();
while (1) {
uart_send(uart_recv());
}
}
1.7.2 ldr_test测试程序的实现
.global ldr_test
ldr_test:
// lab1. 测试ldr地址偏移模式
mov x1, 0x80000
mov x3, 16
/* 读取0x80000地址的值到x0寄存器*/
ldr x0, [x1]
/* 读取0x80008地址的值*/
ldr x2, [x1, #8]
/* 读取x1+x3 地址的值*/
ldr x4, [x1, x3]
/* 读取(x1+ x3<<3) 地址的值*/
ldr x5, [x1, x3, lsl #3]
// lab2:观察ldr前変基模式和后变基模式
/* 前变基模式*/
ldr x6, [x1, #8]!
/* 后变基模式 */
ldr x7, [x1], #8
//lab3: 观察前变基和后变基的str指令
/* 观测前变基的str,观察x2的值,地址0x400000的值 */
mov x2, 0x400000
ldr x6, =0x1234abce
str x6, [x2, #8]!
/* 观测后变基的str,观察x2的值,地址0x500000的值 */
mov x2, 0x500000
str x6, [x2], #8
ret