ARM汇编指令的一些总结-转

ARM汇编指令的一些总结
ARM汇编指令很多,但是真正常用的不是很多,而且需要认真琢磨的又更少了。
比较有用的是MOV B BL LDR STR
还是通过具体汇编代码来学习吧。
@ disable watch dog timer
mov r1, #0x53000000 //立即数寻址方式
mov r2, #0x0
str r2, [r1]
MOV
没有什么好说的,只要掌握几个寻址方式就可以了,而且ARM的寻址方式比386的简单很多。立即数寻址方式,立即数要求以“#”作前缀,对于十六进制的
数,还要求在#后面加上0x或者&。0x大家很好理解。有一次我碰到了&ff这个数,现在才明白跟0xff是一样的。
STR是比较重要的指令了,跟它对应的是LDR。ARM指令集是加载/存储型的,也就是说它只处理在寄存器中的数据。那么对于系统存储器的访问就经常用到STR和LDR了。STR是把寄存器上的数据传输到指定地址的存储器上。它的格式我个人认为很特殊:
STR(条件) 源寄存器,<存储器地址>
比如 STR R0, [R1] ,意思是R0-> [R1],它把源寄存器写在前面,跟MOV、LDR都相反。
LDR应该是非常常见了。LDR就是把数据从存储器传输到寄存器上。而且有个伪指令也是LDR,因此我有个百思不得其解的问题。看这段代码:
mov r1, #GPIO_CTL_BASE
add r1, r1, #oGPIO_F
ldr r2,=0x55aa // 0x55aa是个立即数啊,前面加个=干什么?
str r2, [r1, #oGPIO_CON]
mov r2, #0xff
str r2, [r1, #oGPIO_UP]
mov r2, #0x00
str r2, [r1, #oGPIO_DAT]
对于当中的ldr 那句,我就不明白了,如果你把=去掉,是不能通过编译的。我查了一些资料,个人感觉知道了原因:这个=应该表示LDR不是ARM指令,而是伪指令。作为伪指令的时候,LDR的格式如下:
LDR 寄存器, =数字常量/Label
它的作用是把一个32位的地址或者常量调入寄存器。嗬嗬,那大家可能会问,
“MOV

r2,#0x55aa”也可以啊。应该是这样的。不过,LDR是伪指令啊,也就是说编译时编译器会处理它的。怎么处理的呢?——规则如下:如果该数字常量
在MOV指令范围内,汇编器会把这个指令作为MOV。如果不在MOV范围中,汇编器把该常量放在程序后面,用LDR来读取,PC和该常量的偏移量不能超过
4KB。
这么一说,虽然似懂非懂,但是能够解释这个语句了。
伪指令LDR{cond} register, ={expr|label-expr}
expr为32位常量。编译器根据expr的取值情况来处理这条伪指令:
1、当expr表示的地址没有超过mov或mvn指令中地址的取值范围时,编译器用合适的mov指令或mvn指令代替该LDR伪指令。
2、当expr表示的地址超过了mov或mvn指令中地址的取值范围时,编译器将该常数放在缓冲区中,同时用一条基于PC的LDR指令读取该常数。
...............................
通过上面两种可以得出伪指令LDR和ARM指令LDR的区别,具体使用时,可以不用考虑二者的区别,由编译器决定的,看源码时,你只要搞清楚它的功能就行。
然后说一下跳转指令。ARM有两种跳转方式。
(1) mov pc <跳转地址〉
这种向程序计数器PC直接写跳转地址,能在4GB连续空间内任意跳转。
(2)通过 B BL BLX BX 可以完成在当前指令向前或者向后32MB的地址空间的跳转(为什么是32MB呢?寄存器是32位的,此时的值是24位有符号数,所以32MB)。
B是最简单的跳转指令。要注意的是,跳转指令的实际值不是绝对地址,而是相对地址——是相对当前PC值的一个偏移量,它的值由汇编器计算得出。
BL非常常用。它在跳转之前会在寄存器LR(R14)中保存PC的当前内容。BL的经典用法如下:
bl NEXT ; 跳转到NEXT
……
NEXT
……
mov pc, lr ; 从子程序返回。

后提一下Thumb指令。ARM体系结构还支持16位的Thumb指令集。Thumb指令集是ARM指令集的子集,它保留了32位代码优势的同时还大大节
省了存储空间。由于Thumb指令集的长度只有16位,所以它的指令比较多。它和ARM各有自己的应用场合。对于系统性能有较高要求,应使用32位存储系
统和ARM指令集;对于系统成本和功耗有较高要求,应使用16位存储系统和ARM指令集。

###################################################################################################

###################################################################################################

LDR STR——用于字和无符号字节
指令格式:
LDR/STR{cond}{T} Rd,<地址>
LDR/STR{cond}B{T} Rd,<地址>

LDR{cond}{T} Rd,<地址>   加载指定地址的字数据到Rd中;
STR{cond}{T}  Rd,<地址>    存储Rd中的字数据到指定的地址单元中;

LDR{cond}B{T} Rd,<地址>    指令加载指定地址的字节数据到Rd的的最低字节中(Rd的高24位清零);

STR{cond}B{T} Rd, <地址>   指令存储Rd中的最低字节数据到指定的地址单元中。

T为可选后缀,若有T,那么即使处理器是在特权模式下,存储系统也将访问看成处理器是在用户模式下,T 在用户模式下无效,不能与前索引偏移一起使用T。

地址部分可用的形式有4种:

  • 零偏移(zero offset) [Rn] ,Rn的值作为传送数据的地址。如:
    LDR R0,[R1];
  • 前索引偏移(pre-indexed offset) [Rn,Flexoffset]{!} 在数据传送之前,将偏移量Flexoffset加到Rn 中。其结果作为传送数据的存储器地址。若使用后缀“!”,则结果写回到Rn 中,且Rn 不允许是R15,如:
    LDRB R0,[R1,#8]
    LDR R0,[R1,#8]!
  • 程序相对偏移(program relative) label(label 必须是在当前指令的土4KB 范围内) 。
    程序相对偏移是前索引形式的另一种版本。从PC 计算偏移量,并将PC 作为Rn 生成前索引指令,不能使用后缀“!”,如:
    LDR R0,place ;
    place地址装入R0
  • 后索引偏移(post-indexed offset) [Rn],Flexoffset。在数据传送后,将偏移量Flexoffset 加到Rn 中,结果写回到Rn,Rn 不允许是R15,如:
    LDR R0,[R1],R2,LSL#2 ;
    将存储器地址为R1 的字数据读入寄存器R0,并将新地址R1+R2×4写入R1。
    偏移量Flexoffset可以是下两种形式之:
    1) 取值范围是-4095 到+4095 的整数的表达式,经常是数字常量,如:
    STR R5,[R7],#--8
    2) 一个寄存器再加上移位(移位由立即数指定),如:
    {-}Rm{,shift}
    其中:
    - :可选负号。若带符号“一”,则从Rn 中减去偏移量。否则,将偏移量加到Rn 中。
    Rm :内含偏移量的寄存器。Rm 不允许是R15。
    Shift:Rm 的可选移位方法。可以是下列形式的任何一种:
    ASR n :算术右移n 位(1<=n<=32)
    LSL n :逻辑左移n 位(1<=n<=31)
    LSR n :逻辑右移n 位(1<=n<=32)
    ROR n :循环右移n 位(1<=n<=31)
    RRX :循环右移1 位,带扩展。

AND―――――逻辑"与"操作指令
指令格式:

AND{cond}{S} Rd,Rn,operand2

AND指令将操作数operand2 与Rn 的值按位逻辑"与",结果存放到目的寄存器Rd 中。若设置S,则根据运算结果影响N、Z位,在计算第二操作数时,更新C位,不影响V位(指令ORR、EOR、BIC 对标志位的影响同AND 指令)。

指令示例:
ANDS R1,R1,R2  ;R1=R1&R2,并根据运算的结果更新标志位
AND R0,R0,#0x0F ;R0=R0&0x0F,取出R0最低4位数据。

ORR―――――逻辑"或"操作指令
指令格式:ORR{cond}{S} Rd,Rn,operand2 ORR指令将操作数operand2 与Rn 的值按位逻辑"或",结果存放到目的寄存器Rd 中。指令示例:
ORRS R1,R1,R2 ;R1=R1|R2,并根据运算的结果更新标志位

ORR R0,R0,#0x0F ;R0=R0|0x0F,将R0最低4位置1,其余位不变。

BIC―――――位清除指令
指令格式:
BIC{cond}{S} Rd,Rn,operand2

BIC指令将Rn 的值与操作数operand2 的反码按位逻辑"与",结果存放到目的寄存器Rd 中。指令示例:BIC R0,R0,#0x0F ;将R0最低4位清零,其余位不变。

CMP―――――比较指令

指令格式:

CMP{cond} Rn,operand2

CMP指令用Rn的值减去操作数operand2 ,并将结果的状态(Rn 与operand2比较是大、小、相等)反映在CPSR中,以便后面的指令根据条件标志决定程序的走向。CMP指令与SUBS指令完成的操作一样,只是CMP指令只减,不存结果。

指令示例:
cmp R0,R1 ;比较R0,R1
beq stop ;R0=R1跳到stop
blt less ;R0<R1跳到Less

.
.
.

Less:
.
.
.
Stop:

.

.

.

SUB―――――减法运算指令
指令格式:
SUB{cond}{S} Rd,Rn,operand2 SUB指令用Rn 的值减去操作数operand2 ,并将结果存放到目的寄存器Rd 中。 指令示例:

SUBS R1,R1,R2 ;R1=R1-R2,并并根据运算的结果更新标志位

SUBGT R3,3,#1 ;大于则 R3=R3-1

SUB R0,R2,R3,LSL#2; R0=R2-(R3<<2)

ARM分支指令


助记符


说明


操作


B{cond} lable


分支指令


PC← lable


BL{cond} lable


带链接的分支指令


LR← PC-4 ,PC←lable


BX{cond} Rm


带状态切换的分支指令


PC← Rm,切换处理器状态

 指令的条件码

 条件码  助记符后缀  标志  含义
 0000  EQ  Z置位(Z=1) 相等 
 0001  NE  Z清零(Z=0) 不相等 
 0010  CS  C置位  无符号数大于等于
 0011  CC  C清零  无符号数小于
 0100  MI  N置位 负数 
 0101  PL  N清零 整数或0 
 0110  VS  V置位  溢出
 0111  VC  V清零  未溢出
 1000  HI  C置位且Z清零  无符号数大于
 1001  LS  Z置位且C清零  无符号数小于等于
 1010  GE  N等于V(N=V=1或N=V=0)  带符号数大于或等于
 1011  LT  N不等于V  带符号数小于
 1100  GT  Z清零且N等于V  带符号数大于
 1101  LE  Z置位或N不等于V  带符号数小于或等于
 1110  AL  忽略 无条件执行 


;GPIO寄存器宏定义
GPFCON EQU 0x56000050
GPFDAT EQU 0x56000054
GPFUP EQU 0x56000058

EXPORT LEDTEST
AREA LEDTESTASM,CODE,READONLY ;该伪指令定义了一个代码段,段名为LEDTESTASM,属性只读

LEDTEST
;设置GPF4-GPF7为output
ldr r0,=GPFCON
ldr r1,[r0]
bic r1,r1,#0xff00
orr r1,r1,#0x5500
str r1,[r0]

;禁止GPF4-GPF7端口的上拉电阻
ldr r0,=GPFUP
ldr r1,[r0]
orr r1,r1,#0xf0
str r1,[r0]

looptest
;将数据端口F的数据寄存器的地址附给寄存器r2
ldr r2,=GPFDAT

ldr r3,[r2]
bic r3,r3,#0xf0
orr r3,r3,#0xb0
str r3,[r2] ;GPF6 output 0
ldr r0,=0x2fffff
bl delay ;调用延迟子程序

ldr r3,[r2]
bic r3,r3,#0xf0
orr r3,r3,#0x70
str r3,[r2] ;GPF7 output 0
ldr r0,=0x2fffff         ;初始计数值
bl delay ;调用延迟子程序

ldr r3,[r2]
bic r3,r3,#0xf0
orr r3,r3,#0xd0
str r3,[r2] ;GPF5 output 0
ldr r0,=0x2fffff
bl delay ;调用延迟子程序

ldr r3,[r2]
bic r3,r3,#0xf0
orr r3,r3,#0xe0
str r3,[r2] ;GPF4 output 0
ldr r0,=0x2fffff
bl delay      ;调用延迟子程序

b looptest
delay
sub r0,r0,#1 ;r0=r0-1
cmp r0,#0x0 ;将r0的值与0相比较
bne delay ;比较的结果不为0(r0不为0),继续调用delay,否则执行下一条语句
mov pc,lr ;返回

END ;程序结束符

ARM汇编指令的一些总结-转,布布扣,bubuko.com

时间: 2024-07-30 10:20:55

ARM汇编指令的一些总结-转的相关文章

如何实现对ARM汇编指令的调试?

学习ARM汇编语言时,少不了对ARM汇编指令的调试.作为支持多语言的调试器,gdb自然是较好的选择.调试器工作时,一般通过修改代码段的内容构造trap软中断指令,实现程序的暂停和程序执行状态的监控.为了在x86平台上执行ARM指令,可以使用qemu模拟器执行ARM汇编指令,具体的调试方法,一起来看看吧. 一.准备ARM汇编程序 首先,我们构造一段简单的ARM汇编程序作为测试代码main.s. .globl _start _start: mov R0,#0 swi 0x00900001 以上汇编指

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

自己的一些简单的总结,也是最常用的ARM汇编指令,之后也会不断的补充完善. 1. 汇编系统预定义的段名 .text    @代码段 .data   @初始化数据段 .bss    @未初始化数据段 需要注意的是,源程序中.bss段应该在.text之前. 2.定义入口点 汇编程序的缺省入口是 start标号,用户也可以在连接脚本文件中用ENTRY标志指明其它入口点. .text .global _start _start: 3 .word用法 word expression就是在当前位置放一个wo

ARM汇编指令MCR/MRC学习

MCR指令将ARM处理器的寄存器中的数据传送到协处理器的寄存器中.如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断. 指令的语法格式: MCR{<cond>} p15, 0, <Rd>, <CRn>, <CRm>{,<opcode_2>} MCR2 p15, 0, <Rd>, <CRn>, <CRm>{,<opcode_2>} 其中,<cond>为指令执行的条件码.当<

GNU ARM 汇编指令

http://blog.chinaunix.net/u2/87718/showart_1683402.html GNU ARM 汇编指令简介第一部分 Linux下ARM汇编语法尽管在Linux下使用C或C++编写程序很方便,但汇编源程序用于系统最基本的初始化,如初始化堆栈指针.设置页表.操作 ARM的协处理器等.初始化完成后就可以跳转到C代码执行.需要注意的是,GNU的汇编器遵循AT&T的汇编语法,可以从GNU的站点(www.gnu.org)上下载有关规范. 一. Linux汇编行结构任何汇编行

ARM汇编指令

ARM处理器的指令集可以分为跳转指令.数据处理指令.程序状态寄存器(PSR)处理指令.加载/存储指令.协处理器指令和异常产生指令6大指令. 一.跳转指令 跳转指令用于实现程序流程的跳转,在ARM程序中有以下两种方法可以实现程序流程的跳转.Ⅰ.使用专门的跳转指令: Ⅱ.直接向程序计数器PC写入跳转地址值,通过向程序计数器PC写入跳转地址值,可以实现在4GB的地址空间中的任意跳转,在跳转之前结合使用MOV LR,PC等类似指令,可以保存将来的返回地址值,从而实现在4GB连续的线性地址空间的子程序调用

ARM汇编指令汇总

1.ARM汇编的格式:    在ARM汇编里,有些字符是用来标记行号的,这些字符要求顶格写:有些伪码是需要成对出现的,例如ENTRY和END,就需要对齐出现,也就是说他们要么都顶格,要么都空相等的空,否则编译器将报错.常量定义需要顶格书写,不然,编译器同样会报错.    2.字符串变量的值是一系列的字符,并且使用双引号作为分界符,如果要在字符串中使用双引号,则必须连续使用两个双引号.    3.在使用LDR时,当格式是LDR r0,=0x022248,则第二个参数表示地址,即0x022248,同

常用ARM汇编指令

一面学习,一面总结,一面记录. 下面是整理在网上找到的一些资料,简单整理记录一下,方便以后查阅. ARM处理器的指令集可以分为跳转指令.数据处理指令.程序状态寄存器(PSR)处理指令.加载/存储指令.协处理器指令和异常产生指令6大指令. 一.跳转指令 跳转指令用于实现程序流程的跳转,在ARM程序中有以下两种方法可以实现程序流程的跳转. Ⅰ.使用专门的跳转指令: Ⅱ.直接向程序计数器PC写入跳转地址值,通过向程序计数器PC写入跳转地址值,可以实现在4GB的地址空间中的任意跳转,在跳转之前结合使用M

ARM汇编指令特点

根据朱有鹏老师课程笔记整理而来: (汇编)指令是CPU机器指令的助记符,经过编译后会得到一串1 0组成的机器码,由CPU读取执行. (汇编)伪指令本质上不是指令(只是和指令一起写在代码中),它是编译器环境提供的,目的是用来指导编译过程,经过编译后伪指令最终不会生成机器码. 两种不同风格的ARM指令 ARM官方的ARM汇编风格:指令一般用大写.Windows中IDE开发环境(如ADS.MDK等)常用.如: LDR R0, [R1] GNU风格的ARM汇编:指令一般用小写字母.linux中常用.如:

arm汇编指令的条件码

几乎所有的ARM指令都可以包含一个可选的条件码,句法中以{cond}来标识.可用的条件码如下面所示.几乎所有的ARM数据处理指令均可以根据执行结果来选择是否更新条件码标志,即在指令中包含后缀S. 条件玛 助记符 标志 含义 0000 EQ Z置位 相等 0001 NE Z清零 不相等 0010 CS C置位 无符号数大于或等于 0011 CC C清零 无符号数小于 0100 MI N置位 负数 0101 PL N清零 整数或零 0110 VS V置位 溢出 0111 VC V清零 未溢出 100