MSDN 說
最左邊四個位置的整數值引數分別在 RCX、RDX、R8 和 R9 中以從左到右的順序傳遞。在呼叫堆疊上分配空間作為被呼叫者保存這些暫存器的影子存盤。剩余的引數按從右到左的順序被壓入堆疊。
所以,我正在嘗試呼叫該CreateFileW函式,這是我的代碼:
sub rsp, 20h ; Allocate 32 bytes because 4 registers 8 byte each
mov rcx, offset filename ; lpFileName
mov rdx, GENERIC_READ or GENERIC_WRITE ; dwDesiredAccess
mov r8, FILE_SHARE_DELETE ; dwShareMode
xor r9, r9 ; LpSecurityAttributes
;__And right-to-left order remaining arguments__
push 0 ; hTemplateFile
push FILE_ATTRIBUTE_NORMAL ;dwFlagsAndAttributes
push CREATE_ALWAYS ; dwCreationDisposition
call CreateFileW
它組裝,但不作業,win64dbg 導致下一個錯誤:
00000057 (ERROR_INVALID_PARAMETER)
引數是 100% 好的,因為它適用于Invoke宏,只是生成的代碼不同。
mov rcx,src.403000 ;name
mov edx,C0000000 ;GENERIC_READ or GENERIC_WRITE
mov r8d,4 ;FILE_SHARE_DELETE
xor r9d,r9d ;0
mov qword ptr ss:[rbp-20],2; ;CREATE_ALWAYS
mov qword ptr ss:[rbp-18],80 ;FILE_ATTRIBUTE_NORMAL
and qword ptr ss:[rbp-10],0 ;0
call qword ptr ds:[<&CreateFileW>]
所以我的問題是為什么它使用 RBP 暫存器而不是push并且不為“影子存盤”分配 32 個位元組?
筆記
由于 Microsoft 的 64 位 MASM 不再具有invoke指令,因此我正在使用具有宏的俄羅斯MASM64 SDK專案invoke。該專案松散地基于MASM32 SDK。
uj5u.com熱心網友回復:
如果你想pushargs,你必須在 sub rsp,20h. (這不能很好地作業,因為通常你只需要一個sub rsp,20h用于整個函式,而不是每個呼叫一個)。并且您必須正確計數才能在最后一個之后具有 RSP == 0 push。除了在 Windows x64 中的函式 prologue/epilogue 中,您通常不想更改 RSP,除了 alloca 型別的東西。
堆疊引數位于影子空間之上,因此如果函式將其暫存器引數轉儲到影子空間中的“主空間”,它將有一個連續的引數陣列。(像 printf 這樣的可變函式實際上會這樣做;除非是除錯版本,否則普通函式不會。)
使用除錯器查看堆疊記憶體(在 RSP 上方)的內容,然后按照您的方式與將arg 空間堆疊到影子空間上方的call正常存盤方式進行對比。mov
請注意,sub rsp,20h它不足以為陰影空間和堆疊引數保留空間,因此您顯示的“呼叫宏”代碼必須在此函式的開頭保留更多空間。
為什么它使用 RBP 暫存器而不是 push 并且不為“影子存盤”分配 32 個位元組?
它使用 RBP 是因為如果您已經使用指令將 RBP 設定為幀指標,這是訪問堆疊空間的一種正常方式。
更清楚、更容易地看到相對于 RSP 的尋址模式發生了什么,例如[rsp 20h]訪問陰影空間上方的第一個插槽,您希望在其中存盤第一個堆疊 arg。
如果您分配了可變數量的空間,那么這將是必要的,因此從 RBP 到陰影空間正上方的距離是未知的,但無論如何您都可以這樣做,只是為了清晰和易于獲得正確的偏移量。但是,如果編譯器或聰明的宏可以計算正確的偏移量,并且您已經使用指令將 RBP 設定為幀指標,那么使用它的效率會稍微高一些,因為它在機器代碼中節省了一個位元組([rsp constant]需要一個 SIB要編碼的位元組。)
常規 MASM 沒有invoke64 位模式。不知道你用的是什么。也許您需要手動保留堆疊空間,或者它可能在函式頂部為您執行此操作,但您忽略了它。Michael Petch 說 MASM64 帶有一個invoke宏,它可以sub rsp在你的代碼中添加一個宏。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/527630.html
標籤:Intel Collective 部件x86-64拆卸调用约定masm64
上一篇:為什么(或為什么不)將Neon內在資料型別作為輸入/輸出函式引數傳遞?
下一篇:如何在MASM中跨段填充塊?
