逆向筆記(二)-狀態(tài)寄存器

20210330001.png

狀態(tài)寄存器CPSR

在CPU內(nèi)部的寄存器中有一種特殊的寄存器,這種寄存器在ARM中被稱為狀態(tài)寄存器,即CPSR寄存器。CPSR寄存器和其他寄存器不一樣在于,其他寄存器是用來(lái)存儲(chǔ)數(shù)據(jù)的,而CPSR寄存器是按位起作用,它里面的每一位都是有專門的含義,記錄特定的信息。

CPSR寄存器是32位的

CPSR的低8位(包括I、F、T和M[4:0])稱為控制位,程序無(wú)法修改,除非CPU運(yùn)行于特權(quán)模式下,程序才能修改控制位!

8~27位是保留位,方便后期擴(kuò)展

N、Z、C、V均為條件碼標(biāo)志位。它們的內(nèi)容可被算術(shù)或邏輯運(yùn)算的結(jié)果所改變,并且可以決定某條指令是否被執(zhí)行!意義重大!

N標(biāo)志位

CPSR中的第31位是N標(biāo)志位,它記錄相關(guān)指令執(zhí)行后,其結(jié)果是否為負(fù),如果為負(fù)則N標(biāo)志位為1,如果是非負(fù)數(shù)則N標(biāo)志位為0

練習(xí):

- (void)viewDidLoad {
    [super viewDidLoad];
    
    int a = 10;
    int b = 20;
    
    if (a > b) {
        printf("a大于b\n");
    }else{
        printf("error\n");
    }
}

在if判斷前加上斷點(diǎn)符號(hào),然后運(yùn)行程序,當(dāng)程序運(yùn)行到斷點(diǎn)位置后step into進(jìn)入判斷,然后逐步執(zhí)行,當(dāng)執(zhí)行完判斷條件后,打印cpsr的值:

(lldb) register read cpsr
    cpsr = 0x80000000

然后轉(zhuǎn)換cpsr的值為二進(jìn)制后發(fā)現(xiàn),N標(biāo)志位為1,也就是說(shuō)結(jié)果為負(fù),所以判斷走的是else語(yǔ)句的打印。為了驗(yàn)證是否是N標(biāo)志位進(jìn)行影響判斷結(jié)果的,我們按照上述步驟重新運(yùn)行項(xiàng)目,當(dāng)走到判斷的時(shí)候,我們進(jìn)行修改,將cpar的值修改為0x20000000,這時(shí)候N標(biāo)志位的值為0,表示結(jié)果為非負(fù)數(shù),然后我們看下打印結(jié)果:

(lldb) register read cpsr
    cpsr = 0x80000000
(lldb) register write cpsr 0x20000000
(lldb) register read cpsr
    cpsr = 0x20000000
a大于b

從以上結(jié)果可以驗(yàn)證N位影響相關(guān)指令操作后結(jié)果是否為負(fù)

Z標(biāo)志位

CPSR的第30位是Z標(biāo)志位。它記錄相關(guān)指令執(zhí)行后,其結(jié)果是否為0.如果結(jié)果為0.那么Z = 1.如果結(jié)果不為0,那么Z = 0.

練習(xí):

- (void)viewDidLoad {
    [super viewDidLoad];

    int a = 10;
    int b = 20;
    
    if (a == b) {
        printf("a等于b\n");
    }else{
        printf("error\n");
    }
}

將判斷條件修改為a和b是否相等,正常邏輯來(lái)說(shuō)是不相等的,然后我們還是按照之前的步驟操作,當(dāng)運(yùn)行完成邏輯判斷后,在結(jié)果返回前,我們修改cpsr的Z標(biāo)志位,運(yùn)行結(jié)果如下:

(lldb) register read cpsr
    cpsr = 0x80000000
(lldb) register write cpsr 0x40000000
(lldb) register read cpsr
    cpsr = 0x40000000
a等于b

所以我們?cè)俅悟?yàn)證了Z標(biāo)志位的作用

C標(biāo)志位

CPSR的第29位是C,進(jìn)位標(biāo)志位。一般情況下,進(jìn)行無(wú)符號(hào)數(shù)的運(yùn)算。加法運(yùn)算:當(dāng)運(yùn)算結(jié)果產(chǎn)生了進(jìn)位時(shí)(無(wú)符號(hào)數(shù)溢出),C=1,否則C=0。減法運(yùn)算(包括CMP):當(dāng)運(yùn)算時(shí)產(chǎn)生了借位時(shí)(無(wú)符號(hào)數(shù)溢出),C=0,否則C=1。

進(jìn)位:我們知道,當(dāng)兩個(gè)數(shù)據(jù)相加的時(shí)候,有可能產(chǎn)生從最高有效位想更高位的進(jìn)位。比如兩個(gè)32位數(shù)據(jù):0xaaaaaaaa + 0xaaaaaaaa,將產(chǎn)生進(jìn)位。由于這個(gè)進(jìn)位值在32位中無(wú)法保存,我們就只是簡(jiǎn)單的說(shuō)這個(gè)進(jìn)位值丟失了。其實(shí)CPU在運(yùn)算的時(shí)候,并不丟棄這個(gè)進(jìn)位制,而是記錄在一個(gè)特殊的寄存器的某一位上。ARM下就用C位來(lái)記錄這個(gè)進(jìn)位值

錯(cuò)位:當(dāng)兩個(gè)數(shù)據(jù)做減法的時(shí)候,有可能向更高位借位。再比如,兩個(gè)32位數(shù)據(jù):0x00000000 - 0x000000ff,將產(chǎn)生借位,借位后,相當(dāng)于計(jì)算0x100000000 - 0x000000ff。得到0xffffff01 這個(gè)值。由于借了一位,所以C位 用來(lái)標(biāo)記借位。C = 0.

V標(biāo)志位

CPSR的第28位是V,溢出標(biāo)志位。在進(jìn)行有符號(hào)數(shù)運(yùn)算的時(shí)候,如果超過(guò)了機(jī)器所能標(biāo)識(shí)的范圍,稱為溢出。

正數(shù) + 正數(shù) 為負(fù)數(shù) 溢出

負(fù)數(shù) + 負(fù)數(shù) 為正數(shù) 溢出

正數(shù) + 負(fù)數(shù) 不可能溢出

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容