【发布时间】:2015-11-30 15:03:46
【问题描述】:
我编写了一些代码来了解调用堆栈。我已经使用一些内联程序集来完成此操作,用于在堆栈上传递参数。我用 gcc 4.1.2(在 CentOS5.4 上)编译它,它运行良好,然后我用 gcc 4.8.4(在 Ubuntu14.04.3 上)编译它并运行程序,但它总是崩溃。
我发现变量的引用方式存在差异。局部变量使用 gcc 4.1.2(CentOS5.4) 中的 EBP 寄存器寻址,而局部变量使用 gcc 4.8.4(Ubuntu14.04.3) 中的 ESP 寄存器寻址。这似乎是它崩溃的原因。
我的问题是,我如何控制 gcc 是使用 EBP 还是 ESP?还有,它们有什么区别?
这是 C 代码:
double fun(double d) {
return d;
}
int main(void) {
double a = 1.6;
double (*myfun)() = fun;
asm volatile("subl $8, %esp\n"
"fstpl (%esp)\n");
myfun();
asm volatile("addl $8, %esp\n");
return 0;
}
这是 gcc 4.1.2 中的程序集,它可以工作
int main(void) {
**......**
double a = 1.6;
0x080483bf <+17>: fldl 0x80484d0
0x080483c5 <+23>: fstpl -0x18(%ebp)
double (*myfun) () = fun;
0x080483c8 <+26>: movl $0x8048384,-0xc(%ebp)
asm volatile("subl $8, %esp\n"
"fstpl (%esp)\n");
0x080483cf <+33>: sub $0x8,%esp
0x080483d2 <+36>: fstpl (%esp)
myfun();
0x080483d5 <+39>: mov -0xc(%ebp),%eax
0x080483d8 <+42>: call *%eax
0x080483da <+44>: fstp %st(0)
asm volatile("addl $8, %esp\n");
0x080483dc <+46>: add $0x8,%esp
**......**
这是 gcc 4.8.4 中的程序集。这就是崩溃的原因:
int main(void) {
**......**
double a = 1.6;
0x0804840d <+9>: fldl 0x80484d0
0x08048413 <+15>: fstpl 0x8(%esp)
double (*myfun)() = fun;
0x08048417 <+19>: movl $0x80483ed,0x4(%esp)
asm volatile("subl $8,%esp\n"
"fstpl (%esp)\n");
0x0804841f <+27>: sub $0x8,%esp
0x08048422 <+30>: fstpl (%esp)
myfun();
0x08048425 <+33>: mov 0x4(%esp),%eax
0x08048429 <+37>: call *%eax
0x0804842b <+39>: fstp %st(0)
asm volatile("addl $8,%esp\n");
0x0804842d <+41>: add $0x8,%esp
**......**
【问题讨论】:
-
我昨天粘贴了错误的代码,很抱歉浪费了您所有的时间。代码现在更新。
标签: c gcc disassembly