我已經編寫了一些代碼來了解調用堆棧。我用一些內聯程序集來完成這個任務,以便將參數傳遞給堆棧。我用gcc 4.1.2編譯了它(在CentOS5.4上),它運行良好,然後使用gcc 4.8.4(在Ubuntu14.04.3上)編譯並運行程序,但它總是崩潰。基於ebp的尋址和esp尋址的區別
我發現在引用變量的方式上存在差異。局部變量使用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
**......**
昨天我粘貼了錯誤的代碼,我很抱歉浪費你所有的時間。代碼現在正在更新。 –