我的汇编器中存在SegFaults?但这是不可能的!:O

N8-*_*bit 4 crash x86 assembly nasm segmentation-fault

好的,所以我了解我们所有的C / C ++程序员一次都遇到了我们的过时克星,即恶魔般的信号SIGSEGV,细分错误。现在,我明白了(强调过去时),它是某种形式的故障安全/检查系统,该系统在神奇的GCC(或g ++)编译器吐出的机器代码的某些部分内,或者您拥有什么。

但!今天,我在一个虚拟的Arch Linux系统上安装了一些带有旧式NASM的x86汇编器,这让我感到惊讶和恼火,这再次使我讨厌的SegFault阻碍了我的编码工作。

这是产生可怕信号的代码:

mov eax, 0x7
mov [0xB8000], eax
Run Code Online (Sandbox Code Playgroud)

现在,我知道Linux内核将您的汇编程序加载到Shell中并从那里执行它,但是我认为该MOV指令与处理器进行了1对1的交互,内核如何才能在内核上检测到我正在尝试访问一点内存,它不想要我,并暂停指令?

我不假装理解将程序加载到shell中时到底会发生什么,在shell中曾经拥有什么权限,甚至是shell是什么或它如何工作,但是我曾经很确定ASM给了您完全控制处理器。这个神奇的内核如何干扰我对处理器的直接命令,为什么在本质上是编写纯机器代码时,我仍然被迫浏览操作系统命令链?:O

bca*_*cat 5

Linux执行的程序正在用户模式下运行x86上的ring 3)。此外,它使用基于页面的内存保护来限制程序可以访问的内存位置。特别是,您的程序尝试写入(VGA帧缓冲区),但没有修改权限。处理器的MMU检测到此情况,并引发CPU异常。Linux内核处理此异常,并将其转换为段违规信号 0xB8000。假设您尚未为信号设置自定义处理程序,则内核将终止您的进程。为避免这种情况并获得对硬件的完全访问权限,您将需要编写一个具有完全许可权的内核设备(在x86上为0环)运行的Linux设备驱动程序,或者通过编写自己的操作系统来完全绕开Linux 。