指令速记
引入
https://www.cnblogs.com/chen-farsight/p/6068905.html
- 使用仿真器ARMSim ARM汇编模拟器参考文档嵌入式Linux学习笔记(基于S5PV210、TQ210)
- 指令文档(gnu-assembler.pdf)
标号
标号,就是地址的值,具体到时取地址,还是取地址的内容,看操作符,比如参考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