2017-05-30 66 views
0

我正在將我的程序移植到ml64,一半用於運動,一半用於查看我可以獲得多少性能。瞭解快速調用堆棧幀

不管怎麼說,我目前正試圖瞭解堆棧幀的設置,在這個例子中,據我所知:

push rbp  ; inherited, base pointer of caller, pushed on stack for storage 
mov rbp, rsp ; inherited, base pointer of the callee, moved to rbp for use as base pointer 
sub rsp, 32  ; intel guide says each frame must reserve 32 bytes for the storage of the 
       ; 4 arguments usually passed through registers 
and spl, -16 ; 16 byte alignment? 


mov rsp, rbp ; put your base pointer back in the callee register 
pop rbp   ; restore callers base pointer 

的2周的事情,我沒有得到的

  1. 從RSP中減去32怎麼做呢?據我所知,除了從一個堆棧幀到另一個堆棧幀的職責之外,它只是另一個寄存器,對吧?我懷疑它進入另一個堆棧框架而不是用於當前的框架。

  2. 什麼是SPL,爲什麼掩蓋它使16個字節對齊?

+0

1)它分配空間(因爲棧頂指向由定義RSP)2)SPL是可吸入懸浮粒子的低8位,所以你可以儘管通常使用RSP – Jester

+0

您可能還需要考慮使用用於對齊[爲什麼這個C++代碼比我手寫的程序集更快?](https://stackoverflow.com/questions/40354978/why-is-this-c-code-faster-than-my-hand-written-assembly-for -testing-the-collat​​):-) –

回答

1
push rbp  ;save non-volatile rbp 
mov rbp, rsp ;save old stack 
sub rsp, 32  ;reserve space for 32 bytes of local variables = 8 integers 
       ;or 4 pointers. 
       ;this is per the MS/Intel guides. You can use this as temp 
       ;storage for the parameters or for local variables. 
and spl, -16 ;align stack by 16 bytes (for sse code) 


mov rsp, rbp ;restore the old stack 
pop rbp   ;restore rbp 

如何從RSP減去32在所有

RSP做任何事情是堆棧指針,不只是另一個寄存器。對它做任何事情都會影響堆棧。在這種情況下,它保留棧局部變量的8×4 = 32個字節的空間,能夠加入到。

什麼是SPL?爲什麼掩蓋它使一些16字節對齊?

and rsp,-16強制四個LSB歸零。而且由於堆棧增長下來,它將它對齊16個字節。
使用SSE代碼時,需要16個字節的對齊,其中x64用於浮點數學運算。 16字節對齊允許編譯器使用速度更快的SSE加載和存儲指令。
SPLRSP的低8位。爲什麼編譯器選擇這樣做沒有意義。 這兩個指令都是4個字節,而and rsp,-16嚴格地更好,因爲它不調用部分寄存器更新。

Disassembly: 

0: 40 80 e4 f0  and spl,-16 ;bad! partial register update. 
4: 48 83 e4 f0  and rsp,-16 ;good 
8: 83 e4 f0   and esp,-16 ;not possible will zero upper 32 bits of rsp 

[RSP是]只是另一個寄存器,對不對?

不,RSP非常特別。
它指向the stack,這是PUSHPOP指令的作用。
所有本地變量和參數(不適合寄存器)都存儲在堆棧中。

瞭解FASTCALL

只有一個在X64調用約定。如果你指定一個除__fastcall以外的調用約定,更讓人困惑的是大多數編譯器會將它重新映射到X64上的__fastcall