<深入理解计算机系统> 通过程序的机器级表示来理解函数栈

C源码:

void swap(int *a,int *b)
{
   int c;
   c = *a; 
   *a = *b;
   *b = c;
}

int main(void)
{
   int a ;
   int b ;
   int ret;
   a =16;
   b = 64;
   ret = 0;
   swap(&a,&b);
   ret = a - b;
   return ret;
}

编译:

gcc -g func_stack.c -o a.out
objdump -dS a.out > main.dump

可以得到反汇编的汇编程序main.dump, 有对应的C程序,如下所示:

a.out:     文件格式 elf32-i386


Disassembly of section .init:

08048294 <_init>:
 8048294:	53                   	push   %ebx
 8048295:	83 ec 08             	sub    $0x8,%esp
 8048298:	e8 83 00 00 00       	call   8048320 <__x86.get_pc_thunk.bx>
 804829d:	81 c3 63 1d 00 00    	add    $0x1d63,%ebx
 80482a3:	8b 83 fc ff ff ff    	mov    -0x4(%ebx),%eax
 80482a9:	85 c0                	test   %eax,%eax
 80482ab:	74 05                	je     80482b2 <_init+0x1e>
 80482ad:	e8 1e 00 00 00       	call   80482d0 <__gmon_start__@plt>
 80482b2:	83 c4 08             	add    $0x8,%esp
 80482b5:	5b                   	pop    %ebx
 80482b6:	c3                   	ret    

Disassembly of section .plt:

080482c0 <__gmon_start__@plt-0x10>:
 80482c0:	ff 35 04 a0 04 08    	pushl  0x804a004
 80482c6:	ff 25 08 a0 04 08    	jmp    *0x804a008
 80482cc:	00 00                	add    %al,(%eax)
	...

080482d0 <__gmon_start__@plt>:
 80482d0:	ff 25 0c a0 04 08    	jmp    *0x804a00c
 80482d6:	68 00 00 00 00       	push   $0x0
 80482db:	e9 e0 ff ff ff       	jmp    80482c0 <_init+0x2c>

080482e0 <__libc_start_main@plt>:
 80482e0:	ff 25 10 a0 04 08    	jmp    *0x804a010
 80482e6:	68 08 00 00 00       	push   $0x8
 80482eb:	e9 d0 ff ff ff       	jmp    80482c0 <_init+0x2c>

Disassembly of section .text:

080482f0 <_start>:
 80482f0:	31 ed                	xor    %ebp,%ebp
 80482f2:	5e                   	pop    %esi
 80482f3:	89 e1                	mov    %esp,%ecx
 80482f5:	83 e4 f0             	and    $0xfffffff0,%esp
 80482f8:	50                   	push   %eax
 80482f9:	54                   	push   %esp
 80482fa:	52                   	push   %edx
 80482fb:	68 c0 84 04 08       	push   $0x80484c0
 8048300:	68 50 84 04 08       	push   $0x8048450
 8048305:	51                   	push   %ecx
 8048306:	56                   	push   %esi
 8048307:	68 0f 84 04 08       	push   $0x804840f
 804830c:	e8 cf ff ff ff       	call   80482e0 <__libc_start_main@plt>
 8048311:	f4                   	hlt    
 8048312:	66 90                	xchg   %ax,%ax
 8048314:	66 90                	xchg   %ax,%ax
 8048316:	66 90                	xchg   %ax,%ax
 8048318:	66 90                	xchg   %ax,%ax
 804831a:	66 90                	xchg   %ax,%ax
 804831c:	66 90                	xchg   %ax,%ax
 804831e:	66 90                	xchg   %ax,%ax

08048320 <__x86.get_pc_thunk.bx>:
 8048320:	8b 1c 24             	mov    (%esp),%ebx
 8048323:	c3                   	ret    
 8048324:	66 90                	xchg   %ax,%ax
 8048326:	66 90                	xchg   %ax,%ax
 8048328:	66 90                	xchg   %ax,%ax
 804832a:	66 90                	xchg   %ax,%ax
 804832c:	66 90                	xchg   %ax,%ax
 804832e:	66 90                	xchg   %ax,%ax

08048330 <deregister_tm_clones>:
 8048330:	b8 1f a0 04 08       	mov    $0x804a01f,%eax
 8048335:	2d 1c a0 04 08       	sub    $0x804a01c,%eax
 804833a:	83 f8 06             	cmp    $0x6,%eax
 804833d:	77 01                	ja     8048340 <deregister_tm_clones+0x10>
 804833f:	c3                   	ret    
 8048340:	b8 00 00 00 00       	mov    $0x0,%eax
 8048345:	85 c0                	test   %eax,%eax
 8048347:	74 f6                	je     804833f <deregister_tm_clones+0xf>
 8048349:	55                   	push   %ebp
 804834a:	89 e5                	mov    %esp,%ebp
 804834c:	83 ec 18             	sub    $0x18,%esp
 804834f:	c7 04 24 1c a0 04 08 	movl   $0x804a01c,(%esp)
 8048356:	ff d0                	call   *%eax
 8048358:	c9                   	leave  
 8048359:	c3                   	ret    
 804835a:	8d b6 00 00 00 00    	lea    0x0(%esi),%esi

