不可否认,这次的标题有点长。之所以把标题写得这么详细,主要是为了搜索引擎能够准确地把确实需要了解GCC生成16位实模式代码方法的朋友带到我的博客。先说一下背景,编写能在x86实模式下运行的16位代码,这个话题确实有点复古,所以能找到的资料也相应较少。要运行x86实模式的程序,目前我知道的只有两种方式,一种是使用DOS系统,另一种是把它写成引导扇区的代码,在系统启动时直接运行。很显然,许多讲自己实现操作系统的书籍都会讲到x86实模式,也只有自己实现操作系统引导的朋友需要用到x86实模式,所以我这篇文章的阅读用户数肯定很少,虽然我自认为它填补了网上关于该话题相关资料缺乏的空白。因此,凡是逛到我这篇文章的朋友,请点一下推荐,谢谢。
为什么说我这篇博客填补了相关话题的空白呢?那是因为不管是那些写书的,还是网上写文章的,一旦需要编写16位的实模式代码,都喜欢拿NASM说事儿,一点也不顾GNU AS的感受。当然,这是有历史原因的,因为Linux自从其诞生起就是32位,就是多用户多任务操作系统,所以GCC和Gnu AS一移植到Linux上就是用来编写32位保护模式的代码的。而且,ELF可执行文件格式也只有ELF32和ELF64,没听说过有ELF16的。即使是Linux自己,刚诞生的时候(1991年),也只有使用as86汇编器来编写自己的16位启动代码,直到1995年以后,GNU AS才逐步加入编写16位代码的能力。
Linux升级GCC 4.8.1清晰简明教程(Ubuntu 12.04 64位版为例)
在CentOS 6.4中编译安装GCC 4.8.1 + GDB 7.6.1 + Eclipse 在CentOS 6.4中编译安装GCC 4.8.1 + GDB 7.6.1 + Eclipse
下面开始我的GCC和GNU Binutils的16位代码之旅。我决定使用DOS作为我的测试环境,所以最后生成的可执行文件都把它制作成DOS系统中可运行的Plain Binary格式。第一步安装一个qemu虚拟机来运行FreeDOS,安装虚拟机在Ubuntu中只需要一个sudo apt-get install qemu命令就可以完成,所以我就不截图了。但是FreeDOS的软盘映像文件需要到Qemu的官网上面去下载,下载地址如下图:
使用qemu-system-i386 -fda freedos.img可以运行Qemu虚拟机和FreeDOS系统,如下图:
因为汇编语言更接近底层,而C语言更高级,所以先从汇编语言开始,逐步过渡到C语言。先写一个简单的、能在DOS中显示一个“Hello,world!”的汇编语言程序,考虑到我之后会使用该程序调用C语言的main函数,并且该程序负责让程序运行结束后顺利返回DOS系统,所以我把这个程序命名为test_code16_startup.s。其代码如下: