1.汇编指令LSL
2012-11-15 15:03 匿名 | 分类:汇编语言 | 浏览623次
R1=0x31,R2=0x2 则执行指令ADD R0,R1,R2 LSL #3 后,R0的值是???
R0最终的值是0x198首先 R1+R2=0x33被送到R0第二条逻辑左移3位,0x33左移3位的结果就是0x198,
R0为32为寄存器而非8位寄存器,所以左移并没有导致溢出,0x198就是最后的结果附二进制形式的移动情况:
左移前的R0:00000000 00000000 00000000 00110011左移后的R0:00000000 00000000 00000001 10011000
2.
LDR指令的格式: LDR{条件} 目的寄存器 <存储器地址>
作用:将存储器地址所指地址处连续的4个字节(1个字)的数据传送到目的寄存器中。
LDR R0,[R1];将存储器地址为R1的字数据读入寄存器R0。LDR R0,[R1,R2] ;
将存储器地址为R1+R2的字数据读入寄存器R0。LDR R0,[R1,#8];
将存储器地址为R1+8的字数据读入寄存器
3.
SP是堆栈寄存器,在调用子程序时,都会用到,保存原来程序的环境使用,如各个寄存器的内容,
最重要的是,调用返回时程序的运行指令地址,这是由调用时将返回地址压入堆栈,返回时取出并传给PC寄存器来实现的。
给SP的初始化值的大小,显示了堆栈的存放位置和堆栈的大小,如果堆栈太小,会出现堆栈溢出的问题。
4.
LDM指令:带状态寄存器的批量内存字数数据读取指令
LDM指令将数据从连续的内存单元中读取到指令中寄存器列表中的各寄存器中。
它同时将当前处理器模式对应的SPSR寄存器内容复制到CPSR寄存器中。用于从异常中断中返回恢复压栈的寄存器值
5.
STM指令:将指令中寄存器列表中的各寄存器中的各寄存器数值写入到连续的内存单元中。
它主要用于块数据的写入、数据栈操作以及进入子程序时保存相关的寄存器操作。
汇编指令长跳转:通过直接向PC寄存器读取子数据,程序可以实现在4GB的地址空间的任意跳转,这种跳转叫做长跳转
在下面的代码段中,程序将跳转到子程序Function处开始执行。子程序执行完成后,将返回到return_here处。
ADD LR,PC,#4 ;将子程序function的返回地址设置为当前地址后12字节处,即return_here处
LDR PC,[PC,#-4] ;从下一条指令(DCD function)中读取跳转的目标地址,这里为function
DCD function ;DCD微操作保存跳转的地址
return_here
6.
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 ;程序结束符