08048360 <register_tm_clones>:
 8048360:	b8 1c a0 04 08       	mov    $0x804a01c,%eax
 8048365:	2d 1c a0 04 08       	sub    $0x804a01c,%eax
 804836a:	c1 f8 02             	sar    $0x2,%eax
 804836d:	89 c2                	mov    %eax,%edx
 804836f:	c1 ea 1f             	shr    $0x1f,%edx
 8048372:	01 d0                	add    %edx,%eax
 8048374:	d1 f8                	sar    %eax
 8048376:	75 01                	jne    8048379 <register_tm_clones+0x19>
 8048378:	c3                   	ret    
 8048379:	ba 00 00 00 00       	mov    $0x0,%edx
 804837e:	85 d2                	test   %edx,%edx
 8048380:	74 f6                	je     8048378 <register_tm_clones+0x18>
 8048382:	55                   	push   %ebp
 8048383:	89 e5                	mov    %esp,%ebp
 8048385:	83 ec 18             	sub    $0x18,%esp
 8048388:	89 44 24 04          	mov    %eax,0x4(%esp)
 804838c:	c7 04 24 1c a0 04 08 	movl   $0x804a01c,(%esp)
 8048393:	ff d2                	call   *%edx
 8048395:	c9                   	leave  
 8048396:	c3                   	ret    
 8048397:	89 f6                	mov    %esi,%esi
 8048399:	8d bc 27 00 00 00 00 	lea    0x0(%edi,%eiz,1),%edi

080483a0 <__do_global_dtors_aux>:
 80483a0:	80 3d 1c a0 04 08 00 	cmpb   $0x0,0x804a01c
 80483a7:	75 13                	jne    80483bc <__do_global_dtors_aux+0x1c>
 80483a9:	55                   	push   %ebp
 80483aa:	89 e5                	mov    %esp,%ebp
 80483ac:	83 ec 08             	sub    $0x8,%esp
 80483af:	e8 7c ff ff ff       	call   8048330 <deregister_tm_clones>
 80483b4:	c6 05 1c a0 04 08 01 	movb   $0x1,0x804a01c
 80483bb:	c9                   	leave  
 80483bc:	f3 c3                	repz ret 
 80483be:	66 90                	xchg   %ax,%ax

080483c0 <frame_dummy>:
 80483c0:	a1 10 9f 04 08       	mov    0x8049f10,%eax
 80483c5:	85 c0                	test   %eax,%eax
 80483c7:	74 1f                	je     80483e8 <frame_dummy+0x28>
 80483c9:	b8 00 00 00 00       	mov    $0x0,%eax
 80483ce:	85 c0                	test   %eax,%eax
 80483d0:	74 16                	je     80483e8 <frame_dummy+0x28>
 80483d2:	55                   	push   %ebp
 80483d3:	89 e5                	mov    %esp,%ebp
 80483d5:	83 ec 18             	sub    $0x18,%esp
 80483d8:	c7 04 24 10 9f 04 08 	movl   $0x8049f10,(%esp)
 80483df:	ff d0                	call   *%eax
 80483e1:	c9                   	leave  
 80483e2:	e9 79 ff ff ff       	jmp    8048360 <register_tm_clones>
 80483e7:	90                   	nop
 80483e8:	e9 73 ff ff ff       	jmp    8048360 <register_tm_clones>

080483ed <swap>:
/*main.c代码:*/

void swap(int *a,int *b)
{
 80483ed:	55                   	push   %ebp
 80483ee:	89 e5                	mov    %esp,%ebp
 80483f0:	83 ec 10             	sub    $0x10,%esp
   int c;
   c = *a; 
 80483f3:	8b 45 08             	mov    0x8(%ebp),%eax
 80483f6:	8b 00                	mov    (%eax),%eax
 80483f8:	89 45 fc             	mov    %eax,-0x4(%ebp)
   *a = *b;
 80483fb:	8b 45 0c             	mov    0xc(%ebp),%eax
 80483fe:	8b 10                	mov    (%eax),%edx
 8048400:	8b 45 08             	mov    0x8(%ebp),%eax
 8048403:	89 10                	mov    %edx,(%eax)
   *b = c;
 8048405:	8b 45 0c             	mov    0xc(%ebp),%eax
 8048408:	8b 55 fc             	mov    -0x4(%ebp),%edx
 804840b:	89 10                	mov    %edx,(%eax)
}
 804840d:	c9                   	leave  
 804840e:	c3                   	ret    

0804840f <main>:

int main(void)
{
 804840f:	55                   	push   %ebp
 8048410:	89 e5                	mov    %esp,%ebp
 8048412:	83 ec 18             	sub    $0x18,%esp
   int a ;
   int b ;
   int ret;
   a =16;
 8048415:	c7 45 f4 10 00 00 00 	movl   $0x10,-0xc(%ebp)
   b = 64;
 804841c:	c7 45 f8 40 00 00 00 	movl   $0x40,-0x8(%ebp)
   ret = 0;
 8048423:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
   swap(&a,&b);
 804842a:	8d 45 f8             	lea    -0x8(%ebp),%eax
 804842d:	89 44 24 04          	mov    %eax,0x4(%esp)
 8048431:	8d 45 f4             	lea    -0xc(%ebp),%eax
 8048434:	89 04 24             	mov    %eax,(%esp)
 8048437:	e8 b1 ff ff ff       	call   80483ed <swap>
   ret = a - b;
 804843c:	8b 55 f4             	mov    -0xc(%ebp),%edx
 804843f:	8b 45 f8             	mov    -0x8(%ebp),%eax
 8048442:	29 c2                	sub    %eax,%edx
 8048444:	89 d0                	mov    %edx,%eax
 8048446:	89 45 fc             	mov    %eax,-0x4(%ebp)
   return ret;
 8048449:	8b 45 fc             	mov    -0x4(%ebp),%eax
}
 804844c:	c9                   	leave  
 804844d:	c3                   	ret    
 804844e:	66 90                	xchg   %ax,%ax

08048450 <__libc_csu_init>:
 8048450:	55                   	push   %ebp
 8048451:	57                   	push   %edi
 8048452:	31 ff                	xor    %edi,%edi
 8048454:	56                   	push   %esi
 8048455:	53                   	push   %ebx
 8048456:	e8 c5 fe ff ff       	call   8048320 <__x86.get_pc_thunk.bx>
 804845b:	81 c3 a5 1b 00 00    	add    $0x1ba5,%ebx
 8048461:	83 ec 1c             	sub    $0x1c,%esp
 8048464:	8b 6c 24 30          	mov    0x30(%esp),%ebp
 8048468:	8d b3 0c ff ff ff    	lea    -0xf4(%ebx),%esi
 804846e:	e8 21 fe ff ff       	call   8048294 <_init>
 8048473:	8d 83 08 ff ff ff    	lea    -0xf8(%ebx),%eax
 8048479:	29 c6                	sub    %eax,%esi
 804847b:	c1 fe 02             	sar    $0x2,%esi
 804847e:	85 f6                	test   %esi,%esi
 8048480:	74 27                	je     80484a9 <__libc_csu_init+0x59>
 8048482:	8d b6 00 00 00 00    	lea    0x0(%esi),%esi
 8048488:	8b 44 24 38          	mov    0x38(%esp),%eax
 804848c:	89 2c 24             	mov    %ebp,(%esp)
 804848f:	89 44 24 08          	mov    %eax,0x8(%esp)
 8048493:	8b 44 24 34          	mov    0x34(%esp),%eax
 8048497:	89 44 24 04          	mov    %eax,0x4(%esp)
 804849b:	ff 94 bb 08 ff ff ff 	call   *-0xf8(%ebx,%edi,4)
 80484a2:	83 c7 01             	add    $0x1,%edi
 80484a5:	39 f7                	cmp    %esi,%edi
 80484a7:	75 df                	jne    8048488 <__libc_csu_init+0x38>
 80484a9:	83 c4 1c             	add    $0x1c,%esp
 80484ac:	5b                   	pop    %ebx
 80484ad:	5e                   	pop    %esi
 80484ae:	5f                   	pop    %edi
 80484af:	5d                   	pop    %ebp
 80484b0:	c3                   	ret    
 80484b1:	eb 0d                	jmp    80484c0 <__libc_csu_fini>
 80484b3:	90                   	nop
 80484b4:	90                   	nop
 80484b5:	90                   	nop
 80484b6:	90                   	nop
 80484b7:	90                   	nop
 80484b8:	90                   	nop
 80484b9:	90                   	nop
 80484ba:	90                   	nop
 80484bb:	90                   	nop
 80484bc:	90                   	nop
 80484bd:	90                   	nop
 80484be:	90                   	nop
 80484bf:	90                   	nop

080484c0 <__libc_csu_fini>:
 80484c0:	f3 c3                	repz ret 

Disassembly of section .fini:

080484c4 <_fini>:
 80484c4:	53                   	push   %ebx
 80484c5:	83 ec 08             	sub    $0x8,%esp
 80484c8:	e8 53 fe ff ff       	call   8048320 <__x86.get_pc_thunk.bx>
 80484cd:	81 c3 33 1b 00 00    	add    $0x1b33,%ebx
 80484d3:	83 c4 08             	add    $0x8,%esp
 80484d6:	5b                   	pop    %ebx
 80484d7:	c3                   	ret    

注:

1. 按照习惯栈底放在栈顶上面,栈向下生长,地址递减.

2. 汇编的指令+操作数,操作数可以是立即数(常数,如$0x8)/寄存器/存储器(存储器会有寻址方式). 常用的指令包括mov/sub/add/push/pop/leave/ret/call等.

3. esp是栈顶指针, ebp是帧指针--栈底指针.  函数的参数入栈是从右到左,是可以控制的


具体汇编可以参考如下链接,写的很详细:

点击打开链接

点击打开链接

你可能感兴趣的:(<深入理解计算机系统> 通过程序的机器级表示来理解函数栈)