我試圖通過查看從clang生成的程序集來學習x86程序集。例如,我想了解C中的自動數組是如何初始化爲全0的。從x86_64程序集調用memset
int64_t my_array [3000] = {0};
它看起來像程序集保留堆棧(3000 * 64b/8B/b)24000B然後調用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來抵消我的堆棧指針來組裝。
我不明白-24016部分雖然,似乎任意。因爲堆棧向內存地址越來越低,所以負數是24000,因此我需要多少*,但爲什麼多餘的16B? %ebp是32b所以只需要4B? –
請參閱第5章*堆棧對齊*在同一文檔中,它說:「64位系統將堆棧對齊16位。堆棧字大小爲8個字節,但在任何調用指令之前堆棧必須對齊16位。一個程序在存儲需要16字節對齊的XMM數據時可以依賴這些規則,這適用於所有64位系統(Windows,Linux,BSD)。 – amdn
對,謝謝!看起來我有一些閱讀要做! –