ARM汇编指令
⽬录
⼀、ARM汇编指令集
、两个概念:指令和伪指令
(汇编)指令是CPU机器指令的助记符,经过编译后会得到⼀串1、0组成的机器码,可以由CPU读取执⾏。
(汇编)伪指令本质上不是指令(只是和指令⼀起写在代码中),它是编译器环境提供的,⽬的是⽤来指导编译过程,经过编译后伪指
令最终不会⽣成机器码。
、两种不同风格的ARM指令
ARM官⽅的ARM汇编风格:指令⼀般⽤⼤写、Windows中IDE开发环境(如ADS、MDK等)常⽤。如:LDRR0,[R1]
(我们使⽤)GNU风格的ARM汇编:指令⼀般⽤⼩写字母、linux中常⽤。如:ldrr0,[r1]
两种风格的指令差别不⼤,但是伪指令的差别特别⼤。
、ARM汇编特点
、特点1:LDR/STR架构
ARM采⽤RISC架构,CPU本⾝不能直接读取内存,⽽需要先将内存中内容加载⼊CPU中的通⽤寄存器中才能被CPU处理。
ldr(loadregister)指令将内存内容加载⼊通⽤寄存器。
str(storeregister)指令将寄存器内容存⼊内存空间中。
ldr/str组合⽤来实现ARMCPU和内存数据交换
注意:
CPU与内存之间的数据交换需要通过CPU中的通⽤寄存器才可以,所以访问效率会低⼀些。
、特点2:8种寻址⽅式
Mov表⽰从寄存器到寄存器,ld和str表⽰从内存到寄存器。
寄存器寻址movr1,r2
R1和r2都是寄存器名字,意思是将r2中的内容传送到r1
⽴即寻址movr0,#0xFF00
就是⽴即数寻址,意思是将⽴即数#0xFF00给r0
寄存器移位寻址movr0,r1,lsl#3
意思是将r1左移3位后传送个r0(lsl表⽰左移)
寄存器间接寻址ldrr1,[r2]
[r2]表⽰r2中存储的所指向的内存的地址,意思是将r2中存储的所指向的内存中的数据给r1。
基址变址寻址ldrr1,[r2,#4]
意思是将r2中存储的地址加上4后所指向的地址中的内容给r1。
多寄存器寻址ldmiar1!,{r2-r7,r12}
意思是⼀次访问7个寄存器,{r2-r7,r12}表⽰r2、r3、r4、r5、r6、r7、r12这7个寄存器。⽽r1!表⽰⼀串内存空间,相当于数组头地
址,第⼆个参数有7个寄存器,它就有7个内存空间。
将r1所存地址所代表的内存及其后边的7个连续内存中存储的数据传给7个寄存器。
堆栈寻址stmfdsp!,{r2-r7,lr}
sp是堆栈指针,是⼀个确定的值。具体和多寄存器寻址类似。
相对寻址beqflag以PC为标志来跳转。
在汇编中,“flag:”这种形式的写法叫做标号。⽤来标记后边指令的地址。这样可以直接跳转到标号出执⾏。和C语⾔中的goto⼀样。
、特点3:指令后缀
同⼀指令经常附带不同后缀,变成不同的指令。
经常使⽤的后缀有:
B(byte)功能不变,操作长度变为8位
H(halfword)功能不变,长度变为16位
S(signed)功能不变,操作数变为有符号,
如:ldrldrbldrhldrsbldrsh
S(S标志)功能不变,影响CPSR标志位
如:mov和movs
movr0,#0将0这个数字赋给r0,且r0中的标志位不变。
movsr0,#0将0这个数字赋给r0,且r0中的Z标志位变为1。
、特点4:条件执⾏后缀(⼤于、⼩于、等于)
例如:
movr0,r1相当于C语⾔中的r0=r1;
moveqr0,r1如果eq后缀成⽴,则直接执⾏movr0,r1;如果eq不成⽴,则此语句直接作废,相当于没有。类似于C语⾔中
的
if(eq){r0=r1;}
注意:
条件后缀是否成⽴不是取决于本句代码,⽽是取决于这句代码之前的代码运⾏的结果。
条件后缀决定了本句代码是否被执⾏,⽽不会影响上⼀句和下⼀句代码是否执⾏。
、特点5:多级指令流⽔线
为增加处理器指令流的速度,ARM使⽤多级流⽔线.,下图为3级流⽔线⼯作原理⽰意图。(S5PV210使⽤13级流⽔线,ARM11为8
级)允许多个操作同时处理,⽽⾮顺序执⾏。
PC指向正被取指的指令,⽽⾮正在执⾏的指令。
、数据传输与跳转指令
、数据处理指令
数据传输指令movmvn
mov(move)movr1,r0在两个寄存器之间进⾏数据传递
movr1,#oxff将⽴即数赋值给寄存器
mov和mvn⽤法⼀样,区别是mov是原封不动的传递,⽽mvn是按位取
反后传递。
例如:r1=0x000000ff,然后movr0,r1后,r0=0xff,但是我mvnr0,r
后,r0=0xffffff00
算术指令addsubrsbadcsbcrsc
逻辑指令andorreorbic
and逻辑与
orr逻辑或(位或)
eor裸机异或
bic位清除指令
bicr0,r1,#0x1f将r1中的数的bit0到bit4清零后赋值给r00x1f=0x00011111
⽐较指令(⽐较指令⽤来⽐较2个寄存器中的数)cmpcmntstteq
cmpcmpr0,r1判断r0-r1=0,等价于subr2,r0,r1(r2=r0-r1)
cmncmnr0,r1判断r0+r1=0,等价于addr0,r1
tsttstr0,#0xf测试r0的bit0~bit3是否全为0
tstr0,#0x8测试r0的bit3是否为0。
teqteqr0,r1对两个数进⾏EOR(异或),⽐较是否相等。若两个数
相等,结果为假,否则,结果为真。
注意:⽐较指令不⽤后加s后缀就可以影响cpsr中的标志位。
⽐较指令不需要保存结果,直接访问标志位即可知道⽐较指令的结果。
乘法指令mvlmlaumullumlalsmullsmlal
前导零计数clz(基本⽤不到)
、cpsr访问指令
CPSR寄存器⽐较特殊,需要专门的指令访问,这就是mrs和msr。
mrs&msr
mrs⽤来读psr,msr⽤来写psr
mrsr0,cpsr将cpsr读取到寄存器r0中
msrcpsr,r0将r0中的数读取到cpsr中。
cpsr和spsr的区别和联系:cpsr是程序状态寄存器,整个SoC中只有1个;⽽spsr有5个,分别在5种异常模式下,作⽤是当从普通模式进
⼊异常模式时,⽤来保存之前普通模式下的cpsr的,以在返回普通模式时恢复原来的cpsr。
、跳转指令b&bl&bx
b(branch)直接跳转(就没打算返回),与C语⾔的goto类似。
bl(branchandlink),跳转前把返回地址放⼊lr中,以便返回,以便⽤于函数调⽤。
bx跳转同时切换到ARM模式,⼀般⽤于异常处理的跳转。
、访存指令(访问内存)ldr/str&ldm/stm&swp
单个字/半字/字节访问ldr/str
多字批量访问ldm/stm
swp同时读写
swpr1,r2,[r0]将r0所指向的内存中的值读取到r1中,同时将r2中的值写⼊到r0所指向的内存中。
swpr1,r1,[r0]将r0所指向的内存中的值读取到r1中,同时将r1之前的值写⼊到r0所指向的内存中。
、软中断指令(⽤软件模拟中断)(⽤于操作系统)
swi(softwareinterrupt)
软中断指令⽤来实现操作系统中系统调⽤
、⽴即数
合法⽴即数与⾮法⽴即数
ARM指令都是32位,除了指令标记和操作标记外,本⾝只能附带很少位数的⽴即数。因此⽴即数有合法和⾮法之分。
合法⽴即数:经过任意位数的移位后⾮零部分可以⽤8位表⽰的即为合法⽴即数
例如:
合法⽴即数:0x000000ff0x00ff00000xf000000f
⾮法⽴即数:0x000001ff
、什么是协处理器
SoC内部的另⼀个处理核⼼,协助主处理器CPU实现某些功能,被主处理器CPU调⽤执⾏⼀定任务。
协处理器是通过编号来区分的,在使⽤时只需要知道他的编号就可以操作。
ARM设计上⽀持多达16个协处理器,但是⼀般SoC只实现其中的CP15.(cp:coprocessor)
协处理器和MMU、cache、TLB等处理有关,功能上和操作系统的虚拟地址映射(MMU)、cache管理等有关。
、协处理器cp15操作指令mcr&mrc
、操作指令的作⽤
mrc⽤于读取CP15中的寄存器
mcr⽤于写⼊CP15中的寄存器
、操作指令的使⽤⽅法
mcr{
_1:对于cp15永远为0
:ARM的普通寄存器,不能是r15,否则结果未知
:cp15的寄存器,合法值是c0~c15
:cp15的寄存器,⼀般均设为c0
_2:⼀般省略或为0
例⼦:
mrcp15,0,r0,c1,c0,0
bicr0,r0,#0x00002000
bicr0,r0,#0x00000007
orrr0,r0,#0x00000002
orrr0,r0,#0x00000800
mcrp15,0,r0,c1,c0,0
与栈的处理
、为什么需要多寄存器访问指令
ldr/str每周期只能访问4字节内存,如果需要批量读取、写⼊内存时太慢,解决⽅案是stm/ldm
ldm(loadregistermutiple)
stm(storeregistermutiple)
、ldm/stm的8种后缀
ia(increaafter)先传输,再地址+4
ib(increabefore)先地址+4,再传输
da(decreaafter)先传输,再地址-4
db(decreabefore)先地址-4,再传输
fd(fulldecrea)满递减堆栈
ed(emptydecrea)空递减堆栈
fa(·······)满递增堆栈
ea(·······)空递增堆栈
举例
stmiasp,{r0-r12}
说明:
将r0存⼊sp指向的内存处(假设为0x30001000);然后地址+4(即指向0x30001004),将r1存⼊该地址;然后地址再+4(指
向0x30001008),将r2存⼊该地址······直到r12内容放⼊(0x3001030),指令完成。
⼀个访存周期同时完成13个寄存器的读写
、四种栈
空栈:栈指针指向空位,每次存⼊时可以直接存⼊然后栈指针移动⼀格;⽽取出时需要先移动⼀格才能取出
满栈:栈指针指向栈中最后⼀格数据,每次存⼊时需要先移动栈指针⼀格再存⼊;取出时可以直接取出,然后再移动栈指针
增栈:栈指针移动时向地址增加的⽅向移动的栈
减栈:栈指针移动时向地址减⼩的⽅向移动的栈
、!的作⽤
ldmiar0,{r2-r3}
ldmiar0!,{r2-r3}
感叹号的作⽤就是r0的值在ldm过程中发⽣的增加或者减少最后写回到r0去,也就是说ldm时会改变r0的值。
、^的作⽤
ldmfdsp!,{r0-r6,pc}
ldmfdsp!,{r0-r6,pc}^
^的作⽤:在⽬标寄存器中有pc时,会同时将spsr写⼊到cpsr,⼀般⽤于从异常模式返回。
、总结
批量读取或写⼊内存时要⽤ldm/stm指令
各种后缀以理解为主,不需记忆,最常见的是stmia和stmfd
谨记:操作栈时使⽤相同的后缀就不会出错,不管是满栈还是空栈、增栈还是减栈
ARM默认的是满减栈(stmfd)
、伪指令的意义
伪指令不是指令,伪指令和指令的根本区别是经过编译后会不会⽣成机器码。指令编译后⽣产机器码,伪指令编译后消失。
伪指令的意义在于指导编译过程。
伪指令是和具体的编译器相关的,我们使⽤gnu⼯具链,因此学习gnu环境下的汇编伪指令。
、gnu汇编中的⼀些符号
@⽤来做注释。可以在⾏⾸也可以在代码后⾯同⼀⾏直接跟,和C语⾔中//类似
:以冒号结尾的是标号
.点号在gnu汇编中表⽰当前指令的地址
例⼦:死循环(相当于C语⾔中的while(1);)
flag:flag标号,表⽰⼀个地址
bflag跳转到flag本⾝
b.跳转到当前指令的地址(这⼀句相当于上边两⾏)
#⽴即数前⾯要加#或$,表⽰这是个⽴即数
、常见的gnu伪指令
.global_start@给_start外部链接属性,为了让别的⽂件中访问
.@指定当前段为代码段
.@⽤于定义数据,相当于C语⾔中定义变量
例⼦:
IRQ_STACK_START:
.word0x0badc0de
其中IRQ_STACK_START为变量名,.word为变量类型,0x0badc0de为变量的值。相当于unsignedintIRQ_STACK_START=
0x0badc0de。
.@定义数据(双字,⼩数,字符串)
.align4@以16字节对齐,2的4次⽅。
.align2@以4字节对齐,2的2次⽅
.balignl160xabcdefgh@16字节对齐填充
B表⽰位填充;align表⽰对齐;l表⽰long,以4字节为单位填充;16表⽰以16字节对齐;0xabcdefgh是⽤来填充的原料。
例⼦:
地址
l160xabcdefgh
0x0000000c0xabcdefgh
0x00000010下⼀条指令
说明:
0x00000008为原地址,运⾏.balignl160xabcdefgh伪指令后,需要16字节对齐,跳转到0x00000010,中间的地址0x0000000c
⽤0xabcdefgh填充。
.equ@类似于C中宏定义
、偶尔⽤到的gnu伪指令
.end@标识⽂件结束
.include@头⽂件包含
.arm/.code32@声明以下为arm指令
.thumb/.code16@声明以下为thubm指令
、最重要的伪指令
ldr⼤范围的地址加载指令(将地址加载到寄存器中)
adr⼩范围的地址加载指令(将地址加载到寄存器中)
adrl中等范围的地址加载指令(将地址加载到寄存器中)
nop空操作
注意:
ARM中有⼀个ldr指令,还有⼀个ldr伪指令。⼀般都使⽤ldr伪指令⽽不
⽤ldr指令。
如果是指令,⽴即数前边是#,如果是伪指令,⽴即数前边是=;涉及到合法/⾮法⽴即数,设计到ARM⽂字池。
例如:
ldr指令:ldrr0,#0xff需要编程⼈员考虑⽴即数是否合法
ldr伪指令:ldrr0,=0xff不⽤考虑⽴即数是否合法
、adr和ldr
adr编译时会被1条sub或add指令替代,⽽ldr编译时会被⼀条mov指令替代或者⽂字池⽅式处理;
adr总是以PC为基准来表⽰地址,因此指令本⾝和运⾏地址有关,可以⽤来检测程序当前的运⾏地址在哪⾥(相对寻址)
ldr加载的地址和链接时给定的地址有关,由链接脚本决定。
adr和ldr的差别:
ldr加载的地址在链接时确定,⽽adr加载的地址在运⾏时确定;所以我们可以通过adr和ldr加载的地址⽐较来判断当前程序是否在链接时指
定的地址运⾏。
本文发布于:2022-12-30 00:46:46,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/90/56458.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |