assembly - 我的汇编程序中的段错误?但那是不可能的! :O

标签 assembly crash x86 nasm segmentation-fault

好的,所以我知道我们所有的 C/C++ 程序员都曾遇到过我们不合时宜的克星,恶魔般的信号 SIGSEGV,段错误。现在,我理解(强调过去时)这是某种形式的故障安全/检查系统,位于由神奇的 GCC(或 g++)编译器或您所拥有的机器代码的某些部分中。

但!今天,我在虚拟化的 Arch Linux 系统上使用了一些带有旧 NASM 的 x86 汇编器,令我惊讶和懊恼的是,恶意的 SegFault 再次阻碍了我的编码工作。

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

mov eax, 0x7
mov [0xB8000], eax

现在,我知道 Linux 内核将您组装的程序加载到一个 shell 中并从那里执行它,但我认为这个 MOV 指令与处理器进行了 1 对 1 的交互,内核怎么能检测到我正在尝试访问一个它不希望我使用一点内存并停止指令?

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

最佳答案

Linux 执行你的程序正在运行 user-mode ( ring 3x86 上)。此外,它使用 page-based memory protection限制程序可以访问的内存位置。特别是,您的程序尝试写入 0xB8000 (VGA 帧缓冲区),它无权修改。处理器的 MMU检测到这一点,并抛出 CPU exception . Linux 内核处理此异常,并将其转换为 segment violation signal .假设您尚未为信号设置自定义处理程序,内核将终止您的进程。为了避免这种情况并获得对硬件的完全访问权限,您需要编写一个 Linux 设备驱动程序,该驱动程序将在内核模式(x86 上的 ring 0)下以完全权限运行,或者通过 writing your own operating system 完全绕过 Linux。 .

关于assembly - 我的汇编程序中的段错误?但那是不可能的! :O,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3402324/

相关文章:

winapi - 如何在 MASM 中为一个项目编写和组合多个源文件?

c - 汇编和调用栈

arrays - 如何在ARM汇编中正确创建数组?

objective-c - Xcode 在设备上运行之前立即崩溃

c - raw bin 到 coff 的转换

Java程序在覆盖现有的.txt文件时崩溃?

android - OnTouch适用于1个按钮,但不适用于3个按钮

c - printf 似乎在永远循环之前工作不同

c++ - 内联 gcc 汇编和局部变量( double )

c - 弹出 x86 堆栈以访问函数 arg 时出现段错误