我的汇编程序中的SegFaults?但那是不可能的! :o

时间:2010-08-04 03:15:10

标签: 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

2 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:3)

MMU保护了您尝试访问的内存,因此当您执行违反某些权限的指令时,会生成中断/处理器异常。该异常由内核处理并作为分段故障信号转发到您的应用程序。由于您的应用程序不处理SIGSEGV,它将被终止,并且控制权将返回给您的shell。

如果您想要“完全控制处理器”,那么您需要在较低级别编写代码(如果您希望保持操作系统运行,则需要在内核中编写代码,或者您自己的操作系统或执行程序)如果你想自己开机处理所有事情。)

编写汇编程序与编写C程序没什么不同,除了你可以生成C编译器不会发出的一些奇怪的指令。根据编写语言的语言,没有授予程序的特殊权限或能力。