的修改到%ESP引起SIGSEGV [英] A modification to %esp cause SIGSEGV
问题描述
有时候我用下面的code,以避免堆栈溢出的编码竞赛参加的时候。
Sometimes I use the following code to avoid stack overflow when taking part in coding competition.
int main()
{
static const int _STACK_SIZE = MAXN*10;
static int _STACK[_STACK_SIZE*2], _ESP;
__asm__ __volatile__
(
"movl %%esp, %0\n"
"movl %1, %%esp\n":
"=g"(_ESP):
"g"(_STACK + _STACK_SIZE):
);
// Do Something..
__asm__ __volatile__
(
"movl %0, %%esp\n":
:
"g"(_ESP):
);
}
据我所知,这ASM code备份%ESP
和移动堆栈 _STACK []
。
我的问题:为什么这code事业 SIGSEGV
上的x86-64 Linux服务器(它运行良好,对我自己的x86的Linux)?而如何解决?
My Question: Why this code cause SIGSEGV
on a x86-64 Linux Server(It runs well on my own x86 Linux)? And how to fix it?
我想,也许是因为%ESP
是一个64位指针??
I guess, maybe it's because %esp
is a 64-bit pointer??
我试图删除 __ asm__ __volatile __(MOVL%0,%% ESP \ N:G(_ ESP):);
,它似乎运行好?
I tried to delete the __asm__ __volatile__("movl %0, %%esp\n": : "g"(_ESP):);
and it seems runs well?
推荐答案
这是因为在x86-64的组装修改32位寄存器,如尤其
归零最高32相应的64位寄存器, RSP
在这种情况下,位。在X86-64堆栈指针 RSP
是一个64位寄存器。应该只发生在计算机上的问题,即有超过4吉布 虚拟内存地址空间,因为2 ^ 32字节= 4吉布,所以在计算机有少于4吉布的虚拟内存地址空间,最高的32位将是零呢。
It's because in x86-64 assembly modifying a 32-bit register such as esp
zeroes the highest 32 bits of the corresponding 64-bit register, rsp
in this case. In x86-64 the stack pointer rsp
is a 64-bit register. The problem should occur only in computers that have more than 4 GiB of virtual memory address space, because 2^32 bytes = 4 GiB, so in computers that have less than 4 GiB of virtual memory address space, the highest 32 bits will be zeros anyway.
因此,通过修改尤其
你让 RSP
指向你的程序没有访问权限的地址,因而导致段错误。在X86-64 code,你平常不使用尤其
可言,此时应更换尤其$ C $的所有实例C>与
RSP
在你的x86-64 code。
So by modifying esp
you make rsp
point to an address where your program has no access rights, and thus cause a segmentation fault. In x86-64 code you don't normally use esp
at all, and you should replace all instances of esp
with rsp
in your x86-64 code.
这篇关于的修改到%ESP引起SIGSEGV的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!