ARM汇编语言(2)

ARM汇编语言

一、引言

ARM汇编语言是一种低级别的计算机指令集架构(ISA)语言,它是ARM处理器上的一种指令集架构,用于编写底层的系统软件,例如操作系统、驱动程序和嵌入式系统应用程序。

ARM汇编语言使用基于寄存器的指令集,其中指令操作的数据通常存储在处理器的寄存器中,而不是内存中。ARM汇编语言使用汇编指令来控制计算机的操作,例如数据传输、算术和逻辑操作、分支和跳转指令等等。

ARM汇编语言的语法通常是简单直观的,并且与其他汇编语言相似,但是具体的语法规则会因不同的ARM处理器型号而有所不同。编写ARM汇编语言代码需要对底层计算机硬件和指令集架构的工作原理有深入的理解。

二、ARM处理器的寻址方式

1.寄存器寻址

将一个寄存器的值传送到另一个寄存器的操作。

MOV R1,R2      ;R2→R1,将寄存器R2的值传送到寄存器R1

指令执行时对寄存器中的值直接取出进行操作。

2.立即寻址

立即寻址方式的目的就是将操作数紧跟在操作码后面,与操作码一起放在指令代码段中,在程序运行时,程序直接调用该操作数,而不需要到其他地址单元中去取相应的操作数,上述的写在指令中的操作数也称作立即数。
MOV R0,#0x1234
MOV为操作码,R0为第一操作数,0x1234为立即数

立即数(immediate)是指在指令中直接指定的数据值,必须对应8位常数通过循环右移偶数位的得到,立即数通常被用于指令中的常量、地址、偏移量。

如何判断快速判断这个立即数合法:

  • (1)首先把这个数用二进制表示出来,顺着看和循环看数中“1”的最大间隔是否都大于8(包含首尾的两个1),如果大于8,那这个数肯定是非法的。如果有一次小于等于8则有可能是合法的。
    例如:
    0x1101的二进制为:0000 0000 0000 0000 0001 0001 0000 0001,无论顺着看和循环看,两个1的最大间隔都大于8,所以不是立即数。

  • (2)方法1:
    如果两个1的最大间隔都大于8,一定不是立即数。
    如果顺序看时1的最大间隔等于8,此时可以看看,这个数最高位1的前面或者最低位1的后面是否有偶数个0,只要一种情况下有,这个数就是合法的。
    如果循环看时1的最大间隔小于等于8,此时可以看看,循环看时,两端得到的间隔个数是否有一个为偶数,如果有一个是偶数,这个数就是合法的。

  • (3)方法2:
    1.把数据转换成二进制形式,从低位到高位写成4位1组的形 式,高位一组不够四位的,在高位前面补0。
    2.数1的个数,如果大于8个肯定不是立即数,如果小于等于8进行下面步骤。
    3.如果数据中间有连续的大于等于24个0,循环左移4的倍数,使高位全为0。
    4.找到高位的1,去掉前面大偶数个0。
    5.找到低位的1,去掉后面大偶数个0。
    6.数剩下的位数,如果小于等于8位,那么这个数就是立即数,反之就不是立即数。

总结:判断立即数时,先把它化成二进制,然后取八位数,看左右移动偶数位是否能还原。
例如:
1、判断 0X20000018 是不是立即数:
把数据转换成二进制 0010 0000 0000 0000 0000 0000 0001 1000 循环右移32-3=29次得到原来的数,所以不是立即数。
2、判断0x104是不是立即数:
把数据转化为二进制0000 0000 0000 0000 0000 0001 0000 0100如果取01000001循环32-2=30次得到原数,如果取10000010,循环32-1=31次得到原数。

在ARM汇编语言中,立即数可以使用前缀“#”来表示,表示16进制数值时用“0x”表示,注意“#”后面一定是一个合法的立即数。例如,下面的指令中:

ADD R0, R0, #10   ;R0+10→R0 ,将立即数10加到寄存器R0中
MOV R0,#0x1234   ;0x1234→R0

3.寄存器移位寻址

3.1 LSL:逻辑左移(logical shift left)

MOV R0,#0xff0000f0    ;#0xff0000f0 →R0
MOV R0,R0,LSL #4     ;R0+R*2^4→R0

例:0xff0000f0逻辑左移4位后为0xf0000f00,进位输出为0xf。
寄存器中字的低端空出的位补0。

3.2 LSR:逻辑右移(logical shift right)

MOV R0,R0,LSR #4     ;R0+R/2^4→R0

例:0xff0000f0逻辑右移4位后为0x0ff0000f,进位输出为0x0。
寄存器中字的高端空出的位补0。

3.3 ASR:算数右移(arithmetic shift right)

MOV R0,R0,ASR #4     ;R0+R/2^4→R0

例:0xff0000f0算数右移4位后为0xfff0000f,进位输出为0x0。
移位过程中保持符号位(最高位)不变,即源操作数为正数,字的高端空位补0,否则补1。

3.4 ROR:循环右移(rotate right)

MOV R0,R0,ROR #4     ;R0+R/2^4→R0

例:0xff0000f0循环右移4位后为0x0ff0000f,进位输出为0x0。
由字低端移出的位填到高端空出的位。

4.寄存器间接寻址

寄存器为操作数的地址指针,操作数存放在存储器中。

LDR   R0,[R1]   ;[R1]→R0    取
STR   R0,[R1]    ;R0→[R1]    存

第一条指令将R1的值为地址的存储器的数据传送到R0中,第二条指令是将R0的值传送到以R1为地址的存储器中。
LDR也可以作为伪指令,例如:

LDR r0, =0xFFF0 @伪指令
LDR r0, 0xFFFF @指令

即可以直接传入一个任意的数,不必在意立即数,因为在编译时被解析,作为加载指令。

5.基址加偏址寻址

将寄存器的内容与指令中给出的地址偏移量相加,从而得到一个操作数的有效地址,通常用来访问基址附近的地址的单元。
(1)前变址模式
LDR R0,[R1,#4] ;[R1+4]→R0
(2)自动变址模式
LDR R0,[R1,#4]! ;[R1+4]→R0,R1+4→R1,"!"为更新地址
(3)后变址模式
LDR R0,[R1],#4 ;[R1]→R0,R1+4→R1

猜你喜欢

转载自blog.csdn.net/weixin_57038791/article/details/130454384