学习C++反汇编-函数

C++源代码:

#include<stdio.h>
void __stdcall Show1(int m);
void __cdecl Show2(int n);

int main()
{
	Show1(1);
	Show2(2);
	return 0;
}

void __stdcall Show1(int m)
{
	printf("%d\n",m);
}

void _cdecl Show2(int n)
{

	printf("%d\n",n);
}
生成的汇编代码:

Dump of assembler code for function main:
0x004012f0 <main+0>:	push   %ebp
0x004012f1 <main+1>:	mov    %esp,%ebp
0x004012f3 <main+3>:	sub    $0x8,%esp
0x004012f6 <main+6>:	and    $0xfffffff0,%esp
0x004012f9 <main+9>:	mov    $0x0,%eax
0x004012fe <main+14>:	add    $0xf,%eax
0x00401301 <main+17>:	add    $0xf,%eax
0x00401304 <main+20>:	shr    $0x4,%eax
0x00401307 <main+23>:	shl    $0x4,%eax
0x0040130a <main+26>:	mov    %eax,-0x4(%ebp)
0x0040130d <main+29>:	mov    -0x4(%ebp),%eax
0x00401310 <main+32>:	call   0x401888 <_alloca>
0x00401315 <main+37>:	call   0x401408 <__main>
0x0040131a <main+42>:	movl   $0x1,(%esp)
0x00401321 <main+49>:	call   0x40133c <_Z5Show1i>
0x00401326 <main+54>:	sub    $0x4,%esp
0x00401329 <main+57>:	movl   $0x2,(%esp)
0x00401330 <main+64>:	call   0x40135a <_Z5Show2i>
0x00401335 <main+69>:	mov    $0x0,%eax
0x0040133a <main+74>:	leave  
0x0040133b <main+75>:	ret    
End of assembler dump.
(gdb)
Dump of assembler code for function _Z5Show1i:
0x0040133c <_Z5Show1i+0>:	push   %ebp
0x0040133d <_Z5Show1i+1>:	mov    %esp,%ebp
0x0040133f <_Z5Show1i+3>:	sub    $0x8,%esp
0x00401342 <_Z5Show1i+6>:	mov    0x8(%ebp),%eax
0x00401345 <_Z5Show1i+9>:	mov    %eax,0x4(%esp)
0x00401349 <_Z5Show1i+13>:	movl   $0x403000,(%esp)
0x00401350 <_Z5Show1i+20>:	call   0x4018e8 <printf>
0x00401355 <_Z5Show1i+25>:	leave  
0x00401356 <_Z5Show1i+26>:	ret    $0x4
End of assembler dump.
(gdb)
Dump of assembler code for function _Z5Show2i:
0x0040135a <_Z5Show2i+0>:	push   %ebp
0x0040135b <_Z5Show2i+1>:	mov    %esp,%ebp
0x0040135d <_Z5Show2i+3>:	sub    $0x8,%esp
0x00401360 <_Z5Show2i+6>:	mov    0x8(%ebp),%eax
0x00401363 <_Z5Show2i+9>:	mov    %eax,0x4(%esp)
0x00401367 <_Z5Show2i+13>:	movl   $0x403000,(%esp)
0x0040136e <_Z5Show2i+20>:	call   0x4018e8 <printf>
0x00401373 <_Z5Show2i+25>:	leave  
0x00401374 <_Z5Show2i+26>:	ret    
End of assembler dump.
(gdb) 
main函数和被它调用的函数一样,进入函数后第一件事都是保存栈底指针ebp,调整当前栈底指针位置到栈顶,抬高栈顶esp,此时开辟栈空间作为局部变量的存储空间。

push   %ebp
mov    %esp,%ebp
sub    $0x8,%esp
_cdecl(show2)是C++的默认调用方式,调用方平衡栈,不定参数的函数可以使用;

__stdcall(show1)则是由被调用方平衡栈,不定参数的函数无法使用。

在调用方"自作主张"平衡栈后,main函数中又减了回来,保证最终的结果平衡。

你可能感兴趣的:(学习C++反汇编-函数)