微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > arm汇编指令整理

arm汇编指令整理

时间:11-09 来源:互联网 点击:
1..align

.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

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top