目录
一、反汇编实验
二、分析计算机工作过程
三、实验中存在的问题
四、计算机是如何工作的
五、《庖丁解牛》第一章
一、反汇编实验
编写main.c文件。
用“gcc -S -o main.s main.c -m32”命令编译成汇编代码。
得到main.s,将main.s中的“.”删除后可得到汇编语言。
将main.s中的“.”删除后可得到汇编语言。
二、分析计算机工作过程
由上述试验可得一C语言文件和其在计算机中运行时的汇编语言文件,探究两者之间的对应关系即可分析出C语言这种高级语言在计算机中的工作过程。
分析汇编语言
file "main.c" //读文件 text globl g type g, @function g: .LFB0: cfi_startproc //定义函数栈 endbr32 //具体好像没啥用?用于验证目标地址是期望的跳转目标? pushl %ebp //pushl就是压栈long,%ebp为ebp寄存器 cfi_def_cfa_offset 8 //没怎么看懂,附解释链接:https://www.it1352.com/297897.html cfi_offset 5, -8 //寄存器的上一个值5保存在CFA的偏移量-8处 movl %esp, %ebp //把32位的esp寄存器值传送给32位的ebp寄存器值 cfi_def_cfa_register 5 //修改计算CFA的规则。从现在起,将使用寄存器代替旧的寄存器。偏移量保持不变。链接:https://blog.csdn.net/jtli_embeddedcv/article/details/9321235 call __x86.get_pc_thunk.ax //调用函数,函数将%eip的位置加载到%eax寄存器 addl $_GLOBAL_OFFSET_TABLE_, %eax //两者相加,得数储存在%eax中($_GLOBAL_OFFSET_TABLE_是全局偏移表) movl 8(%ebp), %eax //把32位的ebp寄存器值+8传送给32为的eax寄存器值 addl $20212801, %eax %eax中值+20212801 popl %ebp //ebp寄存器出栈 cfi_restore 5 //ebp寄存器恢复初始值 cfi_def_cfa 4, 4 //cfa的计算方式应该是esp+4? ret //从堆栈中退出pc的高8位和低8位字节,把堆栈指针减2,从pc值处开始继续执行程序 cfi_endproc //定义函数结束 .LFE0: size g, .-g globl f type f, @function f: .LFB1: cfi_startproc //同函数g中同语句 endbr32 //同函数g中同语句 pushl %ebp //同函数g中同语句 cfi_def_cfa_offset 8 //同函数g中同语句 cfi_offset 5, -8 //同函数g中同语句 movl %esp, %ebp //把32位的esp寄存器值传送给32为的ebp寄存器值 cfi_def_cfa_register 5 //同函数g中同语句 call __x86.get_pc_thunk.ax //同函数g中同语句 addl $_GLOBAL_OFFSET_TABLE_, %eax //同函数g中同语句 pushl 8(%ebp) //将ebp寄存器值+8压入栈中 call g //调用g程序 addl $4, %esp //4与esp值相加,存入esp寄存器 leave cfi_restore 5 //同函数g中同语句 cfi_def_cfa 4, 4 //同函数g中同语句 ret //同函数g中同语句 cfi_endproc //同函数g中同语句 .LFE1: size f, .-f globl main type main, @function main: .LFB2: cfi_startproc //同函数g中同语句 endbr32 //同函数g中同语句 pushl %ebp //同函数g中同语句 cfi_def_cfa_offset 8 //同函数g中同语句 cfi_offset 5, -8 //同函数g中同语句 movl %esp, %ebp //同函数g中同语句 cfi_def_cfa_register 5 //同函数g中同语句 call __x86.get_pc_thunk.ax //同函数g中同语句 addl $_GLOBAL_OFFSET_TABLE_, %eax //同函数g中同语句 pushl $2021 //2021压入栈中 call f //调用f函数 addl $4, %esp //4+esp->esp addl $2801, %eax //2801+eax->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.3.0-17ubuntu1~20.04) 9.3.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:
从汇编代码中可以看出,代码明显被分成了三个部分,分别是自定义函数g、自定义函数f,主函数main。汇编代码通过调用各个寄存器以及对各个寄存器中的值进行操作,最终完成程序的执行。
三、实验中存在的问题
1.汇编代码大体看懂了,但还有部分指令没有弄清楚,例如endbr32、cfi_def_cfa_offset等。
解决:认真研究在注释中记下的网页。
2.汇编代码中的addl、movl与之前学的add、mov不一样。
解决:基本一样,强调是32位的。
四、计算机是如何工作的
计算机一般按照顺序读取输入计算机的指令,此外还可以通过call、ret等指令跳转执行其他指令。计算机在执行程序时通过操作临时栈和寄存器来对数据或地址进行处理。
五、《庖丁解牛》第一章
储存程序计算机工作模型
x86-32CPU寄存器
以上图原文链接为:
冯·诺伊曼模型_djh624的博客-CSDN博客_冯诺依曼模型
x86_32的寄存器 - LeonOne的个人空间 - OSCHINA - 中文开源技术交流社区



