匯編四 — 內(nèi)存分區(qū)

內(nèi)存分區(qū)

  • 堆區(qū) (Heap)

特點:動態(tài)申請 可讀可寫

  • 棧區(qū) (Stack)

特點:由系統(tǒng)進(jìn)行內(nèi)存的管理。主要存放函數(shù)的參數(shù)以及局部變量。
在函數(shù)完成執(zhí)行,系統(tǒng)自行釋放棧區(qū)內(nèi)存,不需要用戶管理。

  • 代碼區(qū)

存放程序的二進(jìn)制代碼。比如我們寫的函數(shù),都是在代碼區(qū)的。特點: 可讀可寫可執(zhí)行,存放程序編譯后的二進(jìn)制代碼,不可尋址區(qū)。

  • 全局/靜態(tài)存儲區(qū)

特點:可讀可寫
靜態(tài)存儲區(qū)內(nèi)的變量在程序編譯階段已經(jīng)分配好內(nèi)存空間并初始化。這塊內(nèi)存在程序的整個運行期間都存在,它主要存放靜態(tài)變量、全局變量和常量。
包括:常量區(qū)(靜態(tài)常量區(qū)),全局區(qū)(全局變量區(qū))和靜態(tài)變量區(qū)(靜態(tài)區(qū))。

  • 常量區(qū)

特點: 只讀!
字符串常量區(qū)和常變量區(qū)。

計算機(jī)尋找原理

如以下的函數(shù):

int f = 10;

int func (int a, int b){
    printf("hahha");
    
    int c = a + f;
    
    return c;
}

int main(int argc, char * argv[]) {
    
    printf("%d",func(1, 2));
    
    return 0;
}

尋找常量和全局變量:

image.png

注意上面的 adrp 指令 (adrp:address page 常量)

adrp x0, 1
1. 將1的值,左移12位 1 0000 0000 0000 == 0x1000
2.將PC寄存器的低12位清零 pc = 0x0000000100fe2874; 0x100fe2874 ==> 0x100fe2000
3.將將1 和 2 的結(jié)果相加 給 X0 寄存器!!

adrp 是計算指定的數(shù)據(jù)地址 到當(dāng)前PC值的相對偏移;
由于得到的結(jié)果是低12bit為0,
2^10 == 1024 Byte
2^12 == 4KB
所以要尋找的地址和當(dāng)前 pc 的值的誤差即4 kb, 也就是要尋找的(常量所在的)地址一定會在這 4KB 里面?,F(xiàn)在找到的是一個粗略的基址,以這個基址可以在(再加上)偏移4 kb 的范圍內(nèi)找到。

要算準(zhǔn)確的地址呢?

第二句:add x0, x0, #0xf28 中的偏移 #0xf28,計算機(jī)編譯的時候知道的偏移地址,和此時的 pc 為:

Printing description of $pc:
(unsigned long) pc = 0x0000000100fe2888
可以得到:
0x100fe2888—> 0x100fe3000—>0x100fe3f28
計算過程:
p (char *) 0x100fe2000 + 0x1000 + 0xf28 = 0x100fe3f28

可以看到結(jié)果如下:

常量

第二個 adrp (全局變量)

此時的 (unsigned long) pc = 0x0000000100fe2894
通過推算,準(zhǔn)確的地址為:0x0000000100fe4d10

打印結(jié)果如下:

image.png

可以看到,找到的則為全局變量 f 的值。

注意:需要說明的一點是:要打印地址的值,即為指針做指向的值,p (Int *) 打印的還是這個地址,要打印該地址的值則為:p *(int *) + 地址。

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

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

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