2023/9/28 -- ARM

【内存读写指令】

复制代码
int *p=0X12345678
*p=100;//向内存中写入数据
int a= *p;//从内存读取

1.单寄存器内存读写指令

1.1 指令码以及功能

复制代码
向内存中写:
str:向内存中写一个字(4字节)的数据
strh:向内存写半个字(2字节)的数据
strb:向内存写一个字节的数据
从内存读:
ldr:从内存读取一个字的数据
ldrh:从内存读取半个字的数据
ldrb:从内存读取一个字节的数据

1.2 格式

复制代码
指令码{条件码} 目标寄存器 [目标地址]
str 目标寄存器 ,[目标地址]:将目标寄存器的数据写入到以目标地址为起始的内存中
ldr 目标寄存器 ,[目标地址]:从以目标地址为起始的内存中读一个字的数据到目标寄存器

1.3 示例

复制代码
 mov r1,#0XFFFFFFFF
    ldr r2,=0X40000000
    @向内存写入
    str r1,[r2]
    @从内存读
    ldr r3,[r2]

1.4 单寄存器读写的地址索引方式

复制代码
1.前索引
   mov r1,#0XFFFFFFFF
    ldr r2,=0X40000000
        str r1,[r2,#8]@将r1寄存器的值保存到r2+8为起始地址的内存中
    ldr r3,[r2,#8]@从r2+8为起始地址的内存中读
 2.后索引
      mov r1,#0XFFFFFFFF
    ldr r2,=0X40000000
     str r1,[r2],#8  @将r1寄存器的值保存到r2为起始地址的内存中,r2值=让r2+8
  3.自动索引
  mov r1,#0XFFFFFFFF
  ldr r2,=0X40000000
     str r1,[r2,#8]!  @将r1寄存器的值保存到r2+8为起始地址的内存中,r2=r2+8

2.批量寄存器的内存读写方式

2.1 指令码以及格式

复制代码
向内存写:
    stm 目标地址,{寄存器列表}
    将寄存器列表中每一个寄存器的值都写道目标地址指向的连续空间之中
从内存读
    ldm 目标地址,{寄存器列表}
    将目标地址指向的连续内存中的数据读到寄存器列表中的寄存器中
    
    注意事项:
    1.如果寄存器列表中寄存器的编号连续,可以用-表示列表,如果不连续,用,分割寄存器
        {r1-r5,r7}
    2.无论寄存器列表中如何表示,我们在读写内存的时候始终是低地址 对应低寄存器编号

2.2 示例代码

复制代码
mov r1,#1
    mov r2,#2
    mov r3,#3
    mov r4,#4
    mov r5,#5
    ldr r6,=0X40000000
    stm r6,{r1,r2,r3,r4,r5}  @将r1-r6寄存器的值写道r6指向的连续内存中
    ldm r6,{r7,r8,r9,r10,r11}@从r6指向的连续内存中读取数据保存到r7-r11寄存器中

2.3 批量寄存器的地址增长方式

每次向指定寄存器保存的地址中写入一个数据,保存地址的寄存器保存的地址也会发生相应的改变

复制代码
 mov r1,#1
    mov r2,#2
    mov r3,#3
    mov r4,#4
    mov r5,#5
    ldr r6,=0X40000000
    stm r6!,{r1-r5}
    先向r6指向的内存中写一个数据,然后r6保存的地址向地址大的方向增长
ia后缀
复制代码
 mov r1,#1
    mov r2,#2
    mov r3,#3
    mov r4,#4
    mov r5,#5
    ldr r6,=0X40000000
    stmia r6!,{r1-r5}
    先向r6指向的内存中写一个数据,然后r6保存的地址向地址大的方向增长
ib后缀
复制代码
mov r1,#1
    mov r2,#2
    mov r3,#3
    mov r4,#4
    mov r5,#5
    ldr r6,=0X40000000
    stmib r6!,{r1-r5}
 
 先让R6寄存器保存的地址往地址大的方向增长,再向R6寄存器保存的地址中写入数据
da后缀
复制代码
mov r1,#1
    mov r2,#2
    mov r3,#3
    mov r4,#4
    mov r5,#5
    ldr r6,=0X40000800
    stmda r6!,{r1-r5}
 先向R6指向的内存中存数据,然后R6寄存器保存的地址往地址小的方向增长
dB后缀
复制代码
  mov r1,#1
    mov r2,#2
    mov r3,#3
    mov r4,#4
    mov r5,#5
    ldr r6,=0X40000800
    stmdb r6!,{r1-r5}
 先将R6寄存器保存的地址往地址小的方向增长,再往R6寄存器保存的地址内存中存入数据
复制代码
 mov r1,#1
    mov r2,#2
    mov r3,#3
    mov r4,#4
    mov r5,#5
    ldr r6,=0X40000000
    stmia r6!,{r1-r5}   @ia存,db取
    ldmdb  r6!,{r7-r11}

3.栈内存读写

栈指针寄存器:R13/SP

栈:栈本质上就是一段内存,我们在内存中指定一片区域用于保存一些临时数据,这片区域就是栈区

3.1 栈的类型

复制代码
增栈:压栈结束后,栈顶往地址大的方向增长
减栈:压栈结束后,栈顶往地址小的方向增长
空栈:压栈结束后,栈顶区域没有有效数据
满栈:压栈结束后,栈顶区域存放有效数据

空增栈(EA)/空减栈(ED)/满增栈(FA)/满减栈(FD)
ARM使用的栈是满减栈

3.2 满减栈压栈出栈操作

复制代码
ex1:
  ldr sp,=0X40000020 @指定顶地址
    mov r1,#1
    mov r2,#2
    mov r3,#3
    mov r4,#4
    mov r5,#5
    push {r1-r5} @压栈
    pop {r6-r10}  @将栈顶元素数值出栈
ex2:
    ldr sp,=0X40000020 @指定顶地址
    mov r1,#1
    mov r2,#2
    mov r3,#3
    mov r4,#4
    mov r5,#5
    STMDB sp!,{r1-r5} @压栈
    LDMIA sp!,{r6-r10}  @将栈顶元素数值出栈
EX3:
    ldr sp,=0X40000020 @指定顶地址
    mov r1,#1
    mov r2,#2
    mov r3,#3
    mov r4,#4
    mov r5,#5
    STMfd sp!,{r1-r5} @压栈
    LDMfd sp!,{r6-r10}  @出栈

4.栈实例---叶子函数的调用过程

复制代码
.text  
.global _start 
            

_start:
    ldr sp,=0X40000020 @初始化栈
    b main
main:
    mov r1,#1
    mov r2,#2
    bl func
    add r3,r1,r2
    b main

func:
@压栈保护现场
    stmfd sp!,{r1,r2}
    mov r1,#3
    mov r2,#4
    sub r4,r2,r1
    @出栈恢复现场
    ldmfd sp!,{r1,r2}
    mov pc,lr  @返回main函数
    
    
wh: 
    b wh  
    
.end 

5.栈实例---非叶子函数的调用过程

复制代码
.text  
.global _start 
            

_start:
    ldr sp,=0X40000020 @初始化栈
    b main
main:
    mov r1,#1
    mov r2,#2
    bl func
    add r3,r1,r2
    b main

func:
@压栈保护现场
    stmfd sp!,{r1,r2,lr}
    mov r1,#3
    mov r2,#4
    bl fun1
    sub r4,r2,r1
    @出栈恢复现场
    ldmfd sp!,{r1,r2,lr}
    mov pc,lr  @返回main函数
fun1:
@压栈保护现场
    stmfd sp!,{r1,r2}
    mov r1,#4
    mov r2,#5
    mul r5,r1,r2
    @出栈恢复现场
    ldmfd sp!,{r1,r2}
    mov pc,lr
    
    
wh: 
    b wh  
    
.end 
相关推荐
q***33373 小时前
oracle 12c查看执行过的sql及当前正在执行的sql
java·sql·oracle
tobebetter95275 小时前
How to manage python versions on windows
开发语言·windows·python
Y***h1876 小时前
第二章 Spring中的Bean
java·后端·spring
9***P3346 小时前
PHP代码覆盖率
开发语言·php·代码覆盖率
8***29316 小时前
解决 Tomcat 跨域问题 - Tomcat 配置静态文件和 Java Web 服务(Spring MVC Springboot)同时允许跨域
java·前端·spring
CoderYanger6 小时前
优选算法-栈:67.基本计算器Ⅱ
java·开发语言·算法·leetcode·职场和发展·1024程序员节
jllllyuz7 小时前
Matlab实现基于Matrix Pencil算法实现声源信号角度和时间估计
开发语言·算法·matlab
q***06297 小时前
Tomcat的升级
java·tomcat
多多*7 小时前
Java复习 操作系统原理 计算机网络相关 2025年11月23日
java·开发语言·网络·算法·spring·microsoft·maven
青云交7 小时前
Java 大视界 -- Java 大数据在智能物流无人配送车路径规划与协同调度中的应用
java·spark·路径规划·大数据分析·智能物流·无人配送车·协同调度