前情提要
本人目前大四,保研本校。本想着暑假找个实习,正巧BOSS直聘上有一位前辈问我有没有意愿尝试一下测试开发岗位(基础架构部门)。可能是我没有表达清楚,结果前辈帮我投的是校招/(ㄒoㄒ)/~~(还是怪我没有说清楚。。。不过我跟hr说我想投的是暑假实习岗,他说我可以跟面试官商量,先面面看。。。)
本文是我在大二的时候学习王爽老师的《汇编语言》所记录的笔记,里面包含我对每章的总结以及思考,最后还有一篇“读后感”总结全书。
作为一名小白,在WSL中做一个操作系统小实验的时候,需要查看编译后代码的汇编实现,于是使用objdump
工具直接反汇编。发现跟以前学过的汇编有些不一样(学过8086汇编),上网查询Intel x86汇编的格式(因为我的机器是Intel的CPU),发现得到的汇编格式于Intel标准的汇编格式有些不一样,如下(部分):
在讲装载之前,我们首先要了解程序和进程的区别,我用一种不严谨的说法来一句话解释:硬盘中的程序被装载到内存中就变成了进程。
程序(狭义上是可执行文件)是一个静态概念,它是一些预先编译好的指令和数据的集合的一个文件;进程则是一个动态的概念,它是程序运行时的一个过程,或者讲,一个正在运行的程序。很多时候把动态库叫做运行时(Runtime)就有这种含义。
有一个很形象的比喻就是,程序是一个大厨做菜时的菜谱,计算机的CPU相当于这个大厨,相关的厨具就是计算机的其他硬件,整个做菜的过程就是一个进程。
所谓装载,就是把存储在硬盘等介质内的程序(指令和数据),加载到内存中的某个位置,然后才能由CPU执行。这是由传统的冯·诺伊曼结构的所决定的(学过计组的都懂)。
Windows下的可执行文件格式为PE(Portable Executable),与ELF格式同根同源,都是COFF(Common Object File Format)格式的一种扩展。所以它们之间基本结构相同,下文主要说明它两之间的差异。
我们可以用dumpbin查看obj文件的信息,输入/ALL
参数可以查看所有相关信息:
dumpbin /ALL SimpleSection.obj > SimpleSection.txt
所谓静态链接,就是在链接阶段把所有参与链接的目标文件合并到一个最终的可执行文件中。有静态就有动态,后面会讲的动态链接就是链接过程中只是指明了主程序在运行时需要哪些动态链接库(模块),最终链接得到的可执行文件并没有包含所有模块的代码,而是在运行过程中会动态地加载那些模块。
目标文件就是源代码经过编译后的,链接之前的文件,经过链接就变成了可执行文件,它也是一种二进制文件。
目标文件的格式其实与最终的可执行文件的格式是一致的,只是没有经过符号的链接过程。
在Windows环境下,可执行文件的格式是PE(Portable Executable),在Linux环境下,可执行文件的格式叫ELF(Executable Linkable Format),这两种格式差别不大,都是源自于COFF(Common File Format)格式的。
更新:问题已解决,详见一个神奇的C语言程序 - 知乎 (zhihu.com)评论区大佬。(果然还是太菜了……
写代码时为了节省空间,就是用了uint8_t,然后发现一个很神奇的现象,程序很简单,但是现象很神奇: