要想进行ARM的汇编编程,首战之地要知道最根本、最常用的指令,而要了解指令则有必要要了解寻址办法。所以本文将聚集在——根本寻址办法和根本指令。
首要,来看一看咱们现已见过的2条指令:MOV pc, lr; BL addsub
最简略的汇编指令格局是操作码(例如:MOV、BL)和操作数(例如:pc, lr, addsub)。操作码易于了解,例如MOV表明将某个值从一处传送到另一处,BL表明跳转到某处;而操作数则表明一处和另一处到底是哪里(是在寄存器中仍是内存中),要跳转的方位在哪里(或者是肯定地址或者是相对地址)。
操作数部分要处理的问题是:到哪里去取得操作数?因而就有了寻址办法的分类。根本上来讲,ARM共有8种寻址办法,本文咱们了解其间最根本的3种寻址办法:寄存器寻址、当即数寻址、寄存器直接寻址。
1、寄存器寻址
MOV pc, lr 表明操作数来源于寄存器(pc和lr)。这种寻址办法,在指令的32位机器码中的地址码部分,寄存的是寄存器(pc和lr)的编号,故称之为寄存器寻址。
2、当即数寻址
MOV pc, #64 表明将常数64放入寄存器pc,其间常数64被称为当即数。当即数寻址指令中的地址码部分便是操作数自身,也便是说,数据就包含在指令傍边,取出指令也就取出了能够当即运用的操作数(故称为当即数)。
这儿,或许咱们会看出一个问题:因为当即数是坐落32位机器码中的,而32位机器码中除了操作数外还有操作码,这就意味着不或许用悉数32bit来表明当即数。现实上,ARM机器指令中,仅用了最低的12bit来表明当即数。那么咱们天然推论当即数的规模是-2048——2047,这意味着MOV pc, #8192这样的指令是不合法的。但现实状况并非如此,MOV pc,#8192是合法且能正常运转的。真实状况是,ARM机器指令能够表明的当即数规模是-2^31–2^31-1,只不过它只能表明这其间的2^12个数罢了。ARM是这样用12bit来表明1个当即数的:将12bit划分为2部分——高4位和低8位,将低8位补0扩展为32位,然后循环右移X位(X = 高4位表明的无符号整数*2),例如:假如32位机器码中低12bit为0x512,则其表明的当即数为0x04800000
这儿,请咱们无妨现在先考虑2个问题,咱们将在后续文章中予以回答:
1)、为什么ARM要这样规划,而不是依照咱们最常见的主意(即:12bit就表明-2^11 — 2^11-1中的数)
2)、假如咱们需求mov r0, #10000这样的指令,应该怎么办?(常数10000不能依照如上的办法进行表明)
3、寄存器直接寻址
寄存器直接寻址指令中的地址码给出的是一个通用寄存器的编号,所需的操作数保存在寄存器指定地址的存储单元中,即寄存器为操作数的地址指针。例如:
LDR R0, [R2]表明将R2的值作为内存地址,到该内存处取出寄存的数,放到寄存器R0中
履行LDR R0, [R2]前的状况 履行LDR R0, [R2]后的状况
了解了根本的寻址办法后,咱们现在来看一看最常用的汇编指令
1、单寄存器加载指令。主要有
加载字指令:LDR r0, [r1],将内存中的一个字(4个字节)加载到寄存器r0中
加载字节指令:LDRB r0, [r1],将内存中的一个字节加载到寄存器r0中
有符号数加载字节指令:LDRSB r0, [r1],这条指令与上一条指令的不同之处在于,因为加载的是一个字节,而不是一个字,所以需求确认寄存器r0的高24bit是什么。关于上一条指令,r0的高24bit补0,而本条指令,r0的高24bit补符号位,也便是补r0的bit7
2、单寄存器存储指令。主要有
存储字指令:STR r0, [r1],将r0中的值存储到内存的4个字节中
存储字节指令:STRB r0, [r1],将r0的低8bit存储到内存的1个字节中