指令速记

Posted zongzi10010

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了指令速记相关的知识,希望对你有一定的参考价值。

目录


title: 指令速记
tags: ARM
date: 2018-10-11 19:13:53
---

引入

https://www.cnblogs.com/chen-farsight/p/6068905.html

标号

标号,就是地址的值,具体到时取地址,还是取地址的内容,看操作符,比如参考LDR

纯数字lable参考

LDR

LDR指令分为加载指令ldr rn,[Rn]....与伪指令ldr Rn, =expr.一个很常见的用法如下:(具体解析在ADR)

.text
.global _start

_start:
    nop
_addr1:
ldr r0,=_addr1  //R0=addr1
ldr r0,_addr1   //R0=*addr1

ldr pc,=_start  //取绝对地址
nop
adr pc,_start   //取相对于当前pc的一个地址
nop
  • ldr rn,=lable,表示将lable的值,也就是Rn=lable,一般将其转换为ldr r0, [pc, #20]从某个flash取值

    • 在这种使用等号的形式中,经常使用宏来赋值

      //test.h
      #define TEST_NUM    0x12345678
      
      //test.S
      #include "Test.h"
      ldr r0,=TEST_NUM
  • ldr rn,lable,表示将lable值的所在内存的值赋值给Rn,也就是Rn=*lable,转换为类似ldr r0, [pc, #-12]

ADR与LDR

ADR r0,_start,这里会将_start转换为相对于当前pc值的一个值,看一段汇编.注意,三级流水线,pc=当前+8

.text
.global _start

_start:
    nop
_addr1:
ldr r0,=_addr1
ldr r0,=_addr1

ldr pc,=_start
nop
adr pc,_start
adr r0,_start
nop


00000000 <_start>:
   0:   e1a00000    nop         (mov r0,r0)

00000004 <_addr1>:
        ldr r0,=_addr1;
        //将标号的值赋值给R0
        //4+20+8=hex(32)=0x20, *0x20=00000004
   4:   e59f0014    ldr r0, [pc, #20]   ; 20 <.text+0x20>
   
        ldr r0,_addr1
        //将标号地址存放的值给R0
        //8-12+8=4,也就是将[4]中的内容取出来
   8:   e51f000c    ldr r0, [pc, #-12]  ; 4 <_addr1>
   
        ldr pc,=_start
        //直接取值,从0x24的位置取值0
   c:   e59ff010    ldr pc, [pc, #16]   ; 24 <.text+0x24>
  10:   e1a00000    nop         (mov r0,r0)
  
        adr pc,_start
        // pc=pc+8-28=0x14+8-28=0
        // 这里是通过计算offset得到pc
  14:   e24ff01c    sub pc, pc, #28 ; 0x1c
        adr r0,_start
  18:   e24f0020    sub r0, pc, #32 ; 0x20
  1c:   e1a00000    nop         (mov r0,r0)
  20:   00000004    andeq   r0, r0, r4
  24:   00000000    andeq   r0, r0, r0



以上是关于指令速记的主要内容,如果未能解决你的问题,请参考以下文章

VIM实用指南复制,粘贴 ,删除,撤销,重做指令速记

VIM实用指南复制,粘贴 ,删除,撤销,重做指令速记

CMake速记

这些角度电子邮件指令代码片段如何连接

JVM原理速记复习Java虚拟机总结思维导图面试必备

PHP速记概述