第三天
step4:去除标准库
现在已经不使用启动文件了,但是我们还在使用标准库,printf 和 _exit 函数都是标准库提供的。
可不可以不使用标准库?
当然也可以。
这里就要说到系统调用,用户程序和操作系统的交互通过一系列称为”系统调用“的过程来完成。
系统调用工作在最底层,通过约定的寄存器传递参数,然后使用一条特别的指令,比如 32 位 Linux 是 int 80h,64 位 Linux 是 syscall 进入系统调用,最后通过约定的寄存器获取结果。
现在如果我们不想使用标准库,那么就需要自己去完成系统调用,在 hello 程序中我们使用了两个系统调用:
write: 向终端打印字符实际上就是向终端对应的文件写入数据
exit: 退出程序
因为要访问寄存器,所以必须要使用内联汇编。
用readelf -S -W 读出的结果为:
Size 很小但是 Off 的值非常大,也就是说每个 Section 的体积很小,但是偏移量很大。
step5:自己写链接脚本
现在的链接脚本的偏移太大,是因为使用了对齐。
思路是:将几个段合并成一个段,并且抛弃一些段。
step6:将C文件改为汇编文件,然后使用step5中的链接脚本
ENTRY(_start)
SECTIONS
{
. = 0x8048000 + SIZEOF_HEADERS;
tiny : { *(.text) *(.data) *(.rodata*) }
/DISCARD/ : { *(.comment) }
}```
但在我用ld -T去指定链接脚本链接时,出现了bad-address的错误。
经过测试,发现将SIZEOF_HEADERS去除就可以正常运行了,但我不知道为什么。