ARM 汇编语法

ARM 汇编语法

学习XiUOS需要用到很多ARM的汇编代码,所以对一些网上看到的博客进行了总结

变量

核心寄存器(Cortex-M7为例)

r0, r1, r2, ..., r12  //通用寄存器
SP(R13) // Stack Point	栈地址,有MSP(Main Stack Point)和PSP(Process Stack Point)之分,取决于CONTROL.BIT1,一般用户使用MSP,系统使用PSP
LR(R14) // Link Register	函数返回,异常返回
PC(R15) // Program Counter  当前指令地址

PSR Program Status Register
PRIMASK		//屏蔽可配置的优先级
FAULTMASK	//屏蔽出了NMI意外所有可配置的优先级
BASEPRI		//屏蔽熟知上不小于它的优先级
CONTROL		//用于设置特权级,选择堆栈指针以及FPU上下文切换

语句

. 开头

以.开头的都是汇编伪指令,不属于ARM指令集

.byte 定义单字节数据

.hword/.short 定义双字节数据

.word/.long /.int 定义4字节数据

.quad 定义8字节数据

.float/.single 定义32bit 浮点数

.double 定义64bit浮点数

.ascii 定义字符串以\0为结束符

.asciz /.string 定义字符串(非零结束符)

.fill 分配一段字节内存单元,用size长度value填充repeat次

.zero 分配一段字节内存单元,并用0填充内存

.space/.skip 分配一段内存单元,用value将内存单元初始化

.arm/.code32 定义以下代码使用ARM指令集

.thumb/.code16 定义以下代码使用Thumb指令集

.arch cpu的架构

.fpu 软件浮点

.section 定义一个段

例: .section expr ;expr可以是.text,.data,.bss

.text 将定义符开始的代码编译到代码段

.data 将定义符开始的数据编译到数据段

.bss 将变量存放到.bss段

.align 通过用零或或指定的数据进行填充来使当前位置满足一定的对齐方式,2的权次方对齐

例:

.align 1 2个字节对齐

.align 3 8个字节对齐

.type 说明一个类型

.size 占用内存的大小

.org指定从当前地址加上offset开始存放代码,并且从当前地址到当前地址加上offset之间的内存单元,用零或指定的数据进行填充

.global/.globl 用来定义一个全局的符号

.include 将一个源文件包含到当前源文件中

.end 标记汇编文件的结束行,即标号后的代码不作处理

_start 汇编程序的缺省入口是_start标号,用户也可以在链接脚本文件中用ENTRY标志指明其他入口点

数据传送指令

LDR	Load	ldr ra, [rb]	把 *[rb] 放入 ra 中
STL	Store	str ra, [rb]	把 ra 放入 *[rb] 中

预索引:
ldr R0, [R1, #12] 把 * ([R1] + 12) 放入 R0 中
后索引:
ldr R0, [R1], #12 先执行 *[R1] 放入 R0 再执行 R1 = R1 + 12

加等号:

ldr R0, =array 把array的值放入R0中

和x86一样,可以加一些后缀,例如 B,H,W 表示取1,2,4个字节

LDM	Load Multiple
STM	Store Multiple

这两个指令表示大批量的传输数据

STM R0, {R4, R5} 表示把R4放到*[R0],R放到*([R0]+1)

其后缀 I, D表示Increase和Decrease

其后缀 A, B表示After和Before,After为传送后再增加,即[i++] = x, Before为增加后传送即[++i]=x

ARM 汇编语法_第1张图片

!符号表示这个寄存器会在运行中随着自增自减

PUSH {R0-R3, LR} = STMDB SP!, {R0-R3, LR}

这里栈是往下生长的,所以是D + Before 这样就可以把每个值放进栈中,并且让栈指针递减

同理

POP {R0-R3, PC} = LDMIA SP!, {R0-R3, PC}

移位指令

LSL	Logic Shift Left
LSR	Logic Shift Right
ROR	Rotate Right	循环形式的移位,只有右移,右移 n = 左移32 - n
ASR	Arithmetic Shift Left	只有右移,左移没区别
REV Reverse	大端变小端
BFI	Bit Field Insert	对Bit进行操作
BFX Bit Field Extract
BFC Bit Field Clear

跳转指令

B label 跳到Label
BX Register	跳到寄存器的位置
BL func1 L表示记录函数返回地址的Link Register,类似于call指令

IT (if - then)

IT

其中可以是"T"或者"E" (Then) (Else)

例子:

下面的c代码:

if (R0==R1)   {  R3 = R4 + R5;    R3 = R3 / 2; }  
else          {  R3 = R6 + R7;    R3 = R3 / 2; }

使用IT指令块汇编的结果是这样的:

CMP    R0, R1        ; compare R0 and R1 
ITTEEEQ              ; if R0 == R1, Then-Then-Else-Else 
ADDEQ  R3, R4, R5    ; R3 = R4 + R5
ASREQ  R3, R3, #1    ; R3 = R3 / 2
ADDNE  R3, R6, R7    ; R3 = R6 + R7
ASRNE  R3, R3, #1    ; R3 = R3 / 2

与状态寄存器相关的指令

程序状态储存器

Program State Register

CPSR current 当前程序状态储存器

SPSR saved 保存的程序状态寄存器 - 共6个,在处理异常的时候使用

对于32位的ARM处理器,状态寄存器长度也为32

分为四个部分

  1. 条件标志位:N - Negative Z - Zero C - Carry V - Verflow 和x86一致,表示计算结果是否小于0,等于0,进位,溢出,这四个bit分别在 bit[31 - 28]

  2. Q标志位:Armv5的E系列处理器,CPSR的bit[27]表示DSP指令是否发生了溢出

  3. 控制位:I (IRQ disable), F(FIQ disable), T(Thumb state bit),M[4:0] 表示控制位,其中控制位

    [10000] 用户模式 [10001] FIQ模式 [10010] IRQ模式 [10011] 管理模式 [10111] 中止模式 [11011] 未定义模式 [11111] 系统模式 [10110] Secure Monitor

  4. 保留位:用于将来ARM版本的扩展

状态储存器指令

MRS {} , CPSR/SPSR if cond : [Rd] = CPSR/SPSR

MSR {} CPSR_, # if cond : CPSR_ = #

MSR {} CPSR_, if cond : CPSR_ =

其中设置需要操作的位。

f: 指示bits[31:24] 条件标志位

s: 指示bits[23:16]

x: 指示bits[15:8]

c: 指示bits[7:0] 控制位

CPS 命令

Change Processor State

可以更改CPSR中的M[4:0],也可以更改 I,F

CPSID = CPS Interrupt Disable 关闭中断

CPSFE = CPS Fast Interrupt Enable 打开快速中断

后面加的参数又可以选 I,F

CPSIE I PRIMASK 写 0

CPSID I PRIMASK 写 1,可以屏蔽其他低于自己优先级的中断,如果此中断的优先级为0,则屏蔽所有中断

CPSIE F FAULTMASK 写 0

CPSIE F FAULTMASK 写 1

算术指令

MVN < dest > < src > 非

ORR{条件}{S} < dest >, ,

AND{条件}{S} < dest >, ,

SUB{条件}{S} < dest >, ,

ADD{条件}{S} < dest >, ,

BIC{条件}{S} < dest >, , dest = op_1 AND (! op_2) 位清除,例如将op_2设置为某个掩码,那么这样就可以从op_1中删除掉op_2所代表的掩码

NOP

什么也不做,一般是为了防止数据污染卡流水线用的

你可能感兴趣的:(arm,arm开发,嵌入式硬件)