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

一、反汇编C程序

首先编写一个简单的C语言程序,过程如图所示:

使用命令gcc -S -o 20222803.s 20222803.c -m32可以将C语言代码文件20222803.c反汇编出汇编语言代码文件20222803.s20222803.s内容如下:

	.file	"20222803.c"
	.text
	.globl	g
	.type	g, @function
g:
.LFB0:
	.cfi_startproc
	endbr32
	pushl	%ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	movl	%esp, %ebp
	.cfi_def_cfa_register 5
	call	__x86.get_pc_thunk.ax
	addl	$_GLOBAL_OFFSET_TABLE_, %eax
	movl	8(%ebp), %eax
	addl	$2803, %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
	endbr32
	pushl	%ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	movl	%esp, %ebp
	.cfi_def_cfa_register 5
	call	__x86.get_pc_thunk.ax
	addl	$_GLOBAL_OFFSET_TABLE_, %eax
	pushl	8(%ebp)
	call	g
	addl	$4, %esp
	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
	endbr32
	pushl	%ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	movl	%esp, %ebp
	.cfi_def_cfa_register 5
	call	__x86.get_pc_thunk.ax
	addl	$_GLOBAL_OFFSET_TABLE_, %eax
	pushl	$28
	call	f
	addl	$4, %esp
	addl	$3, %eax
	leave
	.cfi_restore 5
	.cfi_def_cfa 4, 4
	ret
	.cfi_endproc
.LFE2:
	.size	main, .-main
	.section	.text.__x86.get_pc_thunk.ax,"axG",@progbits,__x86.get_pc_thunk.ax,comdat
	.globl	__x86.get_pc_thunk.ax
	.hidden	__x86.get_pc_thunk.ax
	.type	__x86.get_pc_thunk.ax, @function
__x86.get_pc_thunk.ax:
.LFB3:
	.cfi_startproc
	movl	(%esp), %eax
	ret
	.cfi_endproc
.LFE3:
	.ident	"GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0"
	.section	.note.GNU-stack,"",@progbits
	.section	.note.gnu.property,"a"
	.align 4
	.long	 1f - 0f
	.long	 4f - 1f
	.long	 5
0:
	.string	 "GNU"
1:
	.align 4
	.long	 0xc0000002
	.long	 3f - 2f
2:
	.long	 0x3
3:
	.align 4
4:

在vim编辑器中,输入命令g/\.s*/d,删除所有以.打头的字符串,“美化”得到的汇编代码,如下所示:

g:
	endbr32
	pushl	%ebp
	movl	%esp, %ebp
	addl	$_GLOBAL_OFFSET_TABLE_, %eax
	movl	8(%ebp), %eax
	addl	$2803, %eax
	popl	%ebp
	ret
f:
	endbr32
	pushl	%ebp
	movl	%esp, %ebp
	addl	$_GLOBAL_OFFSET_TABLE_, %eax
	pushl	8(%ebp)
	call	g
	addl	$4, %esp
	leave
	ret
main:
	endbr32
	pushl	%ebp
	movl	%esp, %ebp
	addl	$_GLOBAL_OFFSET_TABLE_, %eax
	pushl	$28
	call	f
	addl	$4, %esp
	addl	$3, %eax
	leave
	ret
	movl	(%esp), %eax
	ret

二、汇编语言分析

main函数
代码片段含义
pushl %ebp将EBP寄存器的值也即栈底指针压栈
movl %esp, %ebp将ESP寄存器的值也即栈顶指针存入EBP寄存器
pushl $28将28压栈
call f调用f函数
addl $4, %espESP寄存器的值加4,指向调用f函数前的栈顶
addl $3, %eaxEAX寄存器的值加3,即2831+3=2834
leave撤销函数堆栈
ret返回更上层的堆栈
f函数
代码片段含义
pushl %ebp将EBP寄存器的值也即栈底指针压栈
movl %esp, %ebp将ESP寄存器的值也即栈顶指针存入EBP寄存器
pushl 8(%ebp)将EBP寄存器的值加8,指向之前压入栈的数28,然后将28压栈
call g调用g函数
addl $4, %espESP寄存器的值加4,指向调用g函数前的栈顶
leave撤销调用函数的堆栈
ret回退到f函数调用的代码处
g函数
代码片段含义
pushl %ebp将EBP寄存器的值也即栈底指针压栈
movl %esp, %ebp将ESP寄存器的值也即栈顶指针存入EBP寄存器
movl 8(%ebp), %eax将EBP寄存器的值加8,指向之前压入栈的数28,将28存入EAX寄存器
addl $2803, %eaxEAX寄存器的值加2803,即28+2803=2831
popl %ebp将栈顶数据存入EBP寄存器,也即调用g函数前的栈顶指针
ret回退到g函数调用的代码处

以上具体过程参考了完整汇编程序执行过程分析

遇到的问题

一、在虚拟机中反汇编失败,报错如图:

在这里插入图片描述
解决方法:是由于在64位系统上编译32位可执行程序缺少相应的32位库文件所致,在终端输入sudo apt-get install gcc-multilib之后解决。解决方法来自于“/usr/include/stdio.h:27:10: fatal error: bits/libc-header-start.h: No such file or directory 报错解决”

二、对pushl 8(%ebp)的理解错误

解决方法:仔细查阅《庖丁解牛Linux 分析 》第25页内容得到解决。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我们像只香芋942674

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值