2022-2023-1 20222810《Linux内核原理与分析》第二周作业

实验一:反汇编一个简单的C程序

一、实验步骤

1.打开“Xfce终端”Shell控制台程序,输入ls命令即可看到目录“LinuxKernel”和“Code”,此时看到Code目录下是空的。

2.在Shell命令行下我们常用的文本编辑器是VIM,在命令行下输入“vi.20222810.c”命令即可打开文本编辑器VIM编辑main.c文件。(编写完成后,按esc,输入“:wq”后退出)。

3.编译main.c这个代码文件。直接编译可以使用如下命令:

gcc 20222810.c

4.接着会生成一个目标文件a.out,它是可以执行的,但执行效果没有任何输出信息。可以通过如下命令查看一下这个程序的返回值。

echo $?

 操作如下:

 可以看到,程序的返回值为28。

5.把20222810.c编译成一个汇编代码,使用如下命令:

gcc -S -o 20222810.s 20222810.c -m32

6.打开20222810.s,会发现这个文件是20222810.c生成的,但是20222810.s汇编文件还有一些“.cfi_”打头的字符串等等。这样的代码读起来不是很方便。这时候需要简化一下代码,在VIM中,通过“g/\.s*/d”命令可以获得“干净”的汇编代码。

效果如下:

  

 

 二、分析汇编代码

1.main函数分析如下:

上述代码对应3个函数,main函数,f函数和g函数。

pushl %ebp

是开始执行的第一条指令。作用:把EBP寄存器的值压栈。

movl %esp,%ebp 

将EBP寄存器也指向标号1的位置。

subl $4,%esp 

将ESP寄存器向下移动一个标号。

movl $4,(%esp) 

把立即数4放入ESP寄存器指向的标号2位置。

call f 

EIP寄存器指向f函数。

addl $14,%eax 

 把EAX寄存器加立即数14.

leave

撤销函数main的堆栈,把EBP和ESP寄存器都指向栈空间标号1的位置。 

 ret

函数返回。 

2.f函数分析如下:

pushl %ebp 

EBP寄存器的值标号1 放到栈空间标号4的位置。

movl %esp,%ebp 

让EBP寄存器也指向栈空间标号为4的位置。

subl $4,%esp 

 ESP寄存器减4,指向标号为5的位置。

movl 8(%ebp),%eax

EBP寄存器加8.

movl %eax,(%esp) 

把EAX寄存器中存储的立即数放到ESP寄存器现在所指的位置。

call g 

调用g函数 

leave和ret如上。

3.g函数分析如下:

pushl %ebp

 把EBP寄存器存储的标号4压栈。

movl %esp,%ebp

让EBP寄存器指向堆栈空间标号为7的位置。

movl 8(%ebp),%eax 

在当前EBP寄存器指向的栈空间标号7的位置基础上向上移动两个存储单元指向5,然后把标号5的内容放到EAX寄存器中。

addl $10,%eax 

把立即数10加到EAX寄存器里。

popl %ebp 

把标号7的内容放回EBP寄存器。

三、 小结

1.分析栈时,应该要注意,call f指令相当于以下两条伪指令:

pushl %eip(*)

movl f %eip(*)

这实际上是把EIP寄存器的值(行号为23的指令地址)放到了栈空间标号3的位置,同时因为压栈前 ESP寄存器的值为标号2,压栈时ESP寄存器先指向下一个位置标号3,然后将EIP寄存器的行号23入栈到栈空间标号3的位置。

2.pushl也相当于两个动作。如:

pushl %eax相当于:

subl $4,%esp

movl %eax,(%esp)

先把堆栈的栈顶ESP寄存器的值减4,,再把EAX寄存器的值放到ESP寄存器指向的地方。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值