Reputation: 143
I'm trying to print out current year (CX), month (DH), day (DL) and day of the week (AL) from system timer.
Year stored in CX is printed out correctly.
I tried to printout DH, DL and AL with print_number16bit (I called it print_number initially) but there was a type incompatibility error probably because I tried to pass an 8-bit register to a 16-bit register.
I decided to create a function for 8-bit numbers (print_number8bit initially), but was having weirdly large numbers (>255). I thought maybe it was because I tried to work with h
registers like l
registers (I passed DH to BL). So I decided to create 2 functions: print_number8bitl for l
registers and print_number8bith for h
registers. The DH is printed out correctly but the wrong month: 3 instead of 2. Other data is printed wrong (>255).
How do I print the numbers out correctly?
I'm a beginner in assembler and don't know a lot, I hope I get help.
SSEG segment stack
db 256 dup(0)
SSEG ends
DSEG segment
whitespace db ' $'
DSEG ends
CSEG segment
assume cs:CSEG,ds:DSEG,ss:SSEG
begin:
mov ax, DSEG
mov ds, ax
mov ah, 2Ah
int 21h
mov bx, cx
call print_number16bit
mov bh, dh
call print_number8bith
mov bl, dl
call print_number8bitl
mov bl, al
call print_number8bitl
mov ah,01h
int 21h
mov ah,4ch
int 21h
print_number16bit proc
mov si,10
mov ax,bx
mov cx,0
a1:
mov dx,0
div si
add dx,'0'
push dx
inc cx
cmp ax,0
jnz a1
aa1:
pop dx
mov ah,02h
int 21h
loop aa1
mov ah, 09h
mov dx, offset whitespace
int 21h
ret
endp
print_number8bitl proc
mov si,10
mov al,bl
mov cx,0
a3:
mov dx,0
div si
add dx,'0'
push dx
inc cx
cmp al,0
jnz a3
aa3:
pop dx
mov ah,02h
int 21h
loop aa3
mov ah, 09h
mov dx, offset whitespace
int 21h
ret
endp
print_number8bith proc
mov si,10
mov ah,bh
mov cx,0
a4:
mov dx,0
div si
add dx,'0'
push dx
inc cx
cmp ah,0
jnz a4
aa4:
pop dx
mov ah,02h
int 21h
loop aa4
mov ah, 09h
mov dx, offset whitespace
int 21h
ret
endp
CSEG ends
end begin
Upvotes: 2
Views: 53
Reputation: 39411
Your present 8-bit routines are wrong because they either forget to zero the AH register or the AL register.
The Q/A Displaying numbers with DOS not only explains in great detail how to display a number, it also answers the question about needing separate routines for numbers of different sizes. You only need your one 16-bit routine! But because you didn't preserve the registers, there's little hope to display a correct month (DH), day (DL), or day of the week (AL).
This is my suggestion:
; IN (cx) OUT (cx=0)
print_number16bit proc
push ax
push bx
push dx
mov bx, 10
mov ax, cx
xor cx, cx ; -> CX=0
.a:
xor dx, dx ; -> DX=0
div bx
add dx, '0'
push dx
inc cx
test ax, ax
jnz .a
.b:
pop dx
mov ah, 02h
int 21h
loop .b
mov dl, ' ' ; whitespace
int 21h
pop dx
pop bx
pop ax
ret ; Return with CX=0 (LOOP zeroed CX already)
endp
With these changes, the main part can use the next calling sequence:
; CX is year
call print_number16bit ; -> CX=0
mov cl, dh ; DH is month
call print_number16bit ; -> CX=0
mov cl, dl ; DL is day
call print_number16bit ; -> CX=0
mov cl, al ; AL is day of week
call print_number16bit ; -> CX=0
Upvotes: 0