2012-03-24 109 views
3

我一直在研究一個實模式操作系統,在彙編中編寫和編譯爲帶有NASM的flat .bin可執行文件。
我還想寫一些操作系統的C,所以寫了一個實驗計劃(ctest.c),我想訪問一個字符串,並打印第一個字符:
在實模式下的16位.com C程序操作系統

void test(); 

int main() { test(); return 0; } 

char msg [] = "Hello World!"; 

void test() { 
    _asm 
    { 
     mov si, word ptr [msg] 
     mov al, [si] 
     mov ah, 0eh 
     int 10h 
    } 
    for(;;); 
} 

我編這個Open Watcom v1.9使用wcl ctest.c -lr -l=COM。這創建了ctest.com。我在NASM程序集中編寫的內核將該程序加載到0x2010:0x0000,將DS和ES設置爲0x2000:0x0000,然後跳轉到0x2010:0x0000。這就是我一直致電.COM程序編寫並編譯爲nasm -f bin test.asm -o test.com
當我測試操作系統(使用Bochs)時,它成功加載ctest.com,但打印出一個不含msg []的無意義字符。
有沒有人對此有任何建議?我認爲字符串剛剛在錯誤的地方被初始化。我想保留這個16位操作系統。
謝謝!

+2

.com存儲器映像的前128個字節包含操作系統數據,與CP/M類似。 DOS取決於它。接下來的128個字節包含命令行。執行從0x100開始。 – 2012-03-24 20:11:57

回答

4

您正在使用錯誤的地址。您在0x2000加載:0x0100並跳轉到0x2000:0x0100(不要忘記設置DS = ES = SS = 0x2000和SP = 0之前)您加載在0x2000:0x0000(相當於0x1FF0:0x0100,因爲0x2000 * 0x10 + 0x0000 = 0x1FF0 * 0x10 + 0x0100 = 0x20000 =實模式中的物理存儲器地址),並跳轉到0x1FF0:0x0100(不要忘記設置DS = ES = SS = 0x1FF0和SP = 0)那)。

所有這一切的原因是編譯的x86代碼通常不是位置無關的,如果您移動它,則必須調整代碼中的一些數據偏移量。顯然,你沒有做這些調整。在簡單的情況下,沒有什麼可以調整的,並且你用錯誤的地址逃脫了。

編輯

其實,這裏有更多的是問題:

  1. mov si, word ptr [msg]必須改變,以lea si, byte ptr [msg],因爲你不希望加載si與字符串中有什麼,你想用字符串的地址加載它。
  2. 通過OW鏈接到您的程序的啓動代碼依賴於DOS並調用DOS函數,這在啓動程序時並不具備。瞭解如何解決此問題here
1

在MS-DOS下,COM程序在偏移量0x100處加載。我猜想Open Watcom會做出這樣的假設。我會建議加載COM程序在0x2010:0x0100,看看有什麼。

+0

我剛剛嘗試過,並沒有奏效。順便說一下,我使用int 13h ah 2讀取虛擬軟盤上的扇區。 – user1112148 2012-03-24 20:28:27

+0

最後的地址顯然是錯誤的。 – 2012-03-24 20:57:02

相關問題