从emu8086转换为NASM的代码不起作用

问题描述 投票:1回答:1

我手动将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 

我似乎无法找出问题所在。您能找出问题所在吗?

此外,除非我添加多余的行,否则堆栈溢出不会让我完成此操作,因为“大多数文本是代码”]

谢谢。

assembly x86 nasm dos emu8086
1个回答
3
投票

MASM语法(emu8086)中的[mov dx, empty是负载。

在NASM中,它是地址的mov r16, imm16。您想要mov dx, [empty]

请参阅https://stackoverflow.com/tags/intel-syntax/info,了解有关Intel语法之间的区别的更多信息。

我建议您使用ndisasm拆解您的emu8086版本,并将其与您从NASM版本中获得的结果进行比较。如果您准确移植,它们应该是相同的。 .com文件没有任何可能不同的额外元数据。


此外,请使用BOCHS或DOSBox中的内置调试器进行调试,或使用在DOSBox中运行的任何调试器。程序失败有很多方法,无所事事,您需要调试器。仅在查看运行结果后重新读取代码通常会浪费您的时间。

© www.soinside.com 2019 - 2024. All rights reserved.