ARM汇编指令应用总结

来源:互联网 发布:键盘教程软件视频 编辑:程序博客网 时间:2024/06/11 20:09

/**************请使用Ctrl+F查找你所想要的 ******************/

ADD : 加法

(Addition)

ADD{条件}{S} <dest>, <op 1>, <op 2> dest = op_1 + op_2

ADD 将把两个操作数加起来,把结果放置到目的寄存器中。操作数 1 是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即值:

ADD R0, R1, R2 ; R0 = R1 + R2 ADD R0, R1, #256 ; R0 = R1 + 256 ADD R0, R2, R3,LSL#1 ; R0 = R2 + (R3 << 1)

加法可以在有符号和无符号数上进行。

 

ADRL : 装载长地址

(load Address Long)

ADRL{后缀} <寄存器>, <标号>

 BASIC 汇编器不支持它,但一些扩展支持它。

ADRL 指令使用 ADR 和 ADD,或 ADR 和 SUB 的一个组合,来生成一个更广大的可以到达的地址范围。但是它总是使用两个指令,所以可以尝试更加可运做的布置来重新组织你的那些可以使用普通的 ADR 代码。

还有,在一些汇编器中,用使用三个指令的 ADRX 来定位更大的地址。

 

bne %B0的理解

 

==============================================================

   查了一下书,0~99应该称为局部标号。

   详见 ARM体系结构与编程 第147页

============================================================

昨天在看arm汇编,其中有这样的一段语句

0

         ldr    r3, [r0], #4

         str    r3, [r1], #4

         cmp r2, r0

         bne %B0

 

bne:不等于则调转

但%B0 ,网上搜了一遍,还是未果。从最后的汇编语言来看,%B 代表,往前搜索 lable为0的行,换句话说,就是指本条语句前,lable为0的地址。整条语句的意思就是,如果不相等则跳转到lable为0的行。

 

同样,有了bne %B0,也就有了bne %F1,这是向后搜索lable为1的行。参考代码:

; check if EIN0 button is pressed

 

       ldr       r0,=GPFCON

         ldr    r1,=0x0

         str    r1,[r0]

         ldr    r0,=GPFUP

         ldr    r1,=0xff

         str    r1,[r0]

 

         ldr    r1,=GPFDAT

         ldr    r0,[r1]

       bic      r0,r0,#(0x1e<<1) ; bit clear

         tst    r0,#0x1

         bne %F1

 

(省略一些语句)

;Clear SDRAM End

1

                ;Initialize stacks

         bl      InitStacks

 

总结一下 bne %B0,如果不相等则跳到本条语句前的lable为0的行。

     bne %F1,如果不相等则跳到本条语句后的lable为1的行。

 

传送单一数据

使用单一数据传送指令(STR 和 LDR)来装载和存储单一字节或字的数据从/到内存。寻址是非常灵活的。

首先让我们查看指令格式:

LDR{条件} Rd, <地址> STR{条件} Rd, <地址> LDR{条件}B Rd, <地址> STR{条件}B Rd, <地址>

指令格式

这些指令装载和存储 Rd 的值从/到指定的地址。如果象后面两个指令那样还指定了‘B’,则只装载或存储一个单一的字节;对于装载,寄存器中高端的三个字节被置零(zeroed)。

地址可以是一个简单的值、或一个偏移量、或者是一个被移位的偏移量。可以还可以把合成的有效地址写回到基址寄存器(去除了对加/减操作的需要)。

各种寻址方式的示例: 

 

MRC、MCR

 

MRC 传送一个协处理器寄存器到一个 ARM 寄存器, MCR 做反方向传送(字母看起来象是写反了,记住在 ARM 汇编器中目的通常写在左边)。 MCR 传送 ARM 寄存器 Rd 的内容到协处理器。协处理器基于 ooo、dddd、qqq 和 MMMM 字段的值自由的做它想做的任何事情,尽管有一个“标准的”解释: 把它写到协处理器寄存器 CRN,使用操作 ooo,用 CRM 和 qqq 提供可能的补充控制。汇编语法是: MCR p,o,Rd,CRN,CRM,q给 MCR 指令的 Rd 不应该是 R15。 MRC 从协处理器传送一个单一的字并把它放置到 ARM 寄存器 Rd 中。协处理器使用与 MCR 相同的字段自由的以任何方式生成这个字,有一个标准的解释:它来自 CRN,使用操作 ooo,用 CRM 和 qqq 提供可能的补充控制。汇编语法是: MRC p,o,Rd,CRN,CRM,q如果给 MRC 指令的 Rd 是 R15,使用传送的字的顶端 4 位来设置标志;丢弃余下的 28 位。(例如,这种机制用于浮点比较指令。)

 

LDR  Rd , addressing      ;Rd←[addressing](load)
STR Rd , addressing ;[addressing]←Rd (store)
MOV Rd ,operand2 ; Rd←operand2
LDR可以装载32Wie立即数,而MOV只能装载8位图立即数

MOV是从一个寄存器或者移位的寄存器或者立即数的值传递到另外一个寄存器
从本质上是寄存器到寄存器的传递,为什么会有立即数,其实也是有限制的立即数,不是所有立即数都可以传递的
这个立即数要符合一个8位数循环右移偶数位的取值
原因是,MOV本身就是一条32bit指令,除了指令码本身,它不可能再带一个可以表示32bit的数字,所以用了其中的12bit来表示立即数,其中4bit表示移位的位数(循环右移,且数值x2),8bit用来表示要移位的一个基数
可以看出,并不是所有数都可以表示成一个8bit数循环右移偶数位的
LDR和STR用来存取内存,关于"索引偏移",你是不是指pre-indexed addressing和post-indexed addressing
pre-indexed addressing是指地址经过运算不写回基址寄存器
post-indexed addressing则回写到基址寄存器
比如
pre-indexed addressing:
mov r1,#0
STR r0, [r1, #0x10]       ;r1+0x10这个是所用的实际地址值,但是不回写入r1,在此句之后,r1=0
post-indexed addressing:
STR r0, [r1], #0x10       ;r1+0x10这个是所用的实际地址值,这个值回写入r1,此句之后,r1=0x10
还有一点是关于ldr的,其实ldr可以装载一个32bit立即数的说法并不确切,因为实际上并不是这一条语句装载了一个32bit立即数,比如
ldr r1, =0x12345678
其实真正的汇编代码是将某个地址的值传递给r1,就是说需要一个地址存放0x12345678这个立即数,实际上可以看作是一条伪指令
而且如果这个立即数可以用mov指令的形式来表达,会被编译器实际用mov来代替
比如:
ldr r1,=0x10
会变成
mov r1,#0x10

原创粉丝点击