我尝试使用__asm__
将%rbp
的值放入%rax
寄存器中,以便可以获得对堆栈帧的引用,该引用在创建外部变量时不会更改。
我使用下面的代码来做这件事:
int some_variadic_function(int n, ...)
{
__asm__("movl %rax, %rbp");
return 0;
}
int main() {
some_variadic_function(3, 1, 2, 3);
return 0;
}
然而,当我尝试用clang编译它时,我得到以下错误:
using_rbp.c:4:13: error: invalid operand for instruction
__asm__("movl %rax, %rbp");
^
<inline asm>:1:7: note: instantiated into assembly here
movl %rax, %rbp
^~~~~
1 error generated.
这似乎意味着我不能把%rbp
直接放到%rax
中,是这样还是这段代码有其他问题?
作为参考,我在Mac上使用x86-64
硬件。
1条答案
按热度按时间ig9co6j11#
你犯了一大堆错误。让我们一个一个来:
1.在AT&T的x86汇编语法中,如果你在指令上提供了一个大小后缀,它必须与从操作数推断出的大小相匹配。大小后缀几乎总是不需要的x86(我能想到的唯一的情况是,当你直接将一个立即值移动到内存中时,需要它们):我建议不要使用它们,除非汇编程序抱怨它们的缺失。
1.在AT&T汇编语法中,目的地是 second;
mov %rax, %rbp
将RAX复制到RBP,而不是相反。1.在GNU风格的内联汇编中,
%
开始一个转义序列(类似于printf
);要写一个文字寄存器名,你必须将百分号加倍。这就是为什么你会从clang得到错误,而不是从汇编程序得到错误。1.在64位System V ABI for x86中,
%rbp
是一个普通的通用寄存器,而不是“帧指针”。正确的做法是
但是,这必须使用
-fno-omit-frame-pointer
编译,否则返回值将是垃圾。你可能正遭受着臭名昭著的XY problem的折磨。问一个关于你最初试图做的事情的新问题,而不是关于你试图解决问题的细节,我们可能会更有帮助。