Assembly 我的汇编程序中的错误?但那';这是不可能的O

Assembly 我的汇编程序中的错误?但那';这是不可能的O,assembly,crash,x86,nasm,segmentation-fault,Assembly,Crash,X86,Nasm,Segmentation Fault,好的,我知道我们所有的C/C++程序员都曾经遇到过我们不合时宜的敌人,恶魔信号SIGSEGV,分割错误。现在,我明白了(强调过去式)这是某种形式的故障保护/检查系统,在神奇的GCC(或g++)编译器或您所拥有的机器代码的某些部分中 但是!今天我在一个虚拟化的Arch Linux系统上用一个很好的旧NASM和一个x86汇编程序混在一起,让我感到惊讶和懊恼的是,我的编码工作又一次被邪恶的SegFault阻挠了 以下是产生可怕信号的代码: mov eax, 0x7 mov [0xB8000], eax

好的,我知道我们所有的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

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

如果您想要“完全控制处理器”,您需要在较低的级别编写代码(如果您希望操作系统保持运行,则在内核中编写代码;如果您希望自己处理从引导到启动的所有事情,则在自己的操作系统或执行器中编写代码)


编写汇编程序与编写C程序没有什么不同,只是您可能会生成一些C编译器不会发出的奇怪指令。仅根据编写程序所用的语言,不授予程序任何特殊权限或能力。

Linux执行您的程序正在运行(on)。此外,它还用于限制程序可以访问的内存位置。特别是,您的程序试图写入它无权修改的
0xB8000
(VGA帧缓冲区)。处理器的处理器检测到这一点,并抛出一个。Linux内核处理此异常,并将其转换为一个异常。假设您没有为信号设置自定义处理程序,那么内核会终止您的进程。为了避免这种情况并获得对硬件的完全访问权,您需要编写一个Linux设备驱动程序,该驱动程序将以内核模式(x86上的环0)运行并具有完全权限,或者完全绕过Linux。

您没有与处理器进行1对1的交互。内存保护存在于硬件级别。哎哟!欢迎来到全新的复杂程度:)嗯,你的解释和对MMU的快速维基百科搜索非常有启发性,我太习惯于为z80和6502处理器进行组装,用于娱乐,我从来不知道存在单独的单元来处理内存和保护内存。我对内存映射I/O有一些模糊的了解(如果这是相关的话),但在今天的系统中,在硬件中实现内存管理之类的东西真的很有趣。@N8位,内存映射I/O也是一些硬件魔法,但它不一定与MMU相关。MMU不再像20-30年前那样是单独的单元。它们现在被集成到CPU中,就像浮点单元一样。@Gabe是非常正确的;一般来说,所有这些部分都在同一个软件包中,但它们的设置和交互方式往往有其作为外部部分起源的迹象。是的,谢谢,写信给该地址的整个想法是以与rogue相同的方式制作一款基于文本的口袋妖怪式冒险游戏的开始,除了字符的单独空格,其功能类似于屏幕上的彩色像素。我非常感谢你们花时间向我解释这件事。