Linux下x86 64程序位址空間布局

2021-06-29 00:26:14 字數 1905 閱讀 8680

關於linux 32位記憶體下的記憶體空間布局,可以參考這篇博文linux下c程式程序位址空間局關於源**中各種資料型別/**在elf格式檔案以及程序空間中所處的段,在x86_64下和i386下是類似的,本文主要關注vm.legacy_va_layout以及kernel.randomize_va_space引數影響下的程序空間記憶體巨集觀布局,以及vdso和多執行緒下的堆和棧分布。

在前面談了兩個不同引數下的程序執行時記憶體空間巨集觀的分布。也許你會注意到這樣乙個細節,在每個程序的stack以上的位址中,有一段動態變化的對映位址段,比如下面這個程序,對映到vdso。

如果我們用ldd看相應的程式,會發現vdso在磁碟上沒有對應的so檔案。

不記得曾經在**看到大概這樣乙個問題:

getpid,gettimeofday是不是系統呼叫?

其實這個問題的答案就和vdso有關,雜x86_64和i386上,getpid是系統呼叫,而gettimeofday不是。

vdso全稱是virtual dynamic shared object,是一種核心將一些本身應該是系統呼叫的直接對映到使用者空間,這樣對於一些使用比較頻繁的系統呼叫,直接在使用者空間呼叫可以節省開銷。如果想詳細了解,可以參考這篇文件

下面我們用一段程式驗證下:

#include 

#include

#include

#include

int main(int argc, char **argv)

else

fprintf(stdout, "pid:%d\n", (int)getpid());

fprintf(stdout, "thread id:%d\n", (int)syscall(sys_gettid));

return

0;}

編譯為可執行檔案後,我們可以用strace來驗證:

strace -o temp ./vdso

grep getpid temp

grep gettimeofday temp

#include 

#include

#include

void *routine(void *args)

}int main(int argc, char *argv)

#include 

#include

#include

#include

static

int test_param = 10;

module_param(test_param, int, s_irugo | s_iwusr);

module_parm_desc(test_param, "a test parameter");

static

int print_all_processes_init(void)

};return0;}

static

void print_all_processes_exit(void)

module_init(print_all_processes_init);

module_exit(print_all_processes_exit);

module_author("feilengcui");

module_license("gpl");

module_description("a module print all processes");

x86 64 核心堆疊

switch to.h中 define switch to prev,next,last do while 0 會切換將切換前的程序核心堆疊指標用彙編movl esp,prev sp 儲存。其中被儲存的位址 prev sp 是prev thread.sp 切換後的程序esp從儲存中恢復使用彙編 mo...

x86 64彙編 控制

跳轉指令 條件分支 迴圈switch語句 總結自 深入理解計算機系統 第三版 cpu還維護一組單個位的條件碼暫存器,用來描述最近的算術和邏輯操作的屬性。常用 cf 無符號溢位 of 有符號溢位 zf 零標誌 sf 符號標誌 注意 test指令與and指令一樣,而不改變dest暫存器 用法 兩個運算元...

linux 啟動 過程 學習 (x86 64

1.arch x86 boot header.s kernel setup 從 start開始。設定 stack,bss,最後跳轉到 arch x86 boot main.c。2.在main函式中,把kernel setup header 拷貝到 struct setup header,之後初con...