[OS64位][019]源码阅读:程序4-5 i=1/0 除法错误

学习笔记

使用教材(配书源码以及使用方法)
《一个64位操作系统的设计与实现》
http://www.ituring.com.cn/book/2450
https://www.jianshu.com/p/28f9713a9171

源码结构

  • 配书代码包 :第4章 \ 程序 \ 程序4-5

运行调试

10191360-360fc22fee51b5c6.png
程序 4-5 运行结果 除法错误 在屏幕上显示黑底红字的 do_divide_error(0), ERROR_CODE: ,RSP: ,RIP:
[anno@localhost bootloader]$ make
nasm boot.asm -o boot.bin
nasm loader.asm -o loader.bin

[anno@localhost kernel]$ make
gcc -E  head.S > head.s
as --64 -o head.o head.s
gcc -E  entry.S > entry.s
as --64 -o entry.o entry.s
gcc  -mcmodel=large -fno-builtin -m64 -c main.c
main.c: In function ‘Start_Kernel’:
main.c:79: warning: division by zero
gcc  -mcmodel=large -fno-builtin -m64 -c printk.c
gcc  -mcmodel=large -fno-builtin -m64 -c trap.c
ld -b elf64-x86-64 -z muldefs -o system head.o entry.o main.o printk.o trap.o -T Kernel.lds 
objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O binary system kernel.bin

[anno@localhost 4-5]$ ls
bochsrc  boot.img  bootloader  kernel  media

[anno@localhost 4-5]$ sudo mount boot.img media -t vfat -o loop
[anno@localhost 4-5]$ sudo cp bootloader/loader.bin media
[anno@localhost 4-5]$ sync
[anno@localhost 4-5]$ sudo cp bootloader/boot.bin media
[anno@localhost 4-5]$ sync
[anno@localhost 4-5]$ sudo cp kernel/kernel.bin media
[anno@localhost 4-5]$ sync

[anno@localhost 4-5]$ bochs -f ./bochsrc

源码解析

i=1/0 除法错误 调用关系

10191360-2a060ad5b6292ef5.png
程序 4-5 调用关系图.png
  • leaq do_divide_error(%rip), %rax [ (enrry.S)] 说明栈中FUNC的位置填入的是函数do_divide_error的绝对地址

  • 通过寄存器向函数do_divide_error传递参数,RDI=RSP、RSI=错误码

10191360-e8560960427b8570.png
程序4-5 异常处理程序 压栈操作.png
  • 无特权级切换时,不会压入 OLDRSP OLDSS

_set_gate 格式化IDT描述符并填入IDT表

10191360-a75d3fdb5dad24cd.png
格式化 IDT内的表项 函数调用关系
10191360-138276610e6a2975.png
程序4-5 初始化IDT表项 并填入IDT表.png

参考资料

  • 内联汇编

[内联汇编]扩展asm:格式、占位符、跳转、内联汇编宏函数
https://www.jianshu.com/p/76fda24ee7f7

  • 格式化IDT表项的方法

[OS64位][019]源码阅读:程序4-4 异常/中断(一)显示"Unknown interrupt or fault at RIP\n"
https://www.jianshu.com/p/639656438573

猜你喜欢

转载自blog.csdn.net/weixin_34150503/article/details/90968822