arm汇编指令整理
.align的作用在于对指令或者数据的存放地址进行对齐,有些CPU架构要求固定的指令长度并且存放地址相对于2的幂指数圆整,否则程序无法正常运行,比如ARM;有些系统却不需要,如果不遵循地址的圆整规则,程序依然可以正确执行,只是降低了一些执行效率,比如i386。.align的作用范围只限于紧跟它的那条指令或者数据,而接下来的指令或者数据的地址由上一条指令的地址和其长度决定。
ARM汇编器并不直接使用.align提供的参数作为对齐目标,而是使用2^n的值,比如这里的参数为4,那么圆整对象为2^4 = 16。这也就是为什么在ARM平台的Uboot或者Linux内核汇编中会出现.align 5的根本原因。.align此时的取值范围为0-15,当取值为0,2或者不提供参数时均圆整于4。如果尝试使用大于15的值,将会得到编译器的err。
在指令出现非对齐情况下,插入.align伪指令,对于32bit的ARM会进行4byte的指令对齐。
2..rept
.rept和.endr之间的语句count次。
3..text
几个常用的段代号,基本上与编译器/处理器都没有无关系(FLAT模式):
.text- 代码段
.const - 只读数据段(有些编译器不使用此段,将只读数据并入.data段)
.data- 读写数据段
.bss - 堆
4..extern
".extern"定义一个外部符号(可以是变量也可以是函数。
5..global
".global"将本文件中的某个程序标号定义为全局的。
6..word
.word expression就是在当前位置放一个word型的值,这个值就是expression。
相当于用.word定义了一个16bit的数据。
举例来说,
_rWTCON:
.word 0x15300000
就是在当前地址,即_rWTCON处放一个值0x15300000
7.更多伪指令
http://www.byywee.com/page/M0/S774/774183.html
8.条件码表
条件码助记符 | 标志 | 含义 |
EQ | Z=1 | 相等 |
NE | Z=0 | 不相等 |
CS/HS | C=1 | 无符号数大于或等于 |
CC/LO | C=0 | 无符号数小于 |
MI | N=1 | 负数 |
PL | N=0 | 正数 |
VS | V=1 | 溢出 |
VC | V=0 | 没有溢出 |
HI | C=1,Z=0 | 无符号数大于 |
LS | C=0,Z=1 | 无符号数小于或等于 |
GE | N=V | 带符号数大于或等于 |
LT | N!=V | 带符号数小于 |
GT | Z=0,N=V | 带符号数大于 |
LE | Z=1,N!=V | 带符号数小于或等于 |
AL | 任何无条件执行(指令默认条件) |
9.ldr
伪指令LDR
大范围的地址读取伪指令.LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器.在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令.若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入字池,并使用一条程序相对偏移的LDR指令从文字池读出常量.LDR伪指令格式如下:
LDR{cond} register,=expr/label_expr
其中register加载的目标寄存器
expr 32位立即数.
label_expr基于PC的地址表达式或外部表达式.
LDR/STR指令用于对内存变量的访问,内存缓冲区数据的访问、查表、外围部件的控制操作等等,若使用LDR指令加载数据到PC寄存器,则实现程序跳转功能,这样也就实现了程序散转。
ldr r1, [r2, #4] /*将地址为r2+4的内存单元数据读取到r1中*/
ldr r1,[r2] /*将地址为r2的内存单元数据读取到r1中*/
ldr r1,[r2], #4/*将地址为r2的内存单元数据读取到r1中,然后r2=r2+4*/
str r1 ,[r2, #4]/*将r1的数据保存到地址为r2+4的内存单元中*/
str r1, [r2]/*将r1的数据保存到地址为r2的内存单元中。*/
str r1, [r2],#4/*将r1的数据保存到地址为r2的内存单元,然后r2= r2+4*/
ldrb:8bit=>1byte
ldrh:16bit=>2byte
LDR R0,LED_TAB
LDR R1, =LED_TAB
LED_TAB: .work 0x12345678
R0的值是0x12345678,R1的值是LED_TAB标号值,就是0x12345678在内存中存放的地址
10.adr
转自:http://coon.blogbus.com/logs/2738861.html
ldr r0, _start
adr r0, _start
ldr r0, =_start
nop
mov pc, lr
_start:
nop
编译的时候设置 R0 为 0x0c008000
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
0c008000 <_start-0x14>:
c008000: e59f000c ldr r0, [pc, #12] ; c008014 <_start>
c008004: e28f0008 add r0, pc, #8 ; 0x8
c008008: e59f0008 ldr r0, [pc, #8] ; c008018 <_start+0x4>
c00800c: e1a00000 nop (mov r0,r0)
c008010: e1a0f00e mov pc, lr
0c008014 <_start>:
c008014: e1a00000 nop (mov r0,r0)
c008018: 0c008014 stceq 0, cr8, [r0], -#80
分析:
ldr r0, _start
从内存地址 _start 的地方把值读入。执行这个后,r0 = 0xe1a00000
a
ARM汇编指 相关文章:
- ARM汇编指令的一些总结(11-28)
- 常用ARM汇编指令(11-28)
- 第1天-ARM汇编指令ADD/SUB/MUL(11-26)
- 第1天-ARM汇编指令CMP/CMN/TST/TEQ(11-26)
- 第1天-ARM汇编指令B/BL(11-26)
- 第1天-ARM汇编指令MOV/MVN(11-26)