2016-11-22 83 views
0

我正在使用Visual Studio構建控制檯程序,並且在此C程序中使用了內聯彙編指令,如圖所示:code and error message。 對於那些誰也看不到圖片,我寫的代碼是:「mov ds,ax」在Visual Studio中顯示0xC0000005錯誤

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,我不知道這是什麼錯誤消息的確切的翻譯,但它是粗糙的意思shoule是: 「有一個在0x008e13c2未處理的異常:0000005:訪問衝突發生時讀取0xffffffff

問題1:是否有人知道爲什麼會發生這種情況?我不能將一個隨機值分配給DS寄存器嗎?

順便問一下,另一個問題是,當我將0到3的數字指定給DS寄存器時,沒有發生錯誤,但Visual Studio左下角的寄存器窗口顯示DS寄存器的值沒有被改變了。第二季度:爲什麼會發生這種情況?我有沒有成功地將值分配給DS寄存器?

任何幫助將不勝感激。

+0

由於編譯器生成的代碼可能使用了'ds'作爲別的東西?如果你想進行DOS級別的編程,請使用一個實際的彙編程序來定位DOS,並使用仿真環境來運行該程序。 –

+1

04h不是一個有效的選擇器,因爲它將LDT中的描述符0索引爲RPL = 0(無法使用CPL = 3並且爲空描述符保留) –

+2

您無法摸索DS寄存器。你想達到什麼目的? –

回答

4

Visual Studio在Windows下運行,Windows將CPU切換爲protected mode (PM)
在PM中,您不能再指定選擇器寄存器(如ds),而是指定您想要的任何值,而不是OS爲您加載這些寄存器。

假設操作系統在這方面沒有缺陷,而Windows沒有,其他任何值(但是對於其他選擇器寄存器中的值)將觸發異常。


如果你看到這樣的代碼

mov ax, cs 
mov ds, ax 

mov ax, 0b800h 
mov es, ax 

mov ax, ... 
mov ds, ax 

然後,它的real mode代碼,它不適合在Windows下運行了。
您可能需要考慮使用DOS模擬器(如DOSBox)和可生成16位可執行文件(如NASM,MASM,TASM或Turbo C)的彙編器/編譯器。


值00H - 03H是在這方面的特殊,因爲它們都表示NULL選擇

空的段選擇(值0000-0003)可以被加載到DS, ES,FS和GS寄存器,而不會導致 保護異常。但是,任何後續嘗試引用其對應段 寄存器加載NULL值的段的引用都會導致一般保護異常(#GP),並且不會發生內存引用。

值04h不引用NULL描述符,並且只要您嘗試使用它設置ds就會引發異常。


其實OS,可能會給用戶空間程序可以訪問其它的描述,但假定使他們的用途是等同於一個已經存在的寄存器。因此,改變這些是沒有意義的。

實際上,32位版本的Windows支持16位程序,但自Vista以來,64位版本不支持。無論如何,Visual Studio無法生成MZ exes,根據@RossRidge評論,您需要Visual C++ 1.5或以前版本。

+0

@RossRidge謝謝!正在修正中! –