美文网首页
03 - 状态寄存器

03 - 状态寄存器

作者: 卡布奇诺_95d2 | 来源:发表于2021-03-29 13:50 被阅读0次

状态寄存器 CPSR

CPU内部的寄存器中,有一种特殊的寄存器(对于不同的处理器,个数和结构都可能不同).这种寄存器在ARM中,被称为状态寄存器就是CPSR(current program status register)寄存器
CPSR和其他寄存器不一样,其他寄存器是用来存放数据的,都是整个寄存器具有一个含义.而CPSR寄存器是按位起作用的,也就是说,它的每一位都有专门的含义,记录特定的信息.

注意:状态寄存器是32位的

状态寄存器各bit的意义如下:


image.png
  • 31:N(Negative)标志
  • 30:Z(Zero)标志
  • 29:C(Carry)标志
  • 28:V(Overflow)标志
  • 8-27:保留位
  • 0-7:低8位(包括I、F、T和M[4:0])称为控制位程序无法修改,除非CPU运行于特权模式下,程序才能修改控制位!

注意:N、Z、C、V均为条件码标志位。它们的内容可被算术或逻辑运算的结果所改变,并且可以决定某条指令是否被执行!意义重大!

N(Negative) 标志

它记录相关指令执行后,其结果是否为负。
* 结果为负数,则N = 1
* 结果为非负数,则N = 0

例如:当计算1-4 = -3时,N标志位则为1
在代码运行过程中查看一下寄存器的情况。

//假设有如下一段汇编
test_1`funA:
->  0x104b1e1cc <+0>:  mov    w0, #0x7fffffff
    0x104b1e1d0 <+4>:  adds   w0, w0, #0x1              ; =0x1 
    0x104b1e1d4 <+8>:  subs   w0, w0, #0x1              ; =0x1 
    0x104b1e1d8 <+12>: ret   

//【1】w0被赋值为0x7FFFFFFF,此时的cpsr的值为:
(lldb) register read cpsr
    cpsr = 0x60000000   <==>    0b01100000000000000000000000000000
//【2】将w0 = w0+0x01 = 0x80000000后,得到的cpsr的值为:
(lldb) register read cpsr
    cpsr = 0x90000000  <==>  0b10010000000000000000000000000000
//【3】将w0 = w0-0x01 = 0x7FFFFFFF,此时的cpsr的值为:
(lldb) register read cpsr
    cpsr = 0x30000000  <==>  0b00110000000000000000000000000000

注:adds:做加法的同时,修改状态寄存器(CPSR)subs:做减法的同时,修改状态寄存器(CPSR)

总结:

  • W0是四字节大小,其最高位为符号位。符号位为1:表示负数;符号位为0:表示正数
  • 当0x7FFFFFFF+0x01=0x80000000,这表示结果为负数,此时CPSR寄存器的N标志位变成1
  • 当0x80000000-0x01=0x7FFFFFFF,这表示结果为正数,此时CPSR寄存器的N标志位变成0

Z(Zero) 标志

它记录相关指令执行后,其结果是否为0.

  • 结果为0,则Z = 1
  • 结果为非0,那么Z = 0
    例如:当计算1-1=0时,Z标志位就为1
//假设有如下一段汇编
test_1`funA:
->  0x102ef21cc <+0>:  mov    w0, #0x0
    0x102ef21d0 <+4>:  adds   w0, w0, #0x1              ; =0x1 
    0x102ef21d4 <+8>:  subs   w0, w0, #0x1              ; =0x1 
    0x102ef21d8 <+12>: ret   

//【1】w0被赋值为0x0,此时的cpsr的值为:
(lldb) register read cpsr
    cpsr = 0x60000000   <==>    0b01100000000000000000000000000000
//【2】将w0 = w0+0x01 = 0x01后,得到的cpsr的值为:
(lldb) register read cpsr
    cpsr = 0x00000000  <==>  0b00000000000000000000000000000000
//【3】将w0 = w0-0x01 = 0x0,此时的cpsr的值为:
(lldb) register read cpsr
    cpsr = 0x60000000  <==>  0b01100000000000000000000000000000

总结:

  • 当0x0+0x01 = 0x01,此时结果为非0,CPSR寄存器的Z标志位0
  • 当0x1-0x01 = 0x00,此时结果为0,CPSR寄存器的Z标志位1

C(Carry)标志

CPSR的第29位是C进位标志位。一般情况下,进行无符号数的运算
加法运算:当运算结果产生了进位(无符号数溢出)时,C=1否则C=0
减法运算:当运算时产生了借位(无符号数溢出)时,C=0否则C=1

//假如有如下一段汇编
test_1`funA:
->  0x10081e1bc <+0>:  mov    w0, #-0xFFFFFFFE
    0x10081e1c0 <+4>:  mov    w1, #0x1
    0x10081e1c4 <+8>:  adds   w0, w0, w1
    0x10081e1c8 <+12>: adds   w0, w0, w1
    0x10081e1cc <+16>: mov    w0, #0x1
    0x10081e1d0 <+20>: subs   w0, w0, w1
    0x10081e1d4 <+24>: subs   w0, w0, w1
    0x10081e1d8 <+28>: ret  
//当对w0和w1进行赋值时,CPSR寄存器的值为:
(lldb) register read cpsr
    cpsr = 0x60000000   <==>    0b01100000000000000000000000000000
//【1】当0xFFFFFFFE+0x01=0xFFFFFFFF时,此时未产生进位。当前CPSR寄存器的值为:
(lldb) register read cpsr
    cpsr = 0x80000000   <==>    0b10000000000000000000000000000000
//【2】当0xFFFFFFFF+0x01时,此时产生进位导致w0发生溢出。当前CPSR寄存器的值为:
(lldb) register read cpsr
    cpsr = 0x60000000   <==>    0b01100000000000000000000000000000
//【3】当0x01-0x01时,此时不需要进行借位,当前CPSR寄存器的值为:
(lldb) register read cpsr
    cpsr = 0x60000000   <==>    0b01100000000000000000000000000000
//【4】当0x0-0x01时,此时需要借位,当前CPSR寄存器的值为:
(lldb) register read cpsr
    cpsr = 0x80000000   <==>    0b10000000000000000000000000000000

总结:

  • 加法运算
    • 有进位,C=1
    • 没有进位,C=0
  • 减法运算
    • 有借位,C=0
    • 没有借位,C=1

V(Overflow)溢出标志

CPSR的第28位是V溢出标志位。在进行有符号数运算的时候,如果超过了机器所能标识的范围,称为溢出

//假如有如下一段汇编
test_1`funA:
->  0x1007ee234 <+0>:  mov    w0, #0x7fffffff
    0x1007ee238 <+4>:  adds   w0, w0, w0
    0x1007ee23c <+8>:  mov    w0, #0x7fffffff
    0x1007ee240 <+12>: mov    w1, #-0x80000000
    0x1007ee244 <+16>: adds   w0, w1, w0
    0x1007ee248 <+20>: mov    w0, #-0x80000000
    0x1007ee24c <+24>: adds   w0, w0, w0
    0x1007ee250 <+28>: ret
//当对w0进行赋值时,CPSR寄存器的值为:
(lldb) register read cpsr
    cpsr = 0x60000000   <==>    0b01100000000000000000000000000000
//【1】当0x7FFFFFFF+0x7FFFFFFF=0xFFFFFFFE时,此时正数+正数,且超过正数最大标识,发生溢出。当前CPSR寄存器的值为:
(lldb) register read cpsr
    cpsr = 0x90000000   <==>    0b10010000000000000000000000000000
//【2】当0x7FFFFFFE+0x80000000时,此时正数+负数,未发生溢出。当前CPSR寄存器的值为:
(lldb) register read cpsr
    cpsr = 0x80000000   <==>    0b10000000000000000000000000000000
//【3】当0x80000000+0x80000000时,此时负数+负数,且超过负数的最大标识,发生溢出,当前CPSR寄存器的值为:
(lldb) register read cpsr
    cpsr = 0x70000000   <==>    0b01110000000000000000000000000000

总结:

  • 正数 + 正数结果为负数时,发生溢出V标志为1
  • 负数 + 负数结果为正数时,发生溢出V标志为1
  • 正数 + 负数不可能发生溢出,V标志为0

相关文章

  • 状态寄存器-03

    003-状态寄存器    CPU内部的寄存器中,有一种特殊的寄存器(对于不同的处理器,个数和结构都可能不同).这种...

  • 03 - 状态寄存器

    状态寄存器 CPSR CPU内部的寄存器中,有一种特殊的寄存器(对于不同的处理器,个数和结构都可能不同).这种寄存...

  • 03-汇编基础(3)

    前言 本篇文章主要讲解? 状态寄存器 判断、选择和循环 一、状态寄存器(CPSR) 什么是状态寄存器?? CPU内...

  • 逆向笔记(二)-状态寄存器

    状态寄存器CPSR 在CPU内部的寄存器中有一种特殊的寄存器,这种寄存器在ARM中被称为状态寄存器,即CPSR寄存...

  • 操作系统概论(2)

    控制和状态寄存器: PC(程序计数器),IR(指令寄存器),PSW(程序状态字寄存器) 操作系统需要两种CPU状态...

  • iOS逆向-03:状态寄存器

    003-状态寄存器 CPU内部的寄存器中,有一种特殊的寄存器(对于不同的处理器,个数和结构都可能不同).这种寄存器...

  • OneHot算法及在TensorFlow中的使用

    What One Hot,即用N位状态寄存器编码N个状态,每个状态都有独立的寄存器位,且这些寄存器位中只有一位有效...

  • stm32 TIM(通用定时器)

    寄存器描述CR1控制寄存器1CR2控制寄存器2SMCR从模式控制寄存器DIERDMA/中断使能寄存器SR状态寄存器...

  • ARM汇编

    一. ARM 寄存器 ARM共有37个32位寄存器,其中31个为通用寄存器,6个为状态寄存器.这些寄存器不能被同时...

  • 寄存器

     一、标志寄存器PSW 标志寄存器PSW(程序状态字寄存器PSW)标志寄存器PSW是一个16为的寄存器。它反...

网友评论

      本文标题:03 - 状态寄存器

      本文链接:https://www.haomeiwen.com/subject/wtcshltx.html