我正在编写代码以暂时使用我自己的堆栈进行实验。当我使用文字内联汇编时,这很有效。我将变量位置硬编码为 ebp 的偏移量。但是,我希望我的代码能够在没有硬编码内存地址的情况下工作,所以我一直在研究 GCC 的扩展内联汇编。我所拥有的是以下内容:
volatile intptr_t new_stack_ptr = (intptr_t) MY_STACK_POINTER;
volatile intptr_t old_stack_ptr = 0;
asm __volatile__("movl %%esp, %0\n\t"
"movl %1, %%esp"
: "=r"(old_stack_ptr) /* output */
: "r"(new_stack_ptr) /* input */
);
这样做的重点是首先将堆栈指针保存到变量 old_stack_ptr 中。接下来,堆栈指针 (%esp) 被我保存在 new_stack_ptr 中的地址覆盖。
尽管如此,我发现 GCC 将 %esp 保存到 old_stack_ptr,但没有用 new_stack_ptr 替换 %esp。经过深入检查,我发现它实际上扩展了我的程序集并添加了它自己的说明,如下所示:
mov -0x14(%ebp),%eax
mov %esp,%eax
mov %eax,%esp
mov %eax,-0x18(%ebp)
我认为 GCC 试图保留 %esp,因为我没有将它明确声明为“输出”操作数......我可能完全错了......
我真的很想使用扩展的内联程序集来做到这一点,因为如果没有,似乎我必须将 %ebp 的位置偏移“硬编码”到程序集中,我宁愿使用这样的变量名.. . 特别是因为这段代码需要在几个不同的系统上工作,这些系统似乎都以不同的方式偏移了我的变量,所以使用扩展的内联汇编可以让我明确地说出变量的位置......但我不明白它为什么这样做额外的东西,并且不让我像以前那样覆盖堆栈指针,自从我开始使用扩展程序集以来,它一直在这样做。
我很感激任何帮助!!!