状态寄存器
CPSR(current program status register)寄存器
按位起作用,每一位都有专门的含义,记录特定的信息。
注:CPSR 寄存器是32位的
- CPSR 的低8位(包括I、F、T和M[4:0])称为控制位,程序无法修改,除非 CPU 运行于特权模式下,程序才能修改控制位!
- N、Z、C、V 均为条件码标志位。它们的内容可被算术或逻辑运算的结果所改变,并且可以决定某条指令是否被执行,意义重大。
N(Negative)标志
CPSR 的第31位是 N,符号标志位。它记录相关指令执行后,其结果是否为负。 如果为负,则 N = 1,反之 N = 0.
注意:在 ARM64 的指令集中,有的指令的执行时影响状态寄存器的,比如 add、sub、or 等,他们大都是运算指令(进行逻辑或算数运算)。
分析如下函数:
void func() {
asm(
"mov w0,#0x7fffffff\n"
"adds w0,w0,#0x2\n"
);
}
计算结果第31位为1
验证结果为负,N = 1
Z(Zero)标志
CPSR 的第30位是 Z,0标志位。它记录相关指令执行后,其结果是否为0。 如果结果为0,则 Z = 1,反之 Z = 0.
分析如下函数:
void func(){
asm(
"mov w0, #0x0\n"
"adds w0, w0, #0x0\n"
);
}
验证结果为0,Z = 1。
分析如下函数:
void func(){
asm(
"mov w0, #0x0\n"
"adds w0, w0, #0x1\n"
);
}
验证结果不为0,Z = 0。
C(Carry)标志
CPSR 的第29位是 C,进位标志位。一般情况下进行无符号数的运算。
- 加法运算:当运算结果产生了进位时(无符号数溢出),C = 1,否则 C = 0。
- 减法运算(包括CMP):当运算时产生了借位时(无符号数溢出),C = 0,否则 C = 1。
对于位数为N的无符号数来说,其对应的二进制信息的最高位,即第N - 1位,就是它的最高有效位,而假想存在的第N位,就是相对于最高有效位的更高位。如下图所示:
加法进位:
void func() {
asm(
"mov w0, #0xaaaaaaaa\n"
"adds w0, w0, w0\n"
);
}
减法借位:
void func() {
asm(
"mov w0,#0x0\n"
"subs w0,w0,#0xff\n"
);
}
V(overflow)溢出标志
CPSR 的第28位是 V,溢出标志位。在进行有符号数运算的时候,如果超过了机器所能标识的范围,称为溢出。 溢出则,V = 1,反之 V = 0。
- 正数 + 正数 为负数 溢出
- 负数 + 负数 为正数 溢出
- 正数 + 负数 不可能溢出
分析如下代码:
void func() {
asm(
"mov w0,#0x7FFFFFFF\n" // 第31位为0的最大正数
"adds w0,w0,#0x1\n"
);
}
验证结果为溢出,V = 1。
分析如下函数:
void func() {
asm(
"mov w0, #0xaaaaaaaa\n" // 第31位为1的负数
"adds w0, w0, w0\n"
);
}
验证结果为溢出,V = 1。