href="file:///C:/Users/BJX/AppData/Local/Temp/msohtmlclip1/01/clip_filelist.xml" rel="File-List" /> href="file:///C:/Users/BJX/AppData/Local/Temp/msohtmlclip1/01/clip_themedata.thmx" rel="themeData" /> href="file:///C:/Users/BJX/AppData/Local/Temp/msohtmlclip1/01/clip_colorschememapping.xml" rel="colorSchemeMapping" />
ARM汇编指令学习笔记(一)
汇编真的需要自己学.网上的资料满天飞,又能有多少能让人看进去?
闲话少说,切入正题:ARM(单片机)汇编常用指令用法总结,纯属原创,如有谬误,还望指正.
【这里带“【】”的是笔者随笔,贻笑大方,还望见谅】
MOV
传送指令MOV(Move)把一个字节、字或双字的操作数从源位置传送到目的位置,源操作数的内容不变。可以实现立即数到通用寄存器或主存的传送,通用寄存器与通用寄存器、主存或段寄存器之间的传送,主存与段寄存器之间的传送。该操作属于复制性质,不属于搬家性质。 例如: MOV EAX,050ah ;将十六进制数050a 传送到通用寄存器eax中 。
注意:【感悟:猜想是程序出错的可能原因之一】
1.目的操作数要与源操作数类型要一致
2.目的操作数要和源操作数类型之一必须要有明确的类型
使用方法:
1. 以累加器A为目的操作数的源操作数:#data,direct,Rn,@Ri(指令中的Ri表示取值可以是R0或者R1,Rn表示可以取R0到R7,Ri一般用于间接寻址。具体一个R0或R1是用于Ri还是Rn要看这条指令是什么 )
2. 以工作寄存器Rn为目的操作数的源操作数:A,direct,#data【疑问:工作寄存器之间能不能MOV呢?】
3. 以直接地址direct为目的操作数的源操作数:A,Rn,@Ri,direct2,#data
4. 以寄存器间接地址@Ri为目的操作数的源操作数:A,direct,#data
5. 除此之外还有涉及到DPTR,MOVX,MOVC的指令,在总结寻址时会提及。
应用:
ARM的两种跳转方式之一:MOV PC,地址;向程序计数器直接写跳转地址,能在4G连续空间内任意跳转。此外还可通过B,BL,BLX,BX在前后32MB范围内跳转,详见后文相关笔记。
ADD
没找到资料,简而言之:ADD A,Rn就是把Rn里的数加入A。
应用:
1. 目的操作数必为A,源操作数可为:Rn,@Ri,direct,#data
2. 此外,ADD课替换为ADDC,带上了Cy(进位标志位)
SUBB
SUBB【全称没找到,但地球人都知道这是减】。
应用:
1.和ADD同,目的操作数必为A,源操作数可为:Rn,@Ri,direct,#data【这也在一定程度上证明了SUBB与ADD本质是相同的】
B/BL
B是ARM最简单的跳转指令,但注意跳转的是相对当前PC值的偏移量【就像单片机的SJMP】BL很常用。它在跳转之前会在寄存器LR(R14)中保存PC的当前内容。BL经典用法如下:
bl NEXT;跳转到NEXT
……
NEXT:……
……
Mov pc,lr;从子程序中返回
【附:单片机中跳转的用法:(addr :代表8位地址 addr16:代表16位地址)
长转移指令: LJMP addr16 ;addr16~0→PC
短转移指令: AJMP addr11 ;PC+2→PC,addr10~0→PC10~0
相对转移指令: SJMP rel ;PC+2→PC,PC+rel→PC
间接转移指令: JMP @A+DPTR;A+DPTR→PC】
LDR
LDR【具体全称也没查到L估计是LOAD,R估计是ROM或者RAM】就是把数据总存储器传到寄存器。
注意:
有个伪指令也用LDR:LDR Rn,=expr;作用是装载一个32bit地址或者常量到寄存器Rn。比如:ldr r2,=0x55aa;其实MOV R2,#OX55AA也可以做到,但是LDR是伪指令,也就是说编译时编译器会处理它的:如果该数字常量在MOV指令范围内,汇编器会把这个指令作为MOV;如果不在MOV范围内,汇编器把该常量放在程序后面,用LDR来读取,PC和该常量的偏移量不能超过4KB【大致可以明白了】
应用:
LDR R0,=0X12345678;伪指令,但这点MOV就做不到,MOV限制立即数长度为8位,即小于256(2的8次方【一定注意是8次方】)!
STR
STR 字数据存储指令 【注意方向和MOV等相反是Rd→addr】
格式:STR{<cond>} <Rd>,<addr>;
功能:把寄存器Rd中的字数据(32位)保存到addr所表示的内存地址中,同时还可以把合成的有效地址写回到基址寄存器。 地址addr可以是一个简单的值、一个偏移量,或者是一个被移位的偏移量。 寻址方式同LDR指令。
例如:
STR R0,[R1],#5;把R0中的字数据保存到以R1+5为地址的内存中,然后R1=R1+5(如果是[人,#5]的话R1不变)
(时间太晚了,后面的就明天解决!还好常用的几个都解决了)