反汇编一个简单的C

原创 2017年07月20日 22:05:14

朱婷婷 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

计算机是怎么工作的?

我们知道计算机基本都是采用的冯诺依曼体系结构,它主要的核心思想就是存储程序计算机,指令和数据不加区别混合存储在同一个存储器中。CPU通过寄存器EIP指向内存从而获取内存中的数据。EIP总是指向内存的某一块区域(代码段),不断的指向下一条指令,每条指令的长度可能是不同的。我们可以用一个简单的图来描述下:




一、实验内容:通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的

main.c

int g(int x)
{
    return x+4;
}

int f(int y)
{
    return g(y);
}

int main(void)
{
    return f(2)+4;
}
保存后执行以下命令:

gcc -S -o main.s main.c -m32
其中gcc后面参数含义可以自行man以下,-S表示预处理后可直接对main.c文件编译生产汇编代码,如下所示:
shiyanlou:~/ $ cat main.s                                            [21:59:59]
	.file	"main.c"
	.text
	.globl	g
	.type	g, @function
g:
.LFB0:
	.cfi_startproc
	pushl	%ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	movl	%esp, %ebp
	.cfi_def_cfa_register 5
	movl	8(%ebp), %eax
	addl	$4, %eax
	popl	%ebp
	.cfi_restore 5
	.cfi_def_cfa 4, 4
	ret
	.cfi_endproc
.LFE0:
	.size	g, .-g
	.globl	f
	.type	f, @function
f:
.LFB1:
	.cfi_startproc
	pushl	%ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	movl	%esp, %ebp
	.cfi_def_cfa_register 5
	subl	$4, %esp
	movl	8(%ebp), %eax
	movl	%eax, (%esp)
	call	g
	leave
	.cfi_restore 5
	.cfi_def_cfa 4, 4
	ret
	.cfi_endproc
.LFE1:
	.size	f, .-f
	.globl	main
	.type	main, @function
main:
.LFB2:
	.cfi_startproc
	pushl	%ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	movl	%esp, %ebp
	.cfi_def_cfa_register 5
	subl	$4, %esp
	movl	$2, (%esp)
	call	f
	addl	$4, %eax
	leave
	.cfi_restore 5
	.cfi_def_cfa 4, 4
	ret
	.cfi_endproc
.LFE2:
	.size	main, .-main
	.ident	"GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
	.section	.note.GNU-stack,"",@progbits
二、实验结果分析:

以上汇编代码中,以点(.)开头的都是用于链接的辅助信息,这些信息是不会被执行的。因此以下分析下除去辅助信息之外的汇编指令:

g:
	pushl	%ebp
	movl	%esp, %ebp
	movl	8(%ebp), %eax
	addl	$4, %eax
	popl	%ebp
	ret
f:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$4, %esp
	movl	8(%ebp), %eax
	movl	%eax, (%esp)
	call	g
	leave
	ret
main:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$4, %esp
	movl	$2, (%esp)
	call	f
	addl	$4, %eax
	leave
	ret


程序从main函数开始,假设一开始是一个空栈,如下图所示(在32位环境中,int型数据占4个zi)


pushl	%ebp



movl	%esp, %ebp


subl	$4, %esp

movl	$2, (%esp)


call	f
call f 的操作其实就相当于pushl %eip;  movl * f, %eip; 从这步开始进入到f函数中的操作


pushl	%ebp


movl	%esp, %ebp


subl	$4, %esp

movl	8(%ebp), %eax
以上操作相当于 eax = *(int32_t *) (ebx+4),因此eax = 2

movl	%eax, (%esp)


	call	g

pushl	%ebp


movl	%esp, %ebp

·

movl	8(%ebp), %eax


addl	$4, %eax

popl	%ebp


ret
ret的操作就相当于pop eip(*),所以esp指针向上移一格,然后代码回到第15行的那条指令



leave
leave指令相当于movl %ebp,%esp; popl %ebp;

ret
回到第23行指令继续执行


addl	$4, %eax


leave
ret



执行完以上所有代码,我们可以看到堆栈又回到了最初的状态。

三、总结

通过以上逐条指令的分析来理解C语言函数的执行过程,能够加深我们对计算机C语言等高级语言的理解,同时对以后学习用户空间虚拟地址空间打下了基础。

四、实验截图




反汇编一个简单的C程序并分析

反汇编一个简单的C程序并分析C 源码:int g(int x) { return x+1; }int f(int x) { return g(x); }int main(void) {...
  • luoyhang003
  • luoyhang003
  • 2015年07月03日 22:23
  • 1040

通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的(原创)

首先编写c程序代码: main.c int g(int x) {   return x + 16; }   int f(int x) {   return g(x); }   int main(...
  • lvchaocccc
  • lvchaocccc
  • 2015年08月16日 22:30
  • 684

如何快速查看将C反汇编的代码

如何快速查看将C反汇编的代码 查看反汇编主要的思路在于将 流程,处理,算法 区分开来。 1 函数调用: 原C代码: int sum(int, int);int main...
  • cuijinquan
  • cuijinquan
  • 2014年01月17日 15:07
  • 977

反汇编一个简单的C程序

一、实验截图   二、汇编代码分析: cpu首先执行main函数里的pushl %ebp和movl %esp %ebp。如下图: esp减去4就是向上移动4位到1,如下图: ...
  • freemindh
  • freemindh
  • 2015年10月22日 16:24
  • 319

反汇编一个简单的C程序

#include int g(int x) { return x + 3; } int f(int x) { return g(x); } int main(void) { retu...
  • qq_26437925
  • qq_26437925
  • 2015年10月15日 09:02
  • 308

反汇编一个简单的C程序

反汇编一个简单的C程序 看了下网易云课堂的《Linux内核分析》,第一节要求有一个简单C程序得到汇编代码,然后分析。只要明确每个汇编指令代表的含义,就可以容易的走下去,关键是要体会里面的思想。 ...
  • vonzhoufz
  • vonzhoufz
  • 2015年04月13日 20:34
  • 1020

C语言 基础反汇编——for循环

for循环是各种编程语言中常用的语句;其基本的格式为: for (循环变量 ; bool 表达式; 操作) {      // TODO ... } 一般会需要一个循环变量,这个循环变量一...
  • u012842205
  • u012842205
  • 2015年05月07日 12:59
  • 969

一个简单函数的反汇编

void myfunction(int a,int b) {           int c=a+b; } (1)保存ebp。ebp总是被我们用来保存这个函数执行前的esp的值。执行完...
  • Zarathustra_Sun
  • Zarathustra_Sun
  • 2013年03月16日 16:20
  • 895

C语言反汇编入门实例

VS2013+WIN7+Debug --- g:\coding\poet\test\ctest.cpp ---------------------------------------------- #...
  • lgh1992314
  • lgh1992314
  • 2016年07月30日 21:55
  • 628

Linux下C程序的反汇编

Linux下C程序的反汇编前言:本文主要介绍几种反汇编的方法。gccgcc的完整编译过程大致为:预处理->编译->汇编->链接前三个步骤分别对应了-E、-S、-c三个选项。今天我要介绍的第一种方法就是...
  • u011192270
  • u011192270
  • 2015年12月08日 21:07
  • 5505
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:反汇编一个简单的C
举报原因:
原因补充:

(最多只允许输入30个字)