• ARM 汇编 内存访问指令


    一。 单个寄存器操作读写内存

    内存访问指令格式:<opcode><cond> Rd, [Rn]

      Rn 中保存的是一个内存的地址值

    1. 内存写指令  【 str,strb,strh 】单个寄存器

      1) 【 str 】写 4 个字节

    ldr r0, =0x12345678      @ 
    mov r1, #0x40000000
    str r0, [r1]   @ 将r0中的数据写入 r1 指向的内存中; str写4个字节

     2)【 strb 】写 1 个字节

    strh r0, [r1]  @ 把 r0 中的低字节,写入 r1 指向的低地址中

     

     3) 【 strh 】 写 2 个字节

    strh r0, [r1]   @ 把 r0 中的 低2个字节,写入 r1指向的 2个低地址中
    

     

    2. 读内存指令 【 ldr,ldrb,ldrh 】 单个寄存器

      1) 【 ldr 】 读 4 个字节

    ldr r0, =0x12345678   @ 此处 ldr 是伪指令, ldr 还可以是读内存的指令
    mov r1, #0x40000000
    str r0, [r1]                  @ 先把r0 中的数据写到r1指向的地址中
    ldr r2, [r1]          @ 读取 r1 指向的地址中的数据,读取 4 个字节

     

      2)【 ldrb 】 读 1 个 字节

    ldrb r3, [r1]  @ 读 1个字节, 读低位

      3)【 ldrh 】读 2 个字节

    ldrh r4, [r1]  @ 读取低 2 位 的2 个字节

     二. 操作多个寄存器读写内存 【 写内存: stm , 读内存: ldm 】

     指令格式 : <opcode><cond> Rn{!} {register_list}

      Rn 中保存一个 内存地址值

      {!} 表示是否更新 Rn 中的地址值

      {register_list} 寄存器列表

    1. 【 stm 】 多个寄存器中的值写入内存中

    mov r0, #0x40000000
    ldr r1, =0x11111111
    ldr r2, =0x22222222
    ldr r3, =0x33333333
    ldr r4, =0x44444444
    stm r0!, {r1,r2,r3,r4}   @ 把 此条指令改为 stm r0,{r1,r2,r3,r4} 不会更新r0中的地址值

     对于多个寄存器的操作指令【stm】说明:

    (1)加 ! 表示更新 r0 中的地址值

    (2)寄存器列表中是连续的寄存器可以用 - 连接 如 {r1,  r2,  r3,  r4,  r6} 可以表示为 {r1-r4, r6}

    (3)编号晓得寄存器数据,保存到低地址中

    (4)编号大的寄存器数据,保存到高地址中

     2. 操作多个寄存器 读内存数据

    mov r0, #0x40000000
    ldr r1, =0x11111111
    ldr r2, =0x22222222
    ldr r3, =0x33333333
    stm r0, {r1-r3}  @把寄存器 r1-r3 中的值写入 r0 指向的内存地址中
    
    ldm r0!, {r5-r7} @读出r0指向的内存地址中的放在寄存器 r5-r7 中

     三。栈操作指令 【入栈: stmfd,出栈:ldmfd 】

    栈的 4 种特性 Full满栈     Empty空栈      Ascend增栈     Descend降栈

    组合 4 种栈:

          stmfa   fa   满   增

       stmfd   fd    满   降   ARM 汇编默认使用

       stmea  ea   空   增

       stmed  ed    空   减

      指令格式:<opcode><cond> sp!  {register_list}     : sp 堆栈指针 r14

    ldr sp, =0x40000100   @初始化栈指针
    ldr r1, =0x11111111
    ldr r2, =0x22222222
    ldr r3, =0x33333333
    
    stmfd sp!, {r1-r3}    @把数据 入栈 到sp指向的地址, 增满栈类型, sp指针跟着更新
    ldmfd sp!, {r4-r6}   @出栈, 把栈内数据弹出到 r4-r6寄存器中

    出栈时只是把数据 , 弹出到相应的寄存器中去 , 并没有把 栈指针指向的数据清空 所以还可以看到相应的地址中有数据 , 使用局部变量不初始化 , 就会得到一个 随机的数据

    例子:

     1    ldr sp, =0x40000100  @初始化栈指针
     2    mov r0, #0x12
     3    mov r1, #0x11
     4    bl add_fun
     5    mov r2, #0x22
     6    mov r3, #0x33
     7    b loop
     8 
     9    add_fun:
    10        stmfd sp!, {r0-r3, lr} @ 入栈 r0-r3 ,lr指向跳转此处的吓一跳指令,也就是跳转到 , 第5行 
    11        mov r0, #0x1
    12        mov r1, #0x2
    13        add r4, r0, r1
    14        ldm sp!, {r0-r3, pc} @ 出栈,把 lr 的地址弹到 pc指针中执行
    15    loop:
    16        b loop

  • 相关阅读:
    Docker的load,save和import,export的区别
    LeetCode 146. LRU 缓存机制
    mongoTemplate怎么获取MongoDB自动生成的主键_id
    $ajax()或$.get()中的请求成功时运行的函数success无法执行的解决办法
    使用$.get()请求controller出现 http://localhost:8080/../[object%20Object] 错误的问题解决
    Java利用Runtime调用Python脚本
    SpringMVC返回对象类型报错HttpMessageNotWritableException: No converter found for return value of type
    「题解」洛谷 P1801 黑匣子
    「题解」洛谷 P1717 钓鱼
    「题解」洛谷 P2571 [SCOI2010]传送带
  • 原文地址:https://www.cnblogs.com/electronic/p/11019914.html
Copyright © 2020-2023  润新知