;This is the example from page 145 of the Byte by Byte text.
;Notice the use of more procedures. Also, there are a couple
;of errors in the text that have been corrected:
; disp_char must not destroy the ax register
; the statement ja 9 should be jae 9
DOSSEG
.MODEL SMALL
.STACK
cr EQU 0DH
lf EQU 0AH
.DATA
msg1 DB cr,lf,'The binary value of 55379 is $'
msg2 DB cr,lf,'The binary value of 55379 is $'
.CODE
start: mov ax,@DATA
mov ds,ax
lea dx,msg1
call disp_strg
mov ax,55379
call disp_bin
lea dx,msg2
call disp_strg
mov ax,107
call disp_bin
mov ax,4c00h
int 21h
;set_size sets si equal to 1 or 0, depending on ah
; si=0 if ah is 0
; si=1 if ah is not 0
;if ah is 0, then the number in ax can be represented
;in a byte. This information will be used later to
;suppress printing the upper byte.
set_size proc near
xor si,si ;clear si, assume ah <> 0
cmp ah,0
jne ss_done
mov si,1 ;ah = 0, so ax is a byte
ss_done: ret
set_size endp
;print_space determines when to print the space separating
;the upper byte from the lower byte. Only print the space
;if ax is a word and if the first 8 bits have already been
;processed.
;si indicates if ax is a word, cx equal to 8 indicates that
;the bit positions 9 - 15 have already been processed.
print_space proc near
cmp cx,8 ;cx=8 means high byte
jne ps_done ;has been printed already
cmp si,1 ;si=1 means ax is a byte
je ps_done
mov dl,' ' ;print space
call disp_char
ps_done: ret
print_space endp
;This is the most important procedure. It rotates the number in ax,
;examining the highest bit in ax each time. If the bit is a 1, then
; a '1' is printed, if the bit is a 0, then '0' is printed.
;Also, if the ah register is 0, then only the low byte is processed.
;Also, if ax needs the whole word, then there is a space printed
;between the high byte and the low byte.
disp_bin proc near
push ax ;be polite:save all registers
push bx ;that disp_bin uses
push cx ;they will be restored later
push dx
push si
call set_size ;si=1 means ax is a byte
;si=0 means ax is a word
mov cx,16 ;16 bits in a register
;so set loop counter to 16
;to process each bit
db_top: cmp si,1 ;test if ax is a byte
jne db_test ;if not, then process bit
cmp cx,9 ;test if processing a bit in
jae db_bottom ;in the high byte. If yes then
;don't process it
db_test: call print_space ;test if time to print space
push ax ;save number on stack
and ax,8000h ;isolate highest bit
jnz db_one ;if not 0, then print '1'
mov dl,'0' ;print '0'
jmp db_print
db_one: mov dl,'1'
db_print: call disp_char
pop ax
db_bottom: rol ax,1 ;move next bit into high bit
loop db_top ;process next bit
pop si ;be nice
pop dx ;restore registers in reverse
pop cx ;order of how they were saved
pop bx
pop ax
ret
disp_bin endp
disp_char proc near
push ax ;it is very important to be
mov ah,02h ;polite here. If not, then
int 21h ;this procedure will destroy
pop ax ;the ax register which holds
ret ;the number being processed
disp_char endp
disp_strg proc near
push ax
mov ah,09h
int 21h
pop ax
ret
disp_strg endp
end start