uboot中常用汇编指令汇总解析

来源:互联网 发布:做微信推文用什么软件 编辑:程序博客网 时间:2024/05/15 08:03

一、目录

(1).global
(2).word
(3).balignl
(4)ldr
(5)bl
(6)mov
(7)str
(8)sub
(9)adr
(10)msr与mrs
(11)ldm
(12)orr
(13)bic
(14)mcr

二、具体解析

1. .global

作用:将变量声明为全局变量,从而能够在其它汇编文件中调用。

uboot中实例代码:

.globl _start

将 _start 声明为全局变量

2. .word

作用:定义一段4字节的空间,存储数据,相当于int。

uboot中实例代码:

_undefined_instruction:    .word undefined_instruction_software_interrupt:    .word software_interrupt

3. .balignl

作用:用来进行填充对齐。
uboot中实例代码:

.balignl1 16,0xdeadbeef

用0xdeadbeef 进行填充对齐操作。此处的0xdeadbeef是一个16进制的数字,只不过这个数字的表示全是用16进制的英文表示的,如其名“坏牛肉”,表示仅仅用来进行填充所用。

4. ldr

4.1 作用
用来从存储器中将一个32位的字数据传送到目的寄存器中,通常读取到通用寄存器中,然后对数据进行处理。
当程序计数器PC作为目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而实现程序的跳转。该指令比较常用,且寻址方式灵活多样。
4.2.格式
ldr 目的寄存器,<存储器地址>

LDR R0,[R1];//将存储器地址为R1的字数据读入寄存器R0。LDR R0,[R1R2] ;//将存储器地址为R1+R2的字数据读入寄存器R0。LDR R0,[R1,#8] ;//将存储器地址为R1+8的字数据读入寄存器R0。LDR R0,[R1R2]!;//将存储器地址为R1+R2的字数据读入寄存器R0,并将新地址R1R2写入R1。LDR R0,[R1,#8]!;//将存储器地址为R1+8的字数据读入寄存器R0,并将新地址R18写入R1。LDR R0,[R1],R2 ;//将存储器地址为R1的字数据读入寄存器R0,并将新地址R1R2写入R1。LDR R0,[R1R2LSL2]!;//将存储器地址为R1R2×4的字数据读入寄存器R0,并将新地址R1R2×4写入R1。LDRR0,[R1],R2LSL2 ;//将存储器地址为R1的字数据读入寄存器R0,并将新地址R1R2×4写入R1。”

4.3.uboot中实例代码

ldr r0, =PRO_ID_BASE;//进行赋值操作,将宏值传入r0中ldr r1, [r0,#OMR_OFFSET];//赋值,将r0中的值减去宏定义的值,再传入r1

5. bl

5.1.作用
b指令是单纯的跳转指令,即CPU直接跳转到某地址继续执行。
而bl指的是branch with link,带分支的跳转。而link指的是link Register,链接寄存器R14,即lr。所以,bl的含义是,包含b指令的单纯跳转功能。在跳转之前,还把r15寄存器 PC=CPU地址,赋值给r14=lr,然后跳转到对应位置,等要做的事情结束后,再使用 mov pc , lr 指令,使得CPU跳转回来,相当于调用子程序。
BL Label ;当程序无条件跳转到标号Label处执行时,同时将当前的PC值保存到R14中。

5.2.格式
bl 条件 目标地址
b 地址

5.3.uboot中实例代码

b   after_copy  bl  onenand_bl2_copy

6. mov

6.1. 作用
完成从另一个寄存器,被移位的寄存器或将一个立即数加载到目的寄存器。其中S选项决定指令的操作是否影响CPSR中条件标志位的值,当没有S时指令不更新CPSR中条件标志位的值。

6.2. 格式
MOV{条件}{S} 目的寄存器,源操作数
MOV R1,R0 ; //将寄存器R0的值传送到寄存器R1
MOV PC,R14 ;//将寄存器R14的值传送到PC,常用于子程序返回
MOV R1,R0,LSL#3 ;//将寄存器R0的值左移3位后传送到R1

6.3. uboot中源代码

mov r0, #0x1000

7. str

7.1. 作用
从源寄存器中将一个32位的字数据传送到存储器中。该指令在程序设计中常用,寻址方式灵活多样。

7.2. 格式
STR{条件} 源寄存器,<存储器地址>
STR R0,[R1],#8 ;//将R0中的字数据写入以R1为地址的存储器中,并将新地址R1+8写入R1。
STR R0,[R1,#8] ;//将R0中的字数据写入以R1+8为地址的存储器中。

7.3. uboot中源代码

str r1, [r0]

8. sub

8.1. 作用
用操作数one减去操作数two,把结果放置到目的寄存器中。操作数 1 是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即值。

8.2. 格式
SUB{条件}{S} , ,
SUB R0, R1, R2 ; // R0 = R1 - R2
SUB R0, R1, #256 ; //R0 = R1 - 256
SUB R0, R2, R3,LSL#1 ; //R0 = R2 - (R3 << 1).减法可以在有符号和无符号数上进行。

8.3. uboot中源代码

9. adr

9.1. 作用
ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。进行小范围的读取。
在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。

9.2. 格式
ADR{cond} register, expr
地址表达式expr的取值范围:
当地址值是字节对齐时,其取指范围为: +255 ~ 255B;
当地址值是字对齐时,其取指范围为: -1020 ~ 1020B;

9.3. uboot中源代码

adr r0, _start

就是将_start的地址赋值给r0。

10. mrs(程序状态寄存器访问指令)

10.1. 作用
用于将程序状态寄存器的内容传送到通用寄存器中。该指令一般用在以下两种情况:
Ⅰ.当需要改变程序状态寄存器的内容时,可用MRS将程序状态寄存器的内容读入通用寄存器,修改后再写回程序状态寄存器。
Ⅱ.当在异常处理或进程切换时,需要保存程序状态寄存器的值,可先用该指令读出程序状态寄存器的值,然后保存。

10.2. 格式
MRS{条件} 通用寄存器,程序状态寄存器(CPSR或SPSR)
MRS R0,CPSR ;传送CPSR的内容到R0
MRS R0,SPSR ;传送SPSR的内容到R0”

10.3. uboot中源代码

mrs r0,cpsr

11. msr

11.1. 作用
将操作数的内容传送到程序状态寄存器的特定域中。其中,操作数可以为通用寄存器或立即数。<域>用于设置程序状态寄存器中需要操作的位,32 位的程序状态寄存器可分为4个域:
位[31:24]为条件标志位域,用f表示;
位[23:16]为状态位域,用s表示;
位[15:8]为扩展位域,用x表示;
位[7:0]为控制位域,用c表示;
该指令通常用于恢复或改变程序状态寄存器的内容,在使用时,一般要在MSR指令中指明将要操作的域。

11.2. 格式
MSR{条件} 程序状态寄存器(CPSR或SPSR)_<域>,操作数
MSR CPSR,R0 ;传送R0的内容到CPSR
MSR SPSR,R0 ;传送R0的内容到SPSR
MSR CPSR_c,R0 ;传送R0的内容到SPSR,但仅仅修改CPSR中的控制位域

11.3. uboot中源代码

12. orr

12.1. 作用
用于在两个操作数上进行逻辑或运算,并把结果放置到目的寄存器中。操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令常用于设置操作数1的某些位。

12.2. 格式
ORR{条件}{S} 目的寄存器,操作数1,操作数2
ORR R0,R0,#3 ; //该指令设置R0的0、1位,其余位保持不变。

12.3. uboot中源代码

13. bic

13.1. 作用
用于清除操作数1的某些位,并把结果放置到目的寄存器中。操作数1应 是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。操作数2为32位的掩码,如果在掩码中设置了某一位,则清除这一位。未设置的掩码位保持不变。

13.2. 格式
BIC{条件}{S} 目的寄存器,操作数1,操作数2

13.3. uboot中源代码

14. mcr

14.1. 作用
将ARM处理器的寄存器中的数据传送到协处理器寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。

14.2. 格式
MCR{}

,< opcode_1>,,,{,}
MCR{} p15,0,,,{,}
其中

指令执行的条件码.当忽略时指令为无条件执行。

协处理器将执行的操作的操作码。对于CP15协处理器来说,永远为0b000,当不为0b000时,该指令操作结果不可预知。

作为源寄存器的ARM寄存器,其值将被传送到协处理器寄存器中

作为目标寄存器的协处理器寄存器,其编号可能是C0,C1,…,C15。
和两者组合决定对协处理器寄存器进行所需要的操作,如果没有指定,则将为为C0,opcode_2为0
对照上面的那行代码:
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
可以看出,其中 rd为r0=0,CRn为C7,CRm为C7
对于这行代码的作用,以此按照语法,来一点点解释如下:
首先,mcr做的事情,其实很简单,就是“ARM处理器的寄存器中的数据传送到协处理器寄存器中”,此处即是,将ARM的寄存器r0中的数据,此时r0=0,所以就是把0这个数据,传送到协处理器CP15中。而对应就是写入到“”这个“目标寄存器的协处理器寄存器”,此处CRn为C7,即将0写入到寄存器7(Register 7)中去。而上面关于Register 7的含义中也说了,“Any data written to this location will cause the selected cache to be flushed”,即你往这个寄存器7中写入任何数据,都会导致对应的缓存被清空。而到底那个缓存被清空呢,即我们这行指令
mcr p15, 0, r0, c7, c7, 0起了什么作用呢
那是由“和两者组合决定”的。
而此处CRm为C7,opcode_2为0,而对于C7和0的组合的作用,参见上面的那个表中Register 7中的Flash I+D那一行,
当opcode_2为0,CRm为0111=7,就是我们要找的,其作用是“Flush I + D”,即清空指令缓存I Cache和数据缓存D Cache。
根据该表,同理,如果是opcode_2=0,而CRm=0101b=5,那么对应的就是去“Flush I”,即只清除指令缓存I Cache了。
而对应的指令也就是mcr p15, 0, r0, c7, c5, 0 了。

14.3. uboot中源代码

补充:CP15协处理器
ARM 微处理器可支持多达 16 个协处理器,用于各种协处理操作,在程序执行的过程中,每个协处理器只执行针对自身的协处理指令,忽略 ARM 处理器和其他协处理器的指令。ARM 的协处理器指令主要用于 ARM 处理器初始化 ARM 协处理
器的数据处理操作,以及在ARM 处理器的寄存器和协处理器的寄存器之间传送数据,和在 ARM 协处理器的寄存器和存储器之间传送数据。 ARM 协处理器指令包括以下 5 条:
1. CDP 协处理器数操作指令
2. LDC 协处理器数据加载指令
3. STC 协处理器数据存储指令
4. MCR ARM 处理器寄存器到协处理器寄存器的数据传送指令
5. MRC 协处理器寄存器到ARM 处理器寄存器的数据传送指令

     ......

CP15系统控制协处理器

CP15 —系统控制协处理器(the system control coprocessor)他通过协处理器
指令MCR和MRC提供具体的寄存器来配置和控制caches、MMU、保护系统、配置时
钟模式(在bootloader时钟初始化用到)
CP15的寄存器只能被MRC和MCR(Move to Coprocessor from ARM Register )指
令访问

0 0
原创粉丝点击