GCC内汇编不会让我重写$ ESP [英] GCC INLINE ASSEMBLY Won't Let Me Overwrite $esp

查看:132
本文介绍了GCC内汇编不会让我重写$ 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