ARM汇编有三种数据类型,每种数据类型又可分为有符号(signed)和无符号(unsigned)。汇编语言的变量本身不带类型,数据类型是通过指令的后缀体现出来的。
这三种数据类型分别是:
- 字节(Byte),8个比特
- 字(Word),在ARM汇编中一个字是4个字节(和x86字的定义不一样,x86的字是2个字节)
- 半字(Half Word),2个字节
简单的通过两个指令的变形来举例说明数据类型在汇编指令中如何体现:
ARM指令集中,从内存中加载数据到寄存器的指令是ldr
(Load Register),从寄存器存储到内存的指令是str
(Store Register),这两个指令传送的都是字。而在后面分别加上h
(Half),sh
(Signed Half),b
(Byte)和sb
(Signed Byte),就分别传送了无符号半字、有符号半字、无符号字节和有符号字节。
列表如下:
指令助记符 | 解释说明 |
---|---|
ldr* | 从内存向寄存器传送数据,由于寄存器定长为一个字,因此凡是小于一个字的数据类型传入寄存器都需要进行拓展操作 |
ldr | 由内存向寄存器传送字 |
ldrh | 对半字做零扩展后由内存传送到寄存器 |
ldrsh | 对半字做符号扩展后由内存传送到寄存器 |
ldrb | 对字节做零扩展后由内存传送到寄存器 |
ldrsb | 对字节做符号扩展后由内存传送到寄存器 |
str* | 由寄存器向内存传送数据,优先传送寄存器的低位,因为内存是可以按字节访问的,所以无需区分是否带符号 |
str | 由寄存器向内存传送字 |
strh | 由寄存器取低16位内容向内存传送半字 |
strb | 由寄存器取低8位内容向内存传送字节 |
内存是按照字节编址的,而一个寄存器是四个字节。因此数据在寄存器和内存的流动过程中就会产生一个存储顺序的问题。也即寄存器从低到高位数,第0/1/2/3字节应该在内存中如何排布?是由低地址向高地址排列还是高地址向低地址排列呢?这就是端序问题。
小端序(Little Endian):即对于每个字,字的低字节存储在低位地址,高字节存储在高地址。
大端序(Big Endian):即对于每个字,字的低字节存储在高位地址,高字节存储在低地址。
举例:假设数据字0x12345678存储在地址0x00,那么请画出内存布局及内存中所填充的内容(以16进制表示)。
内存地址 | 小端序 | 大端序 |
---|---|---|
0x03 | 12 | 78 |
0x02 | 34 | 56 |
0x01 | 56 | 34 |
0x00 | 78 | 12 |
x86架构是小端序。ARM架构既可以是小端序,也可以是大端序。