簡體   English   中英

從 x86_64 程序集調用 memset

[英]calling memset from x86_64 assembly

我正在嘗試通過查看從 clang 生成的程序集來學習 x86 程序集。 例如,我想了解 C 中的自動數組如何初始化為全 0。

int64_t my_array [3000] = {0};

看起來程序集在堆棧上保留 24000B ( 3000 * 64b / 8B/b ) 然后調用 memset。 從 memset 的手冊頁,它的簽名看起來像:

void *
memset(void *b, int c, size_t len);

所以我知道應該在 %rsi 中傳遞的第二個參數是 0(我希望每個字節設置的值),第三個參數 (%rdx) 是 $24000,但是第一個參數 (%rdi) 呢? 生成的程序集中的兩個相關指令似乎是:

leaq  -24016(%rbp), %rax
movq  %rax, %rdi

但我不明白為什么基指針為負 24016? 為什么存儲在 %rax 中然后立即移動到 %rdi (也許是因為我沒有使用優化進行編譯)?

無論哪種方式,我都不確定如何將數組的第一個字節的地址傳遞給 memset。 我也在 OSX 上,所以我已經不得不將堆棧指針偏移 8B 才能組裝。

您已在堆棧(自動存儲)上分配了my_array ,這意味着編譯器必須將堆棧指針(堆棧向低地址增長)遞減為局部變量的大小加上用於保存寄存器等的空間。 %ebp基指針被設置為指向調用者的幀指針(在通過將調用者的基指針壓入堆棧來保存調用者的基指針之后)。 這是正確堆棧展開所需的約定的一部分。 請參閱 Agner Fog 的綜合調用約定文檔中的第 9 章異常處理和堆棧展開

http://www.agner.org/optimize/calling_conventions.pdf

由於%ebp指向調用者的幀,編譯器使用它的負偏移量指向my_array的開頭,這是被調用函數中的局部變量。

我不知道為什么編譯器將地址存儲在%rax並立即將其復制到%rdi ,似乎可以一步完成

leaq  -24016(%rbp), %rdi

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM