vs 2015中的英特尔x64 c ++内联汇编

时间:2017-04-02 10:14:35

标签: inline inline-assembly

我在使用VS 2015 C ++的x64内联汇编中使用rsprbp寄存器进行内存索引。是否有可能没有保存和恢复push rsp, push rbp,... pop rbp,pop rsp?

__asm{

mov rsi, memory
mov rsp, rsi
mov rbp, rsi
...
movntps [rsp+rdx], ymm0
... 

}

在调试模式下,在mov rbp, rsi之后,内存的基址被更改。这没问题吗?

1 个答案:

答案 0 :(得分:0)

编写内联汇编时,必须遵守编译器关于允许使用哪些寄存器的规则。 VS2015's rules are documented here我将引用关键位:

  

使用__asm在C / C ++函数中编写汇编语言时,您不需要保留EAX,EBX,ECX,EDX,ESI或EDI寄存器......您应该保留其他寄存器使用(例如DS,SS,SP,BP和标志寄存器)作为__asm块的范围。

将“应该”视为“必须”。因此,您的问题的答案很简单:“不,如果您想将它们用于任何事情,您必须保存并恢复ESP和EBP。”

在行间阅读,我认为你真正想要的是用汇编语言编写整个函数。使用Visual Studio,这意味着您将把它放在单独的.ASM文件中。您仍然必须符合calling convention,但不符合编译器对__asm块更严格的规则。请注意,调用约定仍然要求您保存和恢复ESP和EBP(事实上,除了EAX,ECX和EDX之外的所有寄存器)。

如果你实际编码x64 / Windows,那么,如果我正确阅读本文档,你就不能使用__asm;您必须使用单独的.ASM文件。调用约定是不同的。