南京大学操作系统¶
Abstract
jyy os
Info
绪论¶
Lec0 操作系统上的程序¶
- 如何构建最小的
hello world
:如果采用-static
会复制 libc,那么如果采用gcc -c
和ld
链接会失败,下面是gcc -c
产生的elf
文件的汇编代码
¶
直接采用ld
链接,会发现os上的程序需要libc中的==_start()函数==调用main函数,所以尝试直接将函数声明为_start()
并且去除printf
对puts
的调用,因为没有库函数定义puts
然后发生了segmentation fault
,但是将_start()
的函数体改为while(1)
就能消除bug
原因
使用GDB
查看哪条指令导致了段错误:发现是ret
指令导致,ret指令的语义是就是将栈顶存储的ra
赋值给pc
,然后出栈,即stack[rsp] -> rip; rsp = rsp + 8
;出错的原因可能是rsp
指向的堆栈区不合法,查看后排除,但是发现rip
的值会被赋值为1,地址为0x1
的内存不能被访问,导致段错误,所以解决方法就是死循环不返回。
发现
纯粹的计算指令无法让状态机顺利结束,需要调用syscall
让系统停下来;由下面的代码发现,syscall
在执行前需要根据手册对对应的寄存器赋值,即准备好需要的系统调用参数,把控制权交给操作系统,但是syscall
的实现在libc
中,不方便直接链接。所以最小的hello world
就是模仿syscall
,自己实现libc
。
最小的hello,world实现如下:
坑点
注意这个文件为hello.S
,后缀为大写的S,然后使用gcc -c hello.S && ld hello.o
生成可执行文件