微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 嵌入式Linux+ARMARM体系结构与编程(ARM汇编指令)

嵌入式Linux+ARMARM体系结构与编程(ARM汇编指令)

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

0011

cc/lo

无符号数小于

C = 0

0100

mi

负数

N = 1

0101

pl

非负数

N = 0

0110

vs

上溢出

V = 1

0111

vc

没有上溢出

V = 0

1000

hi

无符号数大于

C = 1或Z = 0

1001

ls

无符号数小于等于

C = 0或Z = 1

1010

ge

带符号数大于等于

N = 1, V = 1或N = 0, V = 0

1011

lt

带符号数小于

N = 1, V = 0或N = 0, V = 1

1100

gt

带符号数大于

Z = 0且N = V

1101

le

带符号数小于/等于

Z = 1或N! = V

1110

al

无条件执行

-

1111

nv

从不执行

-

大多数ARM指令都可以条件执行,即根据cpsr寄存器中的条件标志位决定是否执行该指令:如果条件不满足,该指令相当于一条nop指令。
每条ARM指令包含4位的条件码域,这表明可以定义16个执行条件。
cpsr条件标志位N、Z、C、V分别表示Negative、Zero、Carry、oVerflow。

表示地址变化模式,有4种方式:
ia (Increment After) :事后递增方式。
ib (Increment Before) :事先递增方式。
da (Decrement After) :事后递减方式。
db (Decrement Before):事先递减方式。
中保存内存的地址,如果后面加上感叹号,指令执行后,rn的值会更新,等于下一个内存单元的地址。
表示寄存器列表,对于ldm指令,从所对应的内存块中取出数据,写入这些寄存器;对于stm指令,把这些寄存器的值写入所对应的内存块中。
{^}有两种含义:
如果中有pc寄存器,它表示指令执行后,spsr寄存器的值将自动到cpsr寄存器中——这常用于从中断处理函数中返回;
如果中没有pc寄存器,{^}表示操作的是用户模式下的寄存器,而不是当前特权模式的寄存器。
例:
HandleIRQ: @中断入口函数
sub lr, lr, #4 @计算返回地址
stmdb sp!, { r0 - r12, lr } @保存使用的寄存器
@r0 - r12, lr被保存在sp表示的内存中
@“!”使得指令执行后sp = sp - 14 * 4

ldr lr, =int_return @设置调用IRQ_Handle函数后的返回地址
ldr pc, =IRQ_Handle @调用中断分发函数
int_return:
ldmia sp!, { r0 - r12, pc }^ @中断返回,“^”表示将spsr的值到cpsr
@于是从irq模式返回被中断的工作模式
@“!”使得指令执行后sp = sp + 14 * 4

4、加减指令:add、sub
例:
add r1, r2, #1 // r1 = r2 + 1
sub r1, r2, #1 // r1 = r2 - 1

5、程序状态寄存器的访问指令:msr、mrs
ARM处理器有一个程序状态寄存器(cpsr),它用来控制处理器的工作模式、设置中断的总开关。
例:
msr cpsr, r0 // r0到cpsr中
mrs r0, cpsr // cpsr到r0中

6、其他伪指令
.extern : 定义一个外部符号(可以是变量也可以是函数)
.text : 表示现在的语句都属于代码段
.global : 将本文件中的某个程序标号定义为全局的

ARM-THUMB子程序调用规则:ATPCS
为了使C语言程序和汇编程序之间能够互相调用,必须为子程序间的调用制定规则,在ARM处理器中,这个规则被称为ATPCS:ARM程序和THUMB程序中子程序调用的规则。基本的ATPCS规则包括寄存器使用规则、数据栈使用规则、参数传递规则。

1、寄存器使用规则
子程序间通过寄存器r0 ~ r3来传递参数,这时可以使用它们的别名a1 ~ a4。被调用的子程序返回前无需恢复r0 ~ r3的内容。
在子程序中,使用r4 ~ r11来保存局部变量,这时可以使用它们的别名v1 ~ v8。如果在子程序中使用了它们的某些寄存器,子程序进入时要保存这些寄存器的值,在返回前恢复它们;对于子程序中没有使用到的寄存器,则不必进行这些操作。在THUMB程序中,通常只能使用寄存器r4 ~ r7来保存局部变量。
寄存器r12用作子程序间scratch寄存器,别名为ip。
寄存器r13用作数据栈指针,别名为sp。在子程序中寄存器r13不能用作其他用途。它的值在进入、退出子程序时必须相等。
寄存器r14称为连接寄存器,别名为lr。它用于保存子程序的返回地址。如果在子程序中保存了返回地址(比如将lr值保存到数据栈中),r14可以用作其他用途。
寄存器r15是程序计数器,别名为pc。它不能用作其他用途。

寄存器

别名

使用规则

r15

pc

程序计数器

r14

lr

连接寄存器

r13

sp

数据栈指针

r12

ip

子 程序内部调用的scratch寄存器

r11

v8

ARM状态局部变量寄存器8

r10

v7、s1

ARM状态局部变量寄存器7、在支持数据栈检查的ATPCS中为数据栈限制指针

r9

v6、sb

ARM状态局部变量寄存器6、在支持RWPI的ATPCS中为静态基址寄存器

r8

v5

ARM状态局部变量寄存器5

r7

v4、wr

ARM状态局部变量寄存器4、THUMB状态工作寄存器

r6

v3

ARM状态局部变量寄存器3

r5

v2

ARM状态局部变量寄存器2

r4

v1

ARM状态局部变量寄存器1

r3

a4

参数/结果/scratch寄存器4

r2

a3

参数/结果/scratch寄存器3

r1

a2

参数/结果/scratch寄存器2

r0

a1

参数/结果/scratch寄存器1

2、数据栈使用规则
数据栈有两个增长方向:向内存地址减小的方向增长时,称为DESCENDING栈;向内存地址增加的方向增长时,称为ASCENDING栈。
所谓数据栈的增长就是移动栈指针。当栈指针指向栈顶元素(最后一个入栈的数据)时,称为FULL栈;当栈指针指向栈顶元素(最后一个入栈的数据)相邻的一个空的数据单元时,称为EMPTY栈。
则数据栈可以分为4种:
FD:Full Descending 满递减
ED:Empty Descending 空递减
FA :Full Ascending 满递增
EA:Empty Ascending 空递增
ATPCS规定数据栈为FD类型,并且对数据栈的操作是8字节对齐的。使用stmdb / ldmia批量内存访问指令来操作FD数据栈。
使用stmdb命令往数据栈中保存内容时,先递减sp指针,再保存数据,使用ldmia命令从数据栈中恢复数据时,先获得数据,再递增sp指针,sp指针总是指向栈顶元素,这刚好是FD栈的定义。

3、参数传递规则
一般地,当参数个数不超过4个时,使用r0 ~ r3这4个寄存器来传递参数;如果参数个数超过4个,剩余的参数通过数据栈来传递。
对于一般的返回结果,通常使用r0 ~ r3来传递。
例:
假设CopyCode2SDRAM函数是用C语言实现的,它的数据原型如下:
int CopyCode2SDRAM( unsigned char *buf, unsigned long start_addr, int size )
在汇编代码中,使用下面的代码调用它,并判断返回值:
ldr r0, =0x30000000 @1. 目标地址 = 0x30000000,这是SDRAM的起始地址
mov r1, #0 @2. 源地址 = 0
mov r2, #16*1024 @3. 长度 = 16K
bl CopyCode2SDRAM @调用C函数CopyCode2SDRAM
cmp a0, #0 @判断函数返回值

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

网站地图

Top