2017-05-30 69 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