汇编(三)状态寄存器

435 阅读2分钟

状态寄存器
CPSR(current program status register)寄存器 按位起作用,每一位都有专门的含义,记录特定的信息。

注:CPSR 寄存器是32位的

  • CPSR 的低8位(包括I、F、T和M[4:0])称为控制位,程序无法修改,除非 CPU 运行于特权模式下,程序才能修改控制位!
  • N、Z、C、V 均为条件码标志位。它们的内容可被算术或逻辑运算的结果所改变,并且可以决定某条指令是否被执行,意义重大。 image.png

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 image.png

验证结果为负,N = 1 image.png

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。 image.png

分析如下函数:

void func(){
    asm(
        "mov w0, #0x0\n"
        "adds w0, w0, #0x1\n"
    );
}

验证结果不为0,Z = 0。 image.png

C(Carry)标志

CPSR 的第29位是 C,进位标志位。一般情况下进行无符号数的运算。

  • 加法运算:当运算结果产生了进位时(无符号数溢出),C = 1,否则 C = 0。
  • 减法运算(包括CMP):当运算时产生了借位时(无符号数溢出),C = 0,否则 C = 1。

对于位数为N的无符号数来说,其对应的二进制信息的最高位,即第N - 1位,就是它的最高有效位,而假想存在的第N位,就是相对于最高有效位的更高位。如下图所示: image.png

加法进位:

void func() {
    asm(
            "mov w0, #0xaaaaaaaa\n"
            "adds w0, w0, w0\n"
        );
}

image.png

减法借位:

void func() {
    asm(
        "mov w0,#0x0\n"
        "subs w0,w0,#0xff\n"
        );
}

image.png

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。 image.png

分析如下函数:

void func() {
    asm(
            "mov w0, #0xaaaaaaaa\n" // 第31位为1的负数
            "adds w0, w0, w0\n"
        );
}

验证结果为溢出,V = 1。 image.png