“mov ds,ax”在Visual Studio中显示0xC0000005错误

时间:2016-11-22 15:44:47

标签: c visual-studio assembly

我正在使用Visual Studio构建一个控制台程序,我在这个C程序中使用了内联汇编指令,如图所示:code and error message。 对于那些看不到图片的人,我写的代码是:

void main() {
    __asm {
        mov ax, 0x4;
        mov ds, ax; // 0xC0000005 error occurs while executing this instruction
        xor eax, eax;
    }
}

如您所见,我想为DS段寄存器分配一个值,并且我使用AX将值传送到DS寄存器(所以我不直接将值赋给DS寄存器)

编译和链接都可以,但是当我调试这个程序时,我得到错误代码:0xC0000005。在没有调试的情况下运行会导致同样的错误。

我正在使用Visual Studio的中文版,我不确定这个错误消息的确切翻译是什么,但它的粗略含义是: “在0x008e13c2处有一个未处理的异常:0xC0000005:读取0xffffffff时发生访问冲突。

Q1:有人知道为什么会这样吗?我不能将随机值分配给DS寄存器吗?

顺便说一下,另一个问题是,当我将数字0到3分配给DS寄存器时,没有发生错误,但Visual Studio左下角的寄存器窗口显示 DS寄存器的值没有'已被更改

Q2:为什么会这样?我是否已成功将值分配给DS寄存器?

任何帮助都会感激不尽。

1 个答案:

答案 0 :(得分:4)

Visual Studio在Windows下运行,Windows将CPU切换为protected mode (PM) 在PM中,您不能再为选择器寄存器(如ds)分配任何所需的值,而是操作系统会为您加载这些寄存器。

假设操作系统在这方面没有缺陷,并且Windows不是,则任何其他值 1 (但对于其他选择器寄存器上的那些)将触发异常。

如果你看过像

这样的代码
mov ax, cs
mov ds, ax

mov ax, 0b800h
mov es, ax

mov ax, ...
mov ds, ax

然后是real mode代码,不再适合在Windows下运行 2
您可能需要考虑使用DOS模拟器(如DOSBox)和可生成16位可执行文件的汇编程序/编译器(如NASMMASMTASM或Turbo C )。

值00h - 03h在这方面很特殊,因为它们都代表 NULL选择器

  

可以将NULL段选择器(值0000-0003)加载到DS,ES,FS和GS寄存器中而不会导致   保护例外。但是,任何后续尝试引用其相应段的段   register加载NULL值会导致一般保护异常(#GP)并且不会发生内存引用。

值04h没有引用NULL描述符,一旦你尝试用ds设置它就会引发异常。

1 实际上,OS可以创建用户空间程序可访问的其他描述符,但假设它们的使用将等同于寄存器中已存在的描述符。因此,改变这些是没有意义的。

2 实际上,32位版本的Windows支持16位程序,但是,自Vista以来,64位版本不支持。 Visual Studio无法生成MZ exes,根据@RossRidge注释,您需要Visual C ++ 1.5或之前的版本。