2017-07-30 89 views
2

下面的代碼編譯和運行正常上的Xubuntu 16.04與 在bash的這些命令殼16位x86彙編程序,使用8位內存存儲變量繪製藍色到屏幕的顏色問題?

nasm blue.asm -fbin -oblue.com

dosbox ./blue.com -exit

時遇到的問題是在線路20 mov al, 1;byte [blue]

如果我用這個代替 mov al, byte [blue]

程序在屏幕上繪製一種勃艮第而不是藍色。它工作正常使用這是在8位調色板這裏https://en.wikipedia.org/wiki/BIOS_color_attributes

顏色代碼下面是完整的代碼,隨時讓我知道,如果真有別的毛病雖然。

org 00h 
bits 16  

section .data    

    blue: db  1 

section .text 
MAIN: 

AsyncKeyInput:  

    mov  al, 13h 
    int  10h 
    ; Segment a000h 
    mov  ax, 0a000h 
    mov  es, ax 
    ; Offset 0 
    xor  di, di 
    mov  al, 1;byte [blue] 
    ; Looplength (320*200)/2 = 7d00 
    mov  cx, 7d00h 

hplot: 
    mov [ es: di], al  ;set pixel to colour 
    inc di   ;move to next pixel 
    loop hplot  

    mov  ah, 1   ;Get the State of the keyboard buffer 
    int  16h   ;key press 
    jz  AsyncKeyInput ;if not zero then exit the program 

    ;exit program 
    mov eax, 1 
    mov ebx, 0 
    int 0x80 
ret 
+1

'org 00' or'org 0x100'? 'int 0x80'是一個退出系統調用而不是DOS退出,一個COM程序應該只用'ret' –

+0

我認爲它是'org 00',但這是默認的權利?所以不需要甚至宣佈它?它應該是'0x100'嗎?有什麼區別,它的堆棧大小正確嗎? – pandoragami

+1

DOS COM程序在偏移量0x100處。 –

回答

2

問題的解決方案是爲com程序正確設置程序段前綴爲org 100h。以下是更正後的代碼。

org 100h 
bits 16  

section .data    

    blue: db  1h  

section .text 
MAIN: 

AsyncKeyInput:  

    mov  al, 13h 
    int  10h 
    ; Segment a000h 
    mov  ax, 0a000h 
    mov  es, ax 
    ; Offset 0 
    xor  di, di 
    xor  eax, eax 
    mov  al, byte [blue] 
    ; Looplength (320*200)/2 = 7d00 
    mov  cx, 7d00h 

hplot: 
    mov [ es: di], al  ;set pixel to colour 
    inc di   ;move to next pixel 
    loop hplot  

    mov  ah, 1   ;Get the State of the keyboard buffer 
    int  16h   ;key press 
    jz  AsyncKeyInput ;if not zero then exit the program 

    ;text mode 
    mov  ax, 0003h 
    int  10h   
ret 
+1

還有一個(大)問題。 COM沒有任何部分,它僅僅是由DOS從0x0100偏移量加載到第一個空閒段中的<64kiB二進制文件。所以目前'blue db 1'還定義了第一條要執行的指令,通過網絡反彙編器快速搜索顯示爲「db 0x1」,所以我不確定CPU如何處理它,可能是一些未定義的代碼。刪除無用的「.section」頭文件,並在'org 0x0100'之後立即啓動代碼,將變量放在代碼的中間/末尾,不會意外執行。並可能讀一些關於DOS COM文件。 – Ped7g

+1

另外一個小問題,用mov al,13h'' int 10h'開始的代碼不是一個如何設置13h gfx模式的正確方法。你也必須將'ah'設置爲零(「設置gfx模式服務」),你只需在dosbox下運行,他們的DOS在加載COM後在'ah'中保留零。所以'mov ax,13h'是如何加載AH = 0,AL = 0x13的正確方法。 (然後標籤'AsyncKeyInput'可能放置不好,每次都會導致gfx模式的重新初始化)。 – Ped7g

+0

@ Ped7g「COM沒有任何部分,它只是由DOS從0x0100偏移量加載到第一個空閒段中。」我應該把所有的數據變量放在代碼段之後嗎? – pandoragami

相關問題