我在使用VS 2015 C ++的x64内联汇编中使用rsp
和rbp
寄存器进行内存索引。是否有可能没有保存和恢复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
之后,内存的基址被更改。这没问题吗?
答案 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
文件。调用约定是不同的。