2019-2020-1 20209324《Linux内核原理与分析》第二周作业

1.为什么pushl会使得esp-4?

回答:

pushl是使得栈顶指针进行压栈,由于是l,所以压栈的大小为四个字节32位,pushl指令的具体运行过程是,将pushl指令所带的参数放至ESP的位置上,再将esp-4来完成压栈的操作。

2.为什么会ret跳转到call的下一条指令?

回答:

call指令将EIP的值存入ESP,当ret的时候重新获得原来EIP的值,然后再进行下一条指令时,发生EIP+4,所以就指向了call指令的下一条指令。

3.在使用makefile的过程中,修改了头文件的名字以及代码中与相关的名字,makefile搜索不到头文件

回答:

同时要完成对c文件中对头文件的修改,不然.c文件搜索不到头文件。

4.附带完成本周实验的实验报告

回答:

1.本次实验所选用的C语言代码

// main.c
int g(int x)
{
    return x + 3;
}

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

int main(void)
{
    return f(8) + 1;
}

2.所编译出的汇编代码以及解释

g:
	pushl	%ebp          "压栈,ESP->7,在7号位置中存入EBP的值(4号位置的地址)"
	movl	%esp, %ebp    "EBP指向7号地址,栈不变"
	movl	8(%ebp), %eax "[EBP]+8:EBP指向7号位置,加8后指向5号位置,即把5号位置中存的立即数4取出存入EAX"
	addl	$5, %eax      "[EAX]=[EAX]+5,新[EAX]=9"
	popl	%ebp          "EBP重新指向4的位置,ESP->6"
	ret                   "RET的含义为POP %EIP,所以EIP的值为6号位置的值,即指向call指令的下一条指令,ESP->5,跳转到call的下一条指令"
f:
	pushl	%ebp          "ESP指向4的位置,在4号位置中存入ebp的值(1号位置的地址)"
	movl	%esp, %ebp    "EBP指向4号位置,栈不变"
	subl	$4, %esp      "ESP指向5"
	movl	8(%ebp), %eax "[EBP]+8:EBP指向4号位置,加8后指向2号位置,即把2号位置中存的立即数4取出存入EAX"
	movl	%eax, (%esp)  "把4存入ESP所指向的5号单元"
	call	g             "先压栈,esp->6,原EIP的值赋给6号地址,新EIP为g的地址,跳转到g继续执行"
	leave                 "leave的意思为:movl %ebp,%esp;pop %ebp;即ESP->4,然后把4号位置的值(1号位置的地址)赋给EBP,再ESP->3"
	ret                   "把ESP指向的3号位置的值(f的地址)存入EIP,ESP->2,然后跳转到call的下一条指令"
main:
	pushl	%ebp          "EBP指向0号位置,而esp指向1号位置,把EBP存入1号位置"
	movl	%esp, %ebp    "EBP指向1号位置。栈不变。"
	subl	$4, %esp      "ESP指向2号位置"
	movl	$4, (%esp)    "在ESP所指向的2号位置存一个立即数4"
	call	f             "call指令的意思为push %eip+mov f %eip,所以指令运行过程为,先压栈,ESP->3,3号地址中存入原EIP的值,给EIP赋f的地址,跳转到f继续执行"
	addl	$2, %eax      "[EAX]=[EAX]+2"
	leave                 "ESP->1,EBP->0,ESP->0"
	ret                   "return到main函数之前的堆栈,跟当前的没关系"
posted @ 2020-10-17 15:35  20209324  阅读(136)  评论(0编辑  收藏  举报