嵌入式Linux基础知识之ARM汇编指令及ATPCS

1.  相对跳转指令:b , bl

...
    b fun1
...
fun1:
    bl fun2
...
fun2:
...

bl相对于b的不同之处是,跳转之后会返回bl的下一条指令的地址,将其保存在lr寄存器中。

这两条指令是位置无关指令。

2.数据传送指令mov, 地址读取伪指令ldr

mov r1,r2    /*把寄存器r2的值赋值给寄存器r1*/
mov r1,#4096 /*立即数4096赋值给寄存器r1*/

mov指令传送的常数必须用立即数来表示, 当不知道一个数是否能用立即数来表示时,可以使用伪指令ldr来赋值:

......    
    ldr r1, =4097  /*也可以赋值立即数,前面用等于号*/
    ldr r1, =label /*赋值绝对地址*/
label:
......

3.内存访问指令:ldr,str,ldm,stm

ldr指令从内存中读取数据到寄存器;(ld是load)

str指令把寄存器的值保存到内存中。  (st是store)

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*/

ldm和stm 属于批量内存访问指令,只用一条指令就可以读写多个数据。

使用格式如下:

ldm{cond} {!} {^}
ldm{cond} {!} {^}

其中,{cond}表示指令的执行条件;

表示地址变化模式,有以下4种方式:

1. ia (Increment After) , 事后递增

2.ib (Increment Before) , 事先递增

3.da (Decrement After) , 事后递减

4.db (Decrement Before), 事先递减

保存内存的地址,如果加了感叹号!, 指令执行后,rn的值会更新,等于下一个内存单元的地址。

表示寄存器列表,

对于ldm指令,从所对应的内存块中取出数据,写入这些寄存器;

对于stm指令,把这些寄存器的值写入所对应的内存块中。

{^} 有两种含义:

1. 如果中有pc寄存器,它表示指令执行后,spsr寄存器的值将自动复制到cpsr寄存器中---这常用于从中断处理函数中返回;

2.如果中没有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 main
.text
.global _start
_start:

.extern 定义一个外部符号,可以是变量也可以是函数。

.text 表示下面的语句都属于代码段

.global 将本文件中的某个程序标号定义为全局的,上面示例中表示_start是个全局函数

7.待补充指令.....

 

附录

ATPCS中各寄存器的使用规则及其名称
寄存器 别名 使用规则
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

 

你可能感兴趣的:(嵌入式Linux基础知识之ARM汇编指令及ATPCS)