本文共 1471 字,大约阅读时间需要 4 分钟。
ARM伪指令的学习,分为ARM机器码、定义类伪指令、操作类伪指令三部分。
参考ARM Architecture Reference Manual中The ARM Instruction Set
汇编程序经过汇编器,可以得到机器码,从而在处理器中运行。 ARM机器码是一个32位整数,这个整数被分为多个段,每个段都有其各自含义。 例子: 数据处理机器码:cond:条件,可通过查表找出含义
I:标注位,如果shifter_operand是一个立即数,则I为1;如果shifter_operand是一个寄存器,则I为0. opcode:用于区分指令,可查表观看含义。如1101表示mov指令。 S:用于指明操作是否影响CPSR状态寄存器,如果影响,则为0;如果不影响则为1. Rn:第一源操作寄存器 Rd:目的寄存器 shifter_operand:第二源操作数 如mov r0,r1的机器码为: 1110 00 0 1101 0 0000 0000 000000000001 moveq r0,#0xff的机器码为:0000 00 1 1101 0 0000 0000 000011111111 在mov指令中,shifter_operand占据12位,这表明能使用的源操作数的大小是有限的,若超过限制则会出错。此时可利用伪指令来处理这个问题。 伪指令:伪指令本身并没有所对应的机器码,它只是在编译的时候起作用,或者转化为其它实际指令来运行。其中在编译时起作用的是定义类伪指令,转化为其它实际指令的是操作类伪指令。 GNU ARM汇编中的伪指令都要在指令前加“.”,如 .globalglobal:标明全局标量
data:定义数据段
ascii:定义一个或多个ASCII字符串数据,如:
hello: .ascii “hello world”byte:定义一字节,如:
bh: .byte 0x1word:定义字,如:
add: .word 0xffequ:类似于C语言中的宏定义
用法举例 .equ DA 0x89align:用来控制对齐
.align 4 bh: .byte 0x1 则能保证bh的地址是4的整数倍由于ARM是32bit处理器,所以它的字是32bit的。
字(Word):在ARM体系结构中,字的长度为32位,而在8位/16位处理器体系结构中,字的长度一般为16位。 半字(Half-Word):在ARM体系结构中,半字的长度为16位,与8位/16位处理器体系结构中字的长度一致。 字节(Byte):在ARM体系结构和8位/16位处理器体系结构中,字节的长度均为8位。操作类伪指令ldr与存储器访问指令ldr重名,该伪指令用于解决mov指令不能将大于8bit的数据赋值给寄存器的问题。
mov r0,#0x1ff 编译无法通过,因为mov能够使用的立即数不能超过8bit shifter_operand共12位,但其中有4位是用于存储立即数左移或右移的信息,因此只剩下8位来存储立即数 ldr r0,=0x1ff 编译通过,将0x1ff赋值给r0寄存器。ldr伪指令会转化为存储器访问指令来实现功能,如对于该例子,首先会在内存生成一个word 0x1ff,在利用转化后的存储器访问指令ldr将这个值取出并赋给寄存器r0nop:空操作,一个重要的应用是用于延时,实际上执行的操作是mov r0,r0
伪指令的学习可通过反汇编来查看伪指令是怎么运行的