C++设置堆栈指针

3

在我的C++/C项目中,我想将堆栈指针设置为基址指针... 直觉告诉我应该使用类似这样的代码:

asm volatile(
    "movl %%ebp %%esp"
);

然而,当我执行此操作时,我收到了以下错误消息:
Error: bad register name `%%ebp %%esp'

我使用gcc/g++版本4.9.1编译器。

我不知道是否需要设置特定的g++或gcc标志...应该有一种方法来操作espebp寄存器,但我不知道正确的操作方式。

有人知道如何在c++中操作这两个寄存器吗?也许我应该用十六进制OP代码来做?


7
%%ebp%%esp 之间缺少一个逗号。 - JFMR
1
你可能想要使用 movl %%ebp, %%esp。但是,除非你创建了一个“裸函数”,否则不要这样做,因为你的代码将与编译器自动完成的堆栈帧设置冲突。 - Daniel Kamil Kozar
6
在简单的汇编语言中,您不需要双倍使用“%”。但是,您尝试做的事情非常糟糕,听起来像一个XY问题。 - Jester
@Jester 我知道这有点糊弄,但我没有看到其他更好的解决方案...链接: http://stackoverflow.com/questions/43976035/c-forward-function-call链接: http://stackoverflow.com/questions/43089692/jni-intercepting-native-methods-outputs - Aksim Elnik
3
为什么这个被踩了?是不是自动机制会给'C'标记的问题打一个-3的分数惩罚或者类似的东西? - Tommylee2k
显示剩余5条评论
1个回答

5
您正在使用 GNU C Basic Asm 语法(没有输入/输出/破坏约束),因此 % 不是特殊字符,因此不应该转义。

只有在带有约束的 扩展 Asm 中,% 才需要转义,以便在编译器的 asm 输出中硬编码的寄存器名称前面仅出现一个 % (根据 AT&T 语法的要求)。

您还必须使用逗号分隔操作数:

asm volatile(
    "movl %ebp, %esp"
);

asm语句没有输出操作数时会隐式成为易失性,但显式使用volatile也无妨。

然而,请注意将此语句放在函数内可能会干扰编译器处理堆栈帧的方式。


为什么在eax或ebx前需要双重'%',但在ebp和esp前只需要单个'%'???是的,谢谢,它起作用了 :) - Aksim Elnik
@AksimElnik 我认为只有在汇编字符串后面跟着冒号(:)时,才需要双百分号(%%)。 - JFMR
啊,有道理...谢谢。 - Aksim Elnik
你的内联汇编没有参数,因此没有理由转义寄存器(因为没有“%1”,“%2”,...)。 - JFMR
@AksimElnik:GNU C基本(无操作数)与扩展(带操作数)汇编有其他区别。例如,基本汇编语句隐式地是“易失性的”(但没有输出操作数的扩展汇编语句也是如此)。https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html - Peter Cordes
@眠りネロク:你应该说将这个语句放在函数内是没有用的,而且只会干扰编译器(正如Jester指出的)。我已经扩展了你的答案来解释为什么,但我认为加上这个也太过于替你说话了。特别是因为问题是在问“如何在C++中操作这两个寄存器”。 - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接