赞
踩
最近的文章可能会有较多修改,请关注博客哦
ARMv8处理器支持4种异常等级(Exception Level,EL)。
EL0 为非特权模式,用于运行应用程序,其他资源访问受限,权限不够。
EL1 为特权模式,用于操作系统内核,可以访问系统的所有资源
EL2 用于运行虚拟化管理管理程序(hypervisor)。
EL3 用于运行安全世界中的管理程序,安全模式(secure monitor)。
这里的异常概念不同于程序中的异常概念。当作中断理解会好点。
ARMv8 架构定义了两种执行状态, AArch64和AArch32。当处于 AArch64 状态时,处理器执行 A64 指令集。当处于 AArch32 状态时,处理器可以执行 A32(在早期版本的架构中称为 ARM)或 T32 (Thumb) 指令集。所以,ARMv8的设备可以运行老程序,它是向前兼容的。
注意,AArch64 OS 运行 AArch32 程序时,当应用程序调用(SVC)指令,或接收中断,会切换到 EL1 和 AArch64。
AArch64执行状态提供了32个在任何时间任何特权级下都可访问的64位的通用寄存器。
每个寄存器都有64位宽,它们通常被称为寄存器X0-X30。
每个AArch64 64位通用寄存器(X0-X30)也具有32位(W0-W30)形式。
也就是说,64位模式下寄存器名字叫 Xn,32位模式下名字叫 Wn。这些东西与 CSAPP 里面讲的都是差不多的,只不过它讲的是 X86 架构。
每个寄存器的用途如下:
在aarch64中,没有x31或w31寄存器,但是在一些指令或软件编码中,经常将数字31作为XZR或SP
X0-X7:用于参数传递
X9-X15:调用方需要保存这些寄存器的值,因为被调用函数可能会修改这些寄存器。
X19-X29:被调用方保存这些寄存器的值,退出时再恢复,因为函数返回后可能调用方还会用到这些寄存器的值。
X8, X16-X18, X29, X30:这些都是特殊用途的寄存器
X8: 用于储存间接结果的寄存器,比如返回一个结构体的时候,该寄存器储存的是结构体地址。
X18:不管
sp:保存栈顶地址
fp:保存栈底地址
lr:保存调用跳转指令 bl
指令的下一条指令的内存地址
zr:xzr/wzr
分别代表 64/32 位,可用于清零的操作,零寄存器
pc: 保存将要执行的指令的地址
程序状态寄存器,程序中会存在很多分支,具体走哪条分支,是由状态寄存器决定的,比如一些比较指令执行时,需要根据状态寄存器的负数标志来决定是否进行逻辑分支跳转。
在aarch64中,只能可以通过MSR/MRS指令访问特殊寄存器(special-purpose)的方式读写这些位。除了这些特殊寄存器中表示的位,PSTATE的其它位都是不能访问的。
ARM指令的基本格式如下:
<opcode> {<cond>} {S} <Rd>, <Rn>{,<operand2>}
其中<>号内的项是必须的,{}号内的项是可选的。各项的说明如下:
opcode:指令助记符
cond:执行条件
S:是否影响CPSR寄存器的值
Rd:目标寄存器
Rn:第一个操作数的寄存器
operand2:第2个操作数
ARM指令格式举例:
LDR R0, [R1]:读取R1地址上的存储单元内容,执行条件AL;
BEQ DATAEVEN:条件执行分支指令,执行条件EQ,即相等则跳转到DATAEVEN;
ADDS R2, R1, #1:加法指令,R2<-R1+1,影响CPSR寄存器;
SUBNES R2, R1,#0x20:条件执行的减法运算,执行条件NE,R1-0x20->R2,影响CPSR寄存器
AArch64没有直接与ARMv7中的CPSR等价的寄存器,但是可以访问PSTATE中对应的字段。
我觉的 csapp 在这方面讲的是真的好,一个表格就让初学者对汇编了解很多。看一个例子:
这个表格就说清楚了各种寻址方式对应的汇编格式。
我们看看 arm64 的寻址方式。
立即寻址也叫立即数寻址,这是一种特殊的寻址方式,操作数本身就在指令中给出,只要取出指令也就取到了操作数,这个操作数被称为立即数,对应的方式也称为立即寻址
ADD W0, W1, *#0x05*
寄存器寻址也就是利用寄存器中的数值作为操作数,这是一种常见的方式,也是效率比较高的寻址方式
ADD W0, W1, W2
寄存器间接寻址就是以寄存器中值作为操作数的地址,而操作数本身存放在存储器中
- ADD W0, W1, [W2]
- LDR W3, [W0]
基址变址寻址就是将寄存器(该寄存器一般称作基址寄存器)的内容与指令中给出的地址偏移量相加,从而得到一个操作数的有效地址。变址寻址方式常用于访问某基地址附近的地址单元, 常见的有以下几种形式:
- LDR W0, [W1, #4] ;将寄存器w1中内容加上4作为地址,然后将该地址处的数据存入寄存器w0中
- LDR W0, [W1, #4]! ;将寄存器w1中内容加上4作为地址,然后将该地址处的数据存入寄存器w0中,然后w1中的内容自增4
- LDR W0, [W1], #4 ;将寄存器w1中的内容作为地址,然后将该地址处的数据存入w0中,并将w1中内容自增4
- LDR W0, [W1, W2] ;将w1和w2中的内容相加作为地址,然后将该地址处的数据存入w0
上面有个例子:
LDR W0, [W1, #4]!
汇编后面有个感叹号。ARM中的指令可以带后缀,从而丰富该指令的功能,常用的后缀有:
- B(byte):功能不变,操作长度变为8位(依赖CPU位数,以下相同)
- H(Halfword):功能不变,操作长度变为16位
例如:ldr指令族:ldrb,ldrh,ldrsb ldrsh,从内存中加载指定长度的数据
影响CPSR里的NZCV标识位。指令中使用”S“后缀时、指令执行后程序状态寄存器的条件标志位将被刷新。相当于有符号运算。
例如:
- SUB X1,X0,X3 ;X1=X0-X3 ,CPSR值不变
- SUBS X1,X0,X3 ;X1=X0-X3 , 如果计算结果为负数,CPSR寄存器的N被置位
指令中地址表达式含有“!”后缀时,指令执行后,基址寄存器中的地址值将会发生变化。变化的结果是 (base+offset)。
例如:
- LDR X3,[X0,#4] //X3=X0+4
- LDR X3,[X0,#4]! //X3=X0+4; X0+=4;
注意:“!”不能用于寄存器PC后面
ARM架构中,允许在指令后面添加条件后缀来完成指令条件执行的目的。指令条件执行就是说,指令根据CPSR中条件码的状态和指令的条件域有条件的执行。当指令的执行条件满足时,指令被执行,否则指令将被忽略。
例如:
- ADD X4,X2,#1 ; 无条件执行 X4=X2+1
- ADDEQ X4,X2,#1 ;添加有条件执行后缀EQ,当CPSR中的Z标志置位(之前某条CMP结果相等)时,该指令才执行。
-
- 注意:如果条件后缀和“S”标识同时出现,则S在条件后缀的后面,例如:
- ADDEQS X4,X2,#1 ;即为有条件执行X4=X2+1,结果更新条件标志位
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。