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
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值