【问题标题】:"mov ds, ax" shows 0xC0000005 error in Visual Studio"mov ds, ax" 在 Visual Studio 中显示 0xC0000005 错误
【发布时间】:2017-04-06 09:04:17
【问题描述】:

我正在使用 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 寄存器) .

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

我用的是中文版的Visual Studio,我不知道这个错误信息的确切翻译是什么,但粗略的意思应该是: "0x008e13c2 处有一个未处理的异常:0xC0000005:读取 0xffffffff 时发生访问冲突。"

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

对了,还有一个问题,当我给DS寄存器赋值0到3的时候,没有出现错误,但是Visual Studio左下角的寄存器窗口显示DS寄存器的值没有'没有改变

Q2:为什么会这样?我是否成功地为 DS 寄存器赋值?

任何帮助将不胜感激。

【问题讨论】:

  • 因为编译器生成的代码可能是使用ds 做别的事情?如果您想进行 DOS 级编程,请使用以 DOS 为目标的实际汇编程序,并使用仿真环境来运行程序。
  • 04h 不是一个有效的选择器,因为它索引 LDT 中的描述符 0 且 RPL = 0(您不能使用 CPL = 3 并且保留空描述符)
  • 您不能随意使用 DS 寄存器。你想达到什么目标?
  • 我是汇编语言的新手,我见过一些将值移动到ds 的例子,所以我只是假设我可以为 ds 分配任何值。我使用 Visual Studio 只是因为我更熟悉这种 IDE 和 C 编程语言。
  • 因为它的 CPU 在保护模式下运行。如果你想学习汇编,要么使用 8086 仿真器(实模式仿真器),要么切换到更简单的汇编语言,如 M68K 或 MIPS。

标签: c visual-studio assembly


【解决方案1】:

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 寄存器中,而不会导致 保护例外。但是,任何后续尝试引用其对应段的段 使用 NULL 值加载寄存器会导致一般保护异常 (#GP) 并且不会发生内存引用。

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


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

2 实际上 32 位版本的 Windows 支持 16 位程序,但自从 Vista 以来,64 位版本不支持。 Visual Studio 无论如何都无法生成 MZ exe,根据 @RossRidge 的评论,您需要 Visual C++ 1.5 或更高版本。

【讨论】:

  • @RossRidge 谢谢!正在更正中!
猜你喜欢
  • 2011-07-18
  • 1970-01-01
  • 2020-11-11
  • 2022-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多