Код, преобразованный из emu8086 в NASM, не работает - PullRequest
1 голос
/ 13 января 2020

Я вручную преобразовал некоторый код на emu8086 в NASM, и когда я запускаю программу DOS, экран просто пуст с курсором.

Предполагается, что программа заставляет символ '@' перемещаться по экрану.

преобразованный код:

bits 16
org 100h
section .text
jmp start
start:
call init
jmp mainloop


mainloop:
call draw      
call update
call delay 
call refresh 
mov bl, gameover 
cmp bl, true
je exit
jmp mainloop  

init:  
call clearregisters 
call clearscreen 
mov bl, 0
mov [gameover], bl      
mov bl, 20               
mov bh, 12
mov byte [playerx], bl
mov byte [playery], bh
ret     

update:
call resetcursor
mov bl, playerx
inc bl
mov byte [playerx], bl
ret    


draw:
call drawplayer
ret    

refresh:
call refreshplayer
ret

drawplayer:
mov dl, playerx
mov dh, playery
call setcursorpos 
mov dx, player
call writeline 
ret  


refreshplayer:
mov bl, playerx
dec bl
mov dl, bl
mov dh, playery
call setcursorpos
mov dx, empty 
call writeline
ret

setcursorpos:
push ax
push bx
mov bh, 0
mov ah, 2
int 10h
pop bx
pop ax
ret    

writeline:
push ax
mov ah, 9
int 21h
pop ax
ret

resetcursor:
mov dl, 0
mov dh, 0
call setcursorpos
ret    


clearscreen:
push ax
mov ah, 00h
mov al, 03h  
int 10h
pop ax   
ret 


clearregisters:
xor ax, ax
xor bx, bx
xor cx, cx
xor dx, dx
xor si, si
xor di, di
mov bp, sp
ret    


delay: 
push ax
push cx
push dx
mov cx, 01h
mov dx, 4240h
mov ah, 86h
int 15h   
pop dx
pop cx
pop ax
ret    

exit: 
call clearregisters 
mov ax, 4C00h
int 21h   

section .data
true  equ 1
false equ 0 

player  db '@', 24h     
empty   db 20h, 24h
section .bss
playerx  resb 1
playery  resb 1
gameover resb 1

оригинальный код:

org 100h
jmp start
start:
call init
jmp mainloop


mainloop:
call draw      
call update
call delay 
call refresh 
mov bl, gameover 
cmp bl, true
je exit
jmp mainloop  

init proc near   
call clearregisters 
call clearscreen 
mov bl, 0
mov byte ptr[gameover], bl      
mov bl, 20               
mov bh, 12
mov byte ptr[playerx], bl
mov byte ptr[playery], bh
ret    
init endp  

update proc near
call resetcursor
mov bl, playerx
inc bl
mov byte ptr[playerx], bl
ret    
update endp

draw proc near
call drawplayer
ret    
draw endp

refresh proc near
call refreshplayer
ret
refresh endp

drawplayer proc near
mov dl, playerx
mov dh, playery
call setcursorpos 
mov dx, player
call writeline 
ret  
drawplayer endp 

refreshplayer proc near
mov bl, playerx
dec bl
mov dl, bl
mov dh, playery
call setcursorpos
mov dx, empty 
call writeline
ret
refreshplayer endp

setcursorpos proc
push ax
push bx
mov bh, 0
mov ah, 2
int 10h
pop bx
pop ax
ret    
setcursorpos endp

writeline proc 
push ax
mov ah, 9
int 21h
pop ax
ret
writeline endp

resetcursor proc near
mov dl, 0
mov dh, 0
call setcursorpos
ret    
resetcursor endp

clearscreen proc near
push ax
mov ah, 00h
mov al, 03h  
int 10h
pop ax   
ret 
clearscreen endp 

clearregisters proc
xor ax, ax
xor bx, bx
xor cx, cx
xor dx, dx
xor si, si
xor di, di
mov bp, sp
ret    
clearregisters endp

delay proc near 
push ax
push cx
push dx
mov cx,   01h
mov dx, 4240h
mov ah, 86h
int 15h   
pop dx
pop cx
pop ax
ret    
delay endp 

true  equ 1
false equ 0 

player:  db '@', 24h     
empty:   db 20h, 24h
playerx  db 0ACh
playery  db 0ACh
gameover db 0ACh 

exit: 
call clearregisters 
mov ax, 4C00h
int 21h 

Я не могу понять, что случилось. Не могли бы вы узнать, в чем проблема?

Кроме того, переполнение стека не позволит мне закончить sh, если я не добавлю лишние строки, потому что "большая часть текста - это код"

Спасибо .

1 Ответ

3 голосов
/ 13 января 2020

mov dx, empty в синтаксисе MASM (emu8086) - это загрузка.

В NASM это mov r16, imm16 адреса. Вы хотите mov dx, [empty].

Подробнее о различиях между разновидностями синтаксиса Intel см. { ссылка }.

Я бы порекомендовал разобрать вашу версию emu8086 с помощью ndisasm и сравнение с разборкой того, что вы получаете от своей версии NASM. Они должны быть одинаковыми, если вы перенесли их точно; .com файлы не имеют никаких дополнительных метаданных, которые могут отличаться.


Кроме того, используйте для отладки встроенный отладчик в BOCHS или DOSBox или любой отладчик, который работает внутри DOSBox. Существует так много способов сбоя программы и ничего не делать, что вам нужен отладчик; просто перечитывание кода после просмотра результатов выполнения очень часто является пустой тратой времени.

...