记录x86汇编的学习
瞎写
现在都快两点了,不怎么困…
今天也是摸鱼的一天…
其实还是有些收获的,至少怎么写链接脚本,怎么写MBR扇区的代码,还算是了解了一点点。(并没有学习x86汇编)
总结一下吧。
总结
东西很杂,就随便记录一下
i386 裸机环境搭建
1. 编译 binutils
2. 编译 gcc
binutils 和 gcc 的源码可以去清华[1]或者科大的镜像站上面找,编译主要就是下面这几句:
1 | Varibale Settings |
上面的内容是经过简化的,没把
make
sudo make install
写在里面,配置选项也很简单。
具体内容可以在 OSDev Wiki [2]上面找到,我就不写(抄)了。
关于x86汇编的“方言”
其实是两种语法(syntax):
AT&A 和 Intel
我是最近刚看的《汇编语言》第三版,上面讲的是 Intel 语法,而我打算用GAS来做汇编器,GAS默认使用 AT&T 语法,这让我刚开始很困扰。不过后来我发现可以用一些编译指令[3]来使用 Intel 语法。这也不算个问题了。
关于链接脚本
如何把MagicNumber放到最后面就是用的链接脚本。链接脚本指导连接器如何从对象文件里面获取所需要的内容,如何将这些内容在输出的文件中进行布局。具体参考官方手册[4]。
MBR引导代码
大概半年前我才装上Ununtu真机。以前都是用虚拟机。装的时候搞出了点事情,发现我自己用的不是UEFI启动。用的还是Legacy BIOS。然后我就重新建立ESP分区,把Win10和Ubuntu的引导扔进去,加上GRUB。其实这里面的东西也能写一篇博客,因为遇到的问题还是挺多的。
MBR 是给 Legacy BIOS用的。存储设备的第一个扇区(Sector)的最后两个字节是0x55和0xaa,就会被BIOS当成一个可以启动的设备,BIOS将其512KiB加载到 0x0000:0x7c00 然后从这里开始运行。所以关键就是用链接脚本把 magic number 放到最后面,.text 放到最前面就好了。
给一个简单的小例子:
1 | SECTIONS |
链接的结果是生成ELF文件,用objcopy把没用的ELF头和符号表给去掉,生成Binary文件。这时候就可以尝试用Qemu来模拟了。
Reference
- 清华大学开源软件镜像站, “Index of /gnu/“, https://mirrors.tuna.tsinghua.edu.cn/gnu/
- OSDev-Wiki, “GCC Cross-Compiler”, https://wiki.osdev.org/GCC_Cross-Compiler
- Stackoverflow, “Can I use Intel syntax of x86 assembly with GCC?”, https://stackoverflow.com/questions/9347909/can-i-use-intel-syntax-of-x86-assembly-with-gcc
- Sourceware, “ld-docs”, https://sourceware.org/binutils/docs/ld/index.html