【问题标题】:Code converted from emu8086 to NASM isn't working从 emu8086 转换为 NASM 的代码不起作用
【发布时间】:2020-04-29 18:26:36
【问题描述】:

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

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

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

    请参阅https://stackoverflow.com/tags/intel-syntax/info,了解有关英特尔语法风格之间差异的更多信息。

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


    另外,使用 BOCHS 或 DOSBox 中的内置调试器或在 DOSBox 中运行的任何调试器进行调试。程序失败的方式有很多,什么也不做,你需要一个调试器;只是在查看运行结果后重新阅读代码通常是在浪费您的时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-12
      • 1970-01-01
      相关资源
      最近更新 更多