-
-
[翻译]ARM汇编基础教程——数据类型和寄存器
-
发表于:
2017-8-20 22:25
11572
-
ARM汇编基础教程
——数据类型和寄存器
原文链接:https://azeria-labs.com/arm-data-types-and-registers-part-2/
翻译:ljcnaix
和高级语言一样,ARM汇编语言支持对不同数据类型的操作。我们可以load(或store)的数据类型包括signed/unsigned words,halfwords或者bytes。我们用“-h”或“-sh”后缀表示half words,用“-b”或“-sb”表示bytes,无后缀默认表示words。有符号和无符号数据类型之间的区别有:
§ 有符号数可以表示正直和负值,所以范围较小;
§ 无符号数只能表示正值,所以范围更大。
下面是使用load和store指令操作不同类型数据的示例:
字节序
在内存中有两种存储多字节数据的方式,大端序和小端序。这两种方式的差异是数据存储时的字节顺序不同。在以小端序存储数据的设备中(如x86),位权低(个位的位权比十位低)的字节存储在低地址(地址值小的地址)。在以大端序存储数据的设备上,位权高的字节存储在低地址。上一篇我们提到过,ARM架构在ARMv3之前是小端序的,在那之后,ARM处理器可以通过硬件配置在大小端之间切换。以ARMv6为例,指令是固定的以小端序存储的,而内存数据的读取方式可以通过控制程序状态寄存器CPSR的第9位实现在大端和小端之间切换。
ARM处理器的寄存器个数与ARM指令集版本有关。根据ARM手册,除了基于ARMv6-M和ARMv7-M的处理器,其它的ARM处理器都有30个32 bit的通用寄存器。前17个(原文是16个,我觉的可能是作者犯的off-by-one错误,如果理解有误,请高手指正)寄存器是在用户模式下可访问的,其它的寄存器只有在特定的运行模式下才可以访问(ARMv6-M和ARMv7-M除外,它们的架构有一些差异,有兴趣的话可以单独去学习)。在这篇教程中,我们将关注那些可以在任何运行模式下被访问的寄存器:r0~r15还有CPSR。这16个寄存器可以被分为两组:通用寄存器和专用寄存器。
寄存器
别名
作用
R0
-
通用
R1
-
通用
R2
-
通用
R3
-
通用
R4
-
通用
R5
-
通用
R6
-
通用
R7
-
常用于保存系统调用号
R8
-
通用
R9
-
通用
R10
-
通用
R11
FP
用于保存栈帧
专用寄存器
R12
IP
内部调用暂存寄存器
R13
SP
栈顶指针
R14
LR
用于保存函数返回地址
R15
PC
用于保存下一条指令的地址
CPSR
-
当前程序状态寄存器
下面这张表将ARM的寄存器和x86寄存器做了一个简单类比:
ARM
简述
X86
R0
通用寄存器
EAX
R1~R5
通用寄存器
EBX,ECX,EDX,ESI,EDI
R6~R10
通用寄存器
-
R11(FP)
栈帧寄存器
EBP
R12
内部调用暂存寄存器
-
R13(SP)
堆栈寄存器
ESP
R14(LR)
链接寄存器
-
R15(PC)
程序计数器
EIP
CPSR
当前程序状态寄存器
EFLAGS
R0~R12(R12的使用要慎重):R0~R12是通用寄存器(R12已经不完全是了),它们可以在常规操作中使用,来存储临时变量或地址。习惯上,R0常在算数运算中作为累加器,或者存储函数的返回地址。R7常用于存储系统调用号。R11常作为栈帧指针来标记函数栈帧的边界。此外,ARM的函数调用约定规定,函数的前四个参数存储在寄存器r0~r3中。
R13:R13是堆栈指针(SP,Stack Point)。它指向堆栈的顶部。堆栈是用来存储函数局部存储的一段内存,在函数返回时回收。堆栈指针通过减去我们要分配的空间大小,来分配堆栈上的空间。比如,我们要分配一个32 bit的空间,那么就令R13减4。
R14:R14是链接寄存器(LR,Link Register)。当进行函数调用时,链接寄存器被更新为调用函数指令的下一条指令的地址。这样做可以使程序在执行完子函数之后得以返回父函数。
R15:R15是程序计数器(PC,Program Counter)。在执行指令时,PC总是自动的增加,增加的大小等于正在执行指令的长度。这个长度在ARM架构下是固定的,ARM模式是4字节,Thumb模式是2字节。当执行分支指令时,PC被更新为目的地址。需要注意的是,由于RISC CPU流水线优化的原因,在执行期间,ARM模式下PC等于当前指令地址加8,Thumb模式下等于当前指令地址加4,也就是后移两条指令。这不同于x86的EIP寄存器,总是指向当前指令的下一条指令。
下面我们通过调试器来看看PC的行为。我们使用下面的程序,先将PC保存在寄存器r0中,然后随意执行两条指令。让我们看看会发生什么:
.section .text
.global _start
.global _main
_start:
b _main
[注意]APP应用上架合规检测服务,协助应用顺利上架!