Linux下调用INT 0x10中断触发Segmentation fault的原因
段错误根本原因
你写的是16位x86实模式的裸机代码,但是编译链接出来的是跑在64位Linux用户态的ELF程序,运行环境完全不匹配,触发段错误是必然结果,具体原因如下:
int 0x10是BIOS提供的实模式中断服务,仅在CPU处于16位实模式、操作系统尚未启动的阶段可用,这时候的中断向量表由BIOS初始化填充。你的Ubuntu运行在64位长模式下,CPU启动过程中早就从实模式切到保护模式再进入长模式,实模式的中断向量表已经被废弃,内核维护的中断描述符表不允许用户态调用0x10号中断,执行这条指令会直接触发通用保护异常,内核就会给进程下发SIGSEGV信号,也就是你看到的段错误。- 你用
nasm -f elf64生成64位目标文件、再用ld链接出的是标准Linux用户态程序,这类程序运行在操作系统做的隔离环境里,根本没有权限直接访问BIOS、硬件IO这类底层资源,所有输入输出操作必须走内核提供的系统调用接口,不可能直接调用实模式的BIOS中断。 - 就算前面的中断调用不报错,你代码末尾的
jmp $是无限死循环,也不符合Linux程序的运行规范:正常Linux程序跑完逻辑必须调用exit系统调用把控制权还给内核,直接写死循环会占满CPU核心,永远不会正常退出。
如果要跑这段打印'H'的代码,不能直接编译成Linux可执行文件在系统里跑,得把代码编译成16位纯二进制格式,写到引导扇区镜像里,用QEMU这类虚拟机从镜像直接启动,让CPU在实模式下直接执行你的代码,才能正常触发int 0x10在屏幕上打出字符。
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

