I'm trying to simply output CX
's values (binary) in loop l1
with OutBin proc
, but it gives me only its first value (10).
I guess there's some problem with the loop itself, with saving registers before calling procedure, but I don't know how to fix everything.
.model small
.stack 100h
.data
; X dw 10 DUP (1,2,3)
.code
.startup
mov cx, 10
l1:
mov ax, cx
push cx
call OutBin
pop cx
loop l1
OutBin proc
; AX to print
mov bx, ax
mov cx, 16
ob1:
shl bx,1
jc ob2
mov dl,'0'
jmp ob3
ob2:
mov dl, '1'
ob3:
mov ah,2
int 21h
loop ob1
;call NewLine
OutBin endp
NewLine proc
mov dx, 0Dh
mov ah,2
int 21h
mov dx, 0Ah
mov ah,2
int 21h
NewLine endp
.exit
end
Your program has 2 procedures OutBin and NewLine. Both are missing the ret
instruction just above their endp
directives.
What your program also misses is a descent exit to DOS.
Look what happens when the l1 loop has finished.
loop l1
OutBin proc
The code mistakenly falls through in the OutBin procedure. You'll have to insert the necessary intructions to return to DOS:
loop l1
mov ax, 4C00h ;DOS.TerminateWithExitcode
int 21h
OutBin proc
X dw 10 DUP (1,2,3)
Guessing that your ultimate goal is to display 10 numbers (mov cx, 10
) taken from the array X, this dw
directive is actually defining 30 numbers.
1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3
That's probably not what you wanted.
Notice that once you start reading from the array X, you'll have to setup the segment registers first. With .model small
they don't automatically point to your .data
. If you used .model tiny
, they would though.
shl bx,1 jc ob2 mov dl,'0' jmp ob3 ob2: mov dl, '1' ob3:
The above code can be simplified to the much better:
mov dl, '0'
shl bx, 1
adc dl, 0
If no carry was shifted out, the dl
register will remain '0'.
If a carry is shifted out, the dl
register will get incremented to '1'