GCC内汇编不会让我重写$ ESP [英] GCC INLINE ASSEMBLY Won't Let Me Overwrite $esp
问题描述
我在写code暂时使用自己的堆栈实验。这个工作当我用文字内嵌汇编。我被硬编码的变量位置偏移量为关闭EBP的。不过,我希望我的code,而不haivng硬code内存地址到它的工作,所以我一直在寻找到GCC的扩展内联汇编。我有如下:
I'm writing code to temporarily use my own stack for experimentation. This worked when I used literal inline assembly. I was hardcoding the variable locations as offsets off of ebp. However, I wanted my code to work without haivng to hard code memory addresses into it, so I've been looking into GCC's EXTENDED INLINE ASSEMBLY. What I have is the following:
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的地址。
The point of this is to first save the stack pointer into the variable old_stack_ptr. Next, the stack pointer (%esp) is overwritten with the address I have saved in new_stack_ptr.
尽管如此,我发现GCC是保存%ESP成old_stack_ptr,但与new_stack_ptr更换%ESP。经检查更深,我发现它实际上扩大了我的组装和增加它自己的指令,这有以下几种:
Despite this, I found that GCC was saving the %esp into old_stack_ptr, but was NOT replacing %esp with new_stack_ptr. Upon deeper inspection, I found it actually expanded my assembly and added it's own instructions, which are the following:
mov -0x14(%ebp),%eax
mov %esp,%eax
mov %eax,%esp
mov %eax,-0x18(%ebp)
我觉得GCC试图preserve的ESP%,因为我没有做到这一点明确声明为输出操作......我可能是完全错误的这个...
I think GCC is trying to preserve the %esp, because I don't have it explicitly declared as an "output" operand... I could be totally wrong with this...
我真的很想使用扩展内联汇编要做到这一点,因为如果不是,好像我要硬code位置偏移了的%ebp到组件中,我宁愿用变量名像这样...特别是因为这code需要在几个不同的系统,这似乎所有的不同抵消我的变量,所以使用扩展内联汇编允许我明确地说,可变位置的工作......但我不明白为什么它做多余的东西,而不是让我改写堆栈指针像从前那样,自从我开始使用扩展组件,它已经这样做。
I really wanted to use extended inline assembly to do this, because if not, it seems like I have to "hard code" the location offsets off of %ebp into the assembly, and I'd rather use the variable names like this... especially because this code needs to work on a few different systems, which seem to all offset my variables differently, so using extended inline assembly allows me to explicitly say the variable location... but I don't understand why it is doing the extra stuff and not letting me overwrite the stack pointer like it was before, ever since I started using extended assembly, it's been doing this.
我AP preciate任何帮助!
I appreciate any help!!!
推荐答案
好了,所以问题的gcc分配的输入和输出到相同的寄存器 EAX
。你想告诉你所使用的输入,又名前重挫输出GCC。 earlyclobber。
Okay so the problem is gcc is allocating input and output to the same register eax
. You want to tell gcc that you are clobbering the output before using the input, aka. "earlyclobber".
asm __volatile__("movl %%esp, %0\n\t"
"movl %1, %%esp"
: "=&r"(old_stack_ptr) /* output */
: "r"(new_stack_ptr) /* input */
);
注意&安培;
签收输出。这应该可以解决您的code。
Notice the &
sign for the output. This should fix your code.
更新:或者,你可以强制输入和输出是相同的注册和使用 XCHG
,就像这样:
Update: alternatively, you could force input and output to be the same register and use xchg
, like so:
asm __volatile__("xchg %%esp, %0\n\t"
: "=r"(old_stack_ptr) /* output */
: "0"(new_stack_ptr) /* input */
);
注意0
,指出投入相同的寄存器以此为参数0 的。
这篇关于GCC内汇编不会让我重写$ ESP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!