I'm working on an exercise using Assembly 8086 which inputs a number (in string form) then output the binary form. Here is what I did (tested on emu8086 by the way):
Convert the string to numeric form: I simply iterated through the string, and for each new value I simply multiply the old value by 10, then add by the new value. But there are some checks for overflow which was annoying: I have to check in both the multiplication and addition part, and since in this part I simply ignored the negative part (for simplicity) I had to check for a special case: a 16-bit signed number goes from \$-2^{15} = -32768\$ to \$2^{15} - 1 = 32767\$, so if the input is
-32768
then there would be an error, so I had to check for that case specifically.From numeric to binary: I simply left-shifted the number (which is now stored in
AX
) consecutively and printed the most significant bit.
Please give some feedback, because I'm not sure if the overflow part is ok.
;Written by Dang Manh Truong
.stack 100h
.data
base10_string dw "-32799$"
biggest_16bits_signed equ 7FFFh
special_16bits_signed equ 8000h
special_16bits_signed_str dw "1000000000000000$"
error_overflow dw "Arithmetic overflow encountered. Abort$"
error_not_a_number dw "Not a number. Abort$"
base10 equ 10
tmp dw 0
is_negative dw 0
.code
main proc
;Initialization
mov ax,@data
mov ds,ax
;;;part 1: convert string to value
mov ax,0 ;number = 0;
lea si,base10_string
;check if positive or negative
mov bl,[si] ;bl = value
cmp bl,'+'
jne check_if_negative
add si,1 ;start from after the "+" sign
mov ax,0
jmp while_loop
check_if_negative:
cmp bl,'-'
jne check_if_not_a_number
mov ax,1
mov is_negative,ax
mov ax,0
add si,1 ;start from after the "-" sign
jmp while_loop
check_if_not_a_number:
cmp bl,'0'
jge keep_checking
jmp not_a_number
keep_checking:
cmp bl,'9'
jle while_loop
jmp not_a_number
while_loop:
mov bl,[si] ;bl = value
;check if end of string
cmp bl,'$'
je end_while
;check if not a number
check_:
cmp bl,'0'
jge keep_checking_
jmp not_a_number
keep_checking_:
cmp bl,'9'
jle add_to_number
jmp not_a_number
add_to_number:
and bx,000Fh ;'0'-> 0, '1' -> 1,...
mov dx,base10
;try
mul dx ;number = number*10
;catch (Exception ArithmeticOverflow)
jo overflow
;try
add ax,bx ;number = number*10 + value
;catch <Exception ArithmeticOverflow)
;jo overflow
cmp is_negative,1
jne _perform_check
cmp ax,special_16bits_signed
jne _perform_check
jmp _aftercheck_overflow
_perform_check:
;jo overflow
cmp ax,0
jl overflow
_aftercheck_overflow:
add si,1 ;next value
jmp while_loop
end_while:
;is negative?
cmp is_negative,1
jne begin_part2
neg ax
begin_part2:
;;;part 2: print base-2 number
mov cx,16
mov bx,ax
mov ah,2
print_:
cmp cx,0
je after_print
shl bx,1
;if bit == 1
jnc print_0
;then print_1
mov dl,'1'
int 21h
jmp add_counter
;else print_0
print_0:
mov dl,'0'
int 21h
add_counter:
dec cx
jmp print_
after_print:
jmp return_to_dos
overflow:
lea dx,error_overflow
mov ah,9
int 21h
jmp return_to_dos
not_a_number:
lea dx,error_not_a_number
mov ah,9
int 21h
jmp return_to_dos
return_to_dos:
mov ah,4ch
int 21h
main endp
end main