上面探讨了没有使用-fomit-frame-pointer编译选项的程序的栈桢规律,那么如果一个程序是通过-fomit-frame-pointer编译选项来编译,它运行时的栈桢规律有没有可能不同呢?
先看一个例子:
int func( int num )
{
int result = num*num;
result += num - 1;
return result;
}
void test(int beg, int end )
{
int a[10];
for ( int i = 0; i < 10; i++ )
{
a[i] = beg + func( i ) + end;
}
}
int main()
{
test( 5, 100);
return 0;
}
看一下它们的汇编:
gdb) disassemble func(int)
Dump of assembler code for function _Z4funci:
0x08048470 <+0>: sub $0x10,%esp
0x08048473 <+3>: mov 0x14(%esp),%eax
0x08048477 <+7>: imul 0x14(%esp),%eax
0x0804847c <+12>: mov %eax,0xc(%esp)
0x08048480 <+16>: mov 0x14(%esp),%eax
0x08048484 <+20>: sub $0x1,%eax
0x08048487 <+23>: add %eax,0xc(%esp)
0x0804848b <+27>: mov 0xc(%esp),%eax
0x0804848f <+31>: add $0x10,%esp
0x08048492 <+34>: ret
End of assembler dump.
(gdb) disassemble test
Dump of assembler code for function _Z4testii:
0x08048493 <+0>: sub $0x34,%esp
0x08048496 <+3>: movl $0x0,0x30(%esp)
0x0804849e <+11>: jmp 0x80484c5 <_Z4testii+50>
0x080484a0 <+13>: mov 0x30(%esp),%eax
0x080484a4 <+17>: mov %eax,(%esp)
0x080484a7 <+20>: call 0x8048470 <_Z4funci>
0x080484ac <+25>: mov 0x38(%esp),%edx
0x080484b0 <+29>: add %eax,%edx
0x080484b2 <+31>: mov 0x3c(%esp),%eax
0x080484b6 <+35>: add %eax,%edx
0x080484b8 <+37>: mov 0x30(%esp),%eax
0x080484bc <+41>: mov %edx,0x8(%esp,%eax,4)
0x080484c0 <+45>: addl $0x1,0x30(%esp)
0x080484c5 <+50>: cmpl $0x9,0x30(%esp)
0x080484ca <+55>: setle %al
0x080484cd <+58>: test %al,%al
0x080484cf <+60>: jne 0x80484a0 <_Z4testii+13>
0x080484d1 <+62>: add $0x34,%esp
0x080484d4 <+65>: ret
End of assembler dump.
可见,通过-fomit-frame-pointer编译选项编译出来的程序没有
push %ebp
mov %esp,%ebp
和
pop %ebp
ret
剩余内容请关注微信公众号"debugeeker"。链接为https://mp.weixin.qq.com/s/mQkC9sX0-2Sw4TsngJDhNA