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
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
Share
Improve this question
edited Feb 26 at 0:55
Sep Roland
39.9k10 gold badges48 silver badges89 bronze badges
asked Feb 23 at 13:10
Coder4Fun250Coder4Fun250
1534 bronze badges
2
|
1 Answer
Reset to default 0Your present 8-bit routines are wrong because they either fet 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
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745154088a4614012.html
div si
divides the 32 bit number formed fromdx
andax
but you only set the low 8 bits of the dividend. – Jester Commented Feb 23 at 13:16bl
intobx
, clearbh
(xor bh,bh
). – Erik Eidt Commented Feb 23 at 15:14