utobi
utobi

Reputation: 309

The DOS program seemingly ignores the 'print *' instruction?

This simple program (16-bit assembly using debug on FreeDOS, code below) expects a one-digit integer. It stops if the integer is either 0 or >1. If it's 1, it generates a new line, prints '*', then generates another new line, and stops. The code, however, doesn't do what is expected. In particular, it doesn't print the '*'. I asked ChatGPT, but it didn't find any obvious error.

The source file (prinst.txt) contains this:

a 100
mov ah,02  ; prepare for print
mov dl,3f  ; set '?'
int 21     ; print '?'
mov dl,20  ; set ' '
int 21     ; print ' ', hence generate the '?(space)' prompt.
mov ah,01  ; prepare for saving user input
int 21     ; ask user input. The input saved in al.
mov ah,02  ; prepare for print
mov dl,0d  ; set LF
int 21     ; print LF
mov dl,0a  ; set CR
int 21     ; print CR, hence generate new line
cmp al,30  ; compare user input in al, with '0'
je 012e    ; if equal jump to address 0126 (e.g. int 20)
cmp al,31  ; compare input with '1'
jne 012e   ; if input != '1', jump to address 0126
mov ah,02  ; prepare for print
mov dl,2a  ; set the symbol to print, e.g. '*'
int 21     ; print '*'
mov dl,0d  ; set LF
int 21     ; print LF
mov dl,0a  ; set CR
int 21     ; print CR, hence generate new line
int 20

n prinst.com
rcx
30
w
q

Assembled in FreeDOS using debug

C:\>debug <prinst.txt> prinst.lst

The listing file (prinst.lst) contains this

-a 100
0DAB:0100 mov ah,02  ; prepare for print
0DAB:0102 mov dl,3f  ; set '?'
0DAB:0104 int 21     ; print '?'
0DAB:0106 mov dl,20  ; set ' '
0DAB:0108 int 21     ; print ' ', hence generate the '?(space)' prompt.
0DAB:010A mov ah,01  ; prepare for saving user input
0DAB:010C int 21     ; ask user input. The input saved in al.
0DAB:010E mov ah,02  ; prepare for print
0DAB:0110 mov dl,0d  ; set LF
0DAB:0112 int 21     ; print LF
0DAB:0114 mov dl,0a  ; set CR
0DAB:0116 int 21     ; print CR, hence generate new line
0DAB:0118 cmp al,30  ; compare user input in al, with '0'
0DAB:011A je 012e    ; if equal jump to address 012e (e.g. int 20)
0DAB:011C cmp al,31  ; compare input with '1'
0DAB:011E jne 012e   ; if input != '1', jump to address 012e
0DAB:0120 mov ah,02  ; prepare for print
0DAB:0122 mov dl,2a  ; set the symbol to print, e.g. '*'
0DAB:0124 int 21     ; print '*'
0DAB:0126 mov dl,0d  ; set LF
0DAB:0128 int 21     ; print LF
0DAB:012A mov dl,0a  ; set CR
0DAB:012C int 21     ; print CR, hence generate new line
0DAB:012E int 20
0DAB:0130 
-n prinst.com
-rcx
CX 0000  :30
-w
Writing 0030 bytes
-q

And the output

C:\>prinst.com
? 0

C:\>prinst.com
? 1

Thus, the instruction to print '*' is kind of ignored. Maybe the conditional jumps are not working as expected? Something else?

I tried FreeDOS's debugger (installed on a virtual machine) and DOSBox-x's debugger (version 2024.07.01) on a MacOS` and got the same results.

Also, I know the DOS debugger is terrible, explicitly addressing is not recommended, etc., and I must use a better assembler, s.t. TASM/MASM/NASM.

Upvotes: 0

Views: 49

Answers (0)

Related Questions