ARM LoadStore架构 电脑版发表于:2024/6/25 16:47 ![](https://img.tnblog.net/arcimg/hb/6930d1439f4b43e785a433685b813262.png) >#ARM LoadStore架构 [TOC] LoadStore架构 ------------ ![](https://img.tnblog.net/arcimg/hb/3d9690b8ce754e8ab60c6ed04c2851e4.png) tn2>存储器之间不能直接拷贝,必须通过寄存器做中转:在 ARM 架构中,数据传输只能通过寄存器和存储器之间的操作完成,不能直接在存储器之间进行拷贝。 ### Load 指令 | load指令 | 描述 | | ------------ | ------------ | |`ldr r0, [r7]`| 从地址 r7 指向的存储器中读取 4 字节的数据到寄存器 r0。| |`ldrb r0, [r7]`|从地址 r7 指向的存储器中读取 1 字节的数据到寄存器 r0。| |`ldrh r0, [r7]`|从地址 r7 指向的存储器中读取 2 字节的数据到寄存器 r0。| |`ldr r0, [r7, #8]`|从 r7 地址加 8 的存储器空间中读取 4 字节的数据到寄存器 r0。| |`ldr pc, _irq`|将 `_irq` 地址(标签)中的内容载入 pc(程序计数器)。| ### Store 指令 | Store 指令 | 描述 | | ------------ | ------------ | |`str r0, [r8]`|将寄存器 r0 的值存储到 r8 地址指向的存储器空间中。| |`str r0, [r8, #4]`|将寄存器 r0 的值存储到 r8 地址加 4 的存储器空间中,并且 r8 自增 4。| |`str r0, [r8, #4]`|(错误,应该是 `str r0, [r8], #4`):将寄存器 r0 的值存储到 r8 地址加 4 的存储器空间中。| tn2>下面是要用到的一些伪指令 | 伪指令 | 描述 | | ------------ | ------------ | | `.data` | 定义数据段。 | | `.byte` | 在数据段中分配并初始化一个或多个字节的数据。 | | `.space` | 在数据段中分配一定数量的字节,但不进行初始化。<br/>这通常用于保留内存空间,稍后可以在程序中使用。 | ### 简单示例 ```bash .text b main nop nop nop nop nop nop nop main: ldr r7,=srcBuf ldr r8,=destBuf ldr r0,[r7] str r0,[r8] main_end: b main_end .data srcBuf: .byte 0x00,0x01,0x02,0x03 destBuf: .space 16 .end ``` tn2>`r7`获取到的地址,我们可以通过内存`memory1`窗口来看数据的具体位置。 在右下角。 ![](https://img.tnblog.net/arcimg/hb/6916b4bee3e742ea81a265643deae363.png) tn2>`r8`获取到的地址`0x00000218`占16位的空数据。 再执行如下两行将`r7`的内容赋值到内存中`0x00000218`里面了。 ![](https://img.tnblog.net/arcimg/hb/6985d24154cf419483e92cc6fa5bdec7.png) ### 前索引和后索引 tn2>前索引模式在内存访问之前对基地址寄存器进行偏移计算。指令格式如下: ```bash [base, #offset] ``` tn2>先将 base 和 offset 相加,然后访问计算后的地址。 ```bash .text b main nop nop nop nop nop nop nop main: ldr r7,=buf mov r0,#0xAB str r0,[r7,#8] main_end: b main_end .data buf: .byte 0x00,0x01,0x02,0x03 .byte 0x04,0x05,0x06,0x07 .byte 0x08,0x09,0x0A,0x0B .end ``` ![](https://img.tnblog.net/arcimg/hb/e4cb98151f734f6f91aa8c3c4b048720.png) tn2>后索引模式在内存访问之后对基地址寄存器进行偏移计算。 ```bash str r0, [r7], #8 // 将 r0 的值存储到 r7 地址处,然后 r7 = r7 + 8 ``` ```bash .text b main nop nop nop nop nop nop nop main: ldr r7,=buf mov r0,#0xAB str r0,[r7,#8] str r0,[r7],#8 main_end: b main_end .data buf: .byte 0x00,0x01,0x02,0x03 .byte 0x04,0x05,0x06,0x07 .byte 0x08,0x09,0x0A,0x0B .end ``` ![](https://img.tnblog.net/arcimg/hb/a0de284fa6244c7ba84ced7ab0e90d3d.png) tn2>可以看到寄存器R7的地址更新了。 ### load_store 实现数据拷贝 tn2>通过下面的c语言代码实现相关汇编。 ```c main(){ int i = 0; const char buf[]=[1,2,3]; char destBuf[8]; for(i=0;i<3;i++){ destBuf[i]=buf[i] } } ``` ```c .text b main nop nop nop nop nop nop nop main: mov r0,#0 ldr r7,=buf ldr r8,=destBuf b loop_func1 main_end: b main_end loop_func1: cmp r0,#3 beq main_end ldrb r4,[r7],#1 strb r4,[r8],#1 add r0,#1 b loop_func1 loop_func1_end: mov pc,lr .data buf: .byte 1,2,3 destBuf: .space 8 .end ``` ![](https://img.tnblog.net/arcimg/hb/29401079b1264976bde8684c2411dc63.png)