Im having trouble analyzing this block of code in converting decimal values to binary. Can somebody help explain the lines of text below? This is a working code by the way. I would really appreciate the help, this is for studying purposes. Thanks you!
calc :
mul multiplier
mov bl, byte ptr [si]
mov bh, 00h
add ax, bx
inc si
loop calc
mov si, offset buf4 + 2
mov bx, ax
mov dx, 0000h
mov ax, 8000h
convert :
mov cx, 0000h
conv :
cmp bx, ax
jb cont3
sub bx, ax
inc cx
jmp conv
cont3 :
add cl, 30h
mov byte ptr [si], cl
inc si
mov cx, 0002h
div cx
cmp ax, 0000h
jnz convert
mov byte ptr [si], '$'
prnstr buf3
prnstr buf4+2
stop :
mov ax, 4c00h
int 21h
The first part of the code was no trouble to understand (Accepting user input and checking if its a valid decimal number). I already added some comments.. the first half of the code looks like this:
prnstr macro msg ;acts like a function to print string
mov ah, 09h
lea dx, msg
int 21h
endm
data segment
buf1 db "Enter a decimal number : $"
buf2 db 0ah, "Invalid Decimal Number...$"
buf3 db 0ah, "Equivalent Binary number is : $"
buf4 db 6
db 0
db 6 dup(0)
multiplier db 0ah
data ends
code segment
assume cs:code, ds:data
start :
mov ax,@data
mov ds,ax
mov es, ax
prnstr buf1 ;Display
mov ah, 0ah ;Get line function
lea dx, buf4 ;adress of input buffer
int 21h
mov si, offset buf1 + 2 ;Load pointer to beginning of structure
mov cl, byte ptr [si-1] ;determine end of loop?
mov ch, 00h
subtract :
mov al, byte ptr [si] ;Load 1 byte of buf1 to cl
cmp al, 30h ;check if not below 0
jnb cont1
jmp stop
cont1 :
cmp al, 3ah ;check if not above 9
jb cont2
prnstr buf2 ;Display
jmp stop
cont2 :
sub al, 30h ;convert ASCII to Decimal number
mov byte ptr [si], al ;place bcd form back to pointed character
prnstr buf2 ;Display
inc si ;next character
loop subtract ;repeat until end of string
mov si, offset buf1 + 2 ;Load pointer to beginning of structure
mov cl, byte ptr [si-1] ;reset to determine end of loop using si
mov ch, 00h
mov ax, 0000h ;reset ax to 0
;...CONTINUE TO calc.....
The calc:
loop keeps multiplying by 10 and accumulating, so it appears that it calculates the actual value of the number that was entered in decimal. (It converts the string you entered, say "42", to the number 42.)
The remaining code converts the number that was calculated to binary. It is written in a kind of unorthodox way, to say the least.
The instruction mov dx, 0000h
clears dx
, because further down the div cx
instruction divides the dx:ax
pair by cx
, so if dx
was not zero then you would get garbage.
The ax
register starts with the value 08000h
which in binary is a 1
followed by 15 0
s and in each iteration of the loop it keeps being divided by 2, so on each iteration a new binary digit of 0
enters in from the left side, the 1
binary digit is moved to the right by one position, and a 0
binary digit drops out from the right side.
The check for ax
against zero will stop looping when the 1
binary digit drops out after 16 iterations, leaving ax
with all zeros.
The conv:
loop is a very unorthodox way of setting cx
to 0
or 1
depending on whether the bit represented by ax
is set or cleared in bx
. This loop loops at most once, so I think that the jmp conv
instruction could be missing, and it could just fell through to the cont2:
label.
Also note that loading 2
into cx
and then executing div cx
is retarded, you can just shr ax, 1
.