mov指令用法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mov指令用法相关的知识,希望对你有一定的参考价值。
哪些用法是错误的?
1.立即数送寄存器或主存MOV
reg/mem
,
im
mov
al
,
4
;
al←4,字节传送
mov
cx
,
0ffh
;
cx←00ffh,字传送
mov
si
,
200h
;
si←0200h,字传送
mov
byte
ptr
[si]
,
0ah
;
byte
ptr
说明是字节操作
mov
word
ptr
[si+2
],
0bh
;
word
ptr
说明是字操作
#
注意立即数是字节量还是字量
#
明确指令是字节操作还是字操作
2.寄存器送(段)寄存器或主存
MOV
reg/mem/seg
,
reg;
mov
ax
,
bx
;
ax←bx,字传送
mov
ah
,
al
;
ah←al,字节传送
mov
ds
,
ax
;
ds←ax,字传送
mov
[bx]
,
al
;
[bx]←al,字节传送
3.主存送(段)寄存器
MOV
reg/seg
,
mem;
mov
al
,
[bx]
mov
dx
,
[bp]
;
dx←ss:[bp]
mov
es
,
[si]
;
es←ds:[si]
#
不存在存储器向存储器的传送指令
4.段寄存器送寄存器或主存
MOV
reg/mem
,
seg;
mov
si
,
ds
mov
ax
,
es
;
ax←es
mov
ds
,
ax
;
ds←ax←es
#
对段寄存器的操作有一些限制MOV指令传送功能:
非
法
传
送
种
种
1.两个操作数的类型不一致
–-----例如源操作数是字节,而目的操作数是字;或相反
•
绝大多数双操作数指令,除非特别说明,目的操作数与源操作数必须类型一致,否则为非法指令
MOV
AL
,
050AH;非法指令:050Ah为字,而AL为字节
•
寄存器有明确的字节或字类型,有寄存器参与的指令其操作数类型就是寄存器的类型
•
对于存储器单元与立即数同时作为操作数的情况,必须显式指明;
byte
ptr
指示字节类型
,
word
ptr
指示字类型。
2.两个操作数不能都是存储器
–------传送指令很灵活,但主存之间的直接传送却不允许
•
8086指令系统不允许两个操作数都是存储单元(除串操作指令),要实现这种传送,可通过寄存器间接实现
mov
ax
,
buffer1;ax←buffer1(将buffer1内容送ax)
mov
buffer2
,
ax;buffer2←ax;这里buffer1和buffer2是两个字变量、;实际表示直接寻址方式
3.段寄存器的操作有一些限制
–----段寄存器属专用寄存器,对他们的操作能力有限
•
不允许立即数传送给段寄存器
MOV
DS,100H;非法指令:立即数不能传送段寄存器
•
不允许直接改变CS值
MOV
CS,[SI]
;不允许使用的指令
•
不允许段寄存器之间的直接数据传送
MOV
DS,ES;非法指令:不允许段寄存器间传送 参考技术A MOV指令可以在CPU内或CPU和存储器之间传送字或字节,它传送的信息可以从寄存器到寄存器,立即数到寄存器,立即数到存储单元,从存储单元到寄存器,从寄存器到存储单元,从寄存器或存储单元到除CS外的段寄存器(注意立即数不能直接送段寄存器),从段寄存器到寄存器或存储单元。
虽然这个问题有点喜剧,但我还是给你最详细的解答:
解:mov指令是汇编里使用最频繁的指令,它相当于高级语言中的赋值语句。
指令格式如下:
mov
reg/mem,reg/mem/Imm
该指令的功能是:把源操作数(第二操作数)的值传给目的操作数(第一操作数)。指令执行后,目的操作数的值被改变,而源操作数的值不变。 参考技术B MOV BL,AX(数据长度不匹配)
MOV DS,2000H(不允许给段存储器用立即数赋值)
MOV CS,AX(禁止用MOV指令给CS赋值)
MOV [AX],[2000H](禁止直接在存储器间传送)
MOV [2000H],20H(数据长度不确切,应改为
MOV BYTE PTR [2000H],20H)
太多了,不说了。 参考技术C MOV BL,AX(数据长度不匹配)
MOV DS,2000H(不允许给段存储器用立即数赋值)
MOV CS,AX(禁止用MOV指令给CS赋值)
MOV [AX],[2000H](禁止直接在存储器间传送)
MOV [2000H],20H(数据长度不确切,应改为
MOV BYTE PTR [2000H],20H)
太多了,不说了! 参考技术D SEE
ARM汇编指令
转载:http://blog.csdn.net/horizontalview/article/details/50773740
1.mov的用法
在ARM体系中,mov只能用于数据在寄存器之间的移动或者往寄存器中写入立即数。
格式如下:mov{条件}{s} 目的寄存器,源操作数
mov R1,R2;
2.ldr的用法
LDR是将内存中的数载入到寄存器,LDR可以载入立即数。
格式如下:LDR 目的寄存器,源
LDR R1,=0xE0000000 ;R1=0xE0000000 LDR R1,0xE0000000 ;将内存中地址为0xE0000000的内容载入到R1 LDR R1,[R0] ;将R0中的数所指定的地址的内容传输到R1
3.str的用法
STR是将寄存器中的数字载入内存。
格式如下:STR{条件} 源寄存器,<存储器地址>
STR R1,[R0] ;将R1中的内容传输到R0中的数所指定的地址的内存中去
三者区别:
mov 只能用于寄存器之间的传输,传输立即数时有条件限制,只能装载通过偶数次移位能得到的立即数。
str/ldr 可以用于寄存器与内存之间的数据交换,STR是将寄存器中的数载入内存,LDR是将内存中的数载入到寄存器,LDR可以载入立即数。
并且LDR在往寄存器中载入立即数时,不受立即数的限制,而mov受其限制。
ARM常用伪指令
B,BL MOV,MVN LDR,STR ADD,SUB,ADC,SBC,MUL AND,ORR,XOR,TST,BIC CMP LDM/STM NOP
1.跳转语句B,BL:
程序流程的跳转,在 ARM 程序中有两种方法可以实现程序流程的跳转指令用于实现
使用专门的跳转指令 B
直接向程序计数器PC 写入跳转地址值
这是几乎是任何一种CPU必备的机器,PC表示CPU当前执行语句位置,改变PC的值,相当于实现程序跳转
如实现类似C语言的Return 语句,就是用MOV PC,LR
这里可以在任意4G的空间进行跳转
B(Branch)指令表示无条件跳转。
B main;//跳转到标号为main地址代码处
BL指令(Branch with Link),带有返回值的跳转
BL比B多做一步,在跳转前,BL会把当前位置保存在R14(即LR寄存器),当跳转代码结束后,用MOV PC,LR指令跳回来,这实际上就是C语言执行函数的用法,
汇编里调子程序都用BL,执行完子函数后,可以用MOV PC,LR跳回来.
BL delay ;执行子函数或代码段delay ,delay可以为C函数.
注意:与Mov PC,XXX能在4G空间跳转不同,B语句只能在32M空间跳转(因为偏移量是一个有符号26bit的数值=32M)
2.传输数据指令MOV,MVN
MOV(MOVE)指令可完成从另一个寄存器、被移位的寄存器或将一个立即数加载到目的寄存器
MOV R0,R1 ; 把R1的值传到R0
MOV R3,#3 ;把常数3传给R3,MOV中用#表示常数,这个值不能超过
MVN( MOVE Negative)取反后再传值,比MOV多了一步取反
MVN R0, #0 ;把0取反(即-1)传给R0
MVN R1,R2 ;把R2的值取反传给R1
3.加载/存储指令LDR,STR
LDR,STR是用于寄存器和外部存储器交换数据指令,注意与MOV的区别,后面只在寄存器或常数交换.
LDR/STR可以采用多种寻址方式,以下只举出使用频率最高几种用法
LDR(load)用于把一个32Bit的WORD数据从外部存储空间装入到寄存器中
LDR R0,[R1]; R1的值当成地址,再从这个地址装入数据到R0 (R0=*R1)
LDR R1,=0x30008000 ; 把地址0x30008000的值装入到R1中,LDR中用常数要用=打头.(注意跟MOV的区别,MOV是#)
ldr r0, =(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0)
用位与的方法赋值
STR(Store) 用于把一个寄存器的值存入外部存储空间,是LDR的逆操作.
STR R0,[R1] ; 把R0的值,存入到R1对应地址空间上(*R1 = R0)
STR R0,=0x30008000 ;把R0中值存入到地址0x30008000
S2C2440的中CPU内核以外的模块的控制寄存器空间也是属于外部空间,所以也得用如下指令LDR R0,=GPFDAT
4.算术运算指令,ADD/ADC SUB/SBC MUL
ADD加法指令
ADD R0,R1,R2; R0=R1+R2
ADD R0,R1,#3 ;R0=R1+3
ADC带进位加法指令,即除了加两个数以外,还要把CPSR的C值也要带进来
通常用于大数(超过32Bit整数)相加,这时单用ADD不能处理,必须折成两步,其中一步用ADC.
以下是做64Bit的加法
ADDS R0,R1,R2; R0=R1+R2,ADDS中S表示把进位结果写入CPSR
ADC R5,R3,R4 ;R5=R3+R4+C
SUB减法指令
SUB R0,R1,R2; R0=R1-R2
SUB R0,R1,#3 ;R0=R1-3
SBC带进位减法指令,即除了加两个数以外,还要把CPSR的C值也要带进来,类似ADC
以下是做64Bit的减法
SUBS R0,R1,R2; R0=R1-R2,SUBS中S表示把进位结果写入CPSR
SBC R5,R3,R4 ;R5=R3-R4-C
MUL 乘法指令
MUL R0,R1,R2; R0=R1*R2
MUL R0,R1,#3 ;R0=R1*3
5.位操作指令AND,ORR,TST,BIC
AND位与指令
AND R0,R1,R2; R0=R1 & R2
AND R0,R1,#0xFF ;R0=R1 & 0xFF
ORR位或指令
ORR R0,R1,R2; R0=R1 | R2
ORR R0,R1,#0xFF ;R0=R1 | 0xFF
TST测试某一位是否为1,并把结果写入CPSR,供下一句使用
TST R1,#0xffe; 等同于if(R1 & 0xffe)
TST R1,#%1;测试最低位是否为1,%表示二进制
BIC清位操作
BIC R0,R0,#0xF ; 等同于 R0 &=~(0xF)
BIC R0,R0,#%1011 ; 该指令清除 R0 中的位 0 1 3,其余的位保持; %表示是二进制,0x表示十六进制
6.比较指令CMP
CMP比较两个操作数,并把结果存入CPSR供下一句语句使用
CMP R0,R1; 比较R0,R1
7.多寄存器语句传输指令LDM,STM
类似于一次传一个BUFFER到寄存器当中,或反过来.后面一般要接一个地址改变方法
LDM 从BUFFER传数据到多个寄存器
LDMIA R0! ,{R3-R9} ;加R0指向的地址上连续空间的数据,保存到R3-R9当中,!表示R0值更新,IA后缀表示按WORD递增
LDMFD SP!,{R0-R7,PC}^;恢复现场,异常处理返回,^表示不允许在用户模式下使用。
STM 从寄存器列表向存储空间传值。
STMIA R1!,{R3-R9} ;将R3-R9的数据存储到R1指向的地址上,R1值更新。
STMFD SP!,{R0-R7,LR}; 现场保存,将R0~R7,LR入栈
stmfd sp!,{r8-r9}
,把SP寄存器对应的地址的值存到R8,R9当中.!表示最后的值写入SP中。
8.ARM指令的变形
大部分指令后位可以接 <cond>与S两个特殊位来表示,对CPSR特殊的一些判断
S,表示当前指令执行后把结果改写CPSR
subs,Adds
<Cond>取决于具体条件,只有CPSR满足指定条件时才指这一指令
以上是关于mov指令用法的主要内容,如果未能解决你的问题,请参考以下文章