home *** CD-ROM | disk | FTP | other *** search
- ;; NUMVERT.ASM
- ;;
- ;; Useful decimal, hexidecimal and binary conversion routines.
- ;;
- ;; This program can be assembled using the A86 or TASM assemblers
- ;;
- ;; Not tested with Masm, should work?
- ;;
- ;; This code is "PUBLIC DOMAIN"
- ;;
- ;; by William Cravener 12/07/92
- ;;
- ;---------------------------------------------------------
- ;;
- code SEGMENT
- ASSUME cs:code, ds:code, es:code, ss:code
- ORG 100h ; COM files begin here
- start:
- jmp begin
- ;;
- ;----------------------------------------------------------------
- ;;
- input_buffer DB 18 ; maximum of 18 numbers
- DB 0 ; actual length of input
- DB 19 DUP (0) ; room for carriage
- ;;
- decimal DB 'DECIMAL = ', 0
- hexidecimal DB ' HEX = ', 0
- binary DB ' BINARY = ', 0
- ;;
- explain DB 0dh, 0ah, 'Number Conversion by ยป-Swift-Ware-', 0dh, 0ah
- DB 0dh, 0ah, 'Decimal to - 65535'
- DB 0dh, 0ah, 'Hexidecimal to - FFFFH'
- DB 0dh, 0ah, 'Binary to - 1111111111111111B'
- DB 0dh, 0ah, 'Include H or B at end of number.'
- DB 0dh, 0ah, 0ah, 'Enter number: $'
- ;;
- ;----------------------------------------------------------------;
- ;;
- begin:
- call clear_screen ; first clear the screen
- mov dx, OFFSET explain ; point to explanation
- mov ah, 9 ; display string function
- int 21h ; the interrupt
- mov dx, OFFSET input_buffer ; point to buffer storage
- push dx ; save pointer on stack
- mov ah, 0ah ; use DOS buffered input
- int 21h ; the interrupt
- pop di ; pop pointer into DI
- inc di ; point to input length
- push di ; save new pointer location
- mov cl, BYTE PTR [di] ; place input length in CL
- add di, cx ; add length to offset
- cmp BYTE PTR [di], 'a' ; is it uppercase?
- jb isup ; if neccessary
- cmp BYTE PTR [di], 'z' ; make it so
- ja isup ; by -
- sub BYTE PTR [di], 20h ; subtraction
- isup:
- cmp BYTE PTR [di], 'B' ; is it a binary number?
- je be_binary_number ; yes - need binary convert
- cmp BYTE PTR [di], 'H' ; is it a hexidecimal number
- je be_hexidecimal_number ; yes - need hex convert
- be_decimal_number:
- inc di ; wasn't the above must be decimal
- mov BYTE PTR [di], 0 ; end input string with a "0"
- pop si ; pop saved pointer into SI
- inc si ; point to beginning of string
- call ascdec_2_bin ; make it a binary value
- jmp show_the_numbers ; show all three converted formats
- be_binary_number:
- mov BYTE PTR [di], 0 ; end input string with a "0"
- pop si ; pop saved pointer into SI
- inc si ; point to beginning of string
- dec cx ; binary routine needs number of chars
- call ascbin_2_bin ; make it a binary value
- jmp show_the_numbers ; show all three converted formats
- be_hexidecimal_number:
- mov BYTE PTR [di], 0 ; end input string with a "0"
- pop si ; pop saved pointer into SI
- inc si ; point to beginning of string
- call aschex_2_bin ; make it a binary value
- show_the_numbers:
- call cr_lf ; do a CR LF pair
- call show_decimal ; display as a ASCII decimal
- call show_hexidecimal ; display as a ASCII hexidecimal
- call show_binary ; display as a ASCII binary
- int 20h ; finished exit to DOS
- ;----------------------------------
- show_decimal: ; routine displays ascii decimal
- push dx ; save binary value on stack
- call cr_lf ; do a CR LF pair
- push si ; save buffer pointer
- mov si, OFFSET decimal ; point to DECIMAL =
- call write_string ; write it to screen
- pop si ; pop buffer pointer off stack
- call bin_2_ascdec ; make DX value a ascii decimal
- call write_string ; write it to screen
- call cr_lf ; do a CR LF pair
- pop dx ; retrieve binary value off stack
- ret
- show_hexidecimal: ; routine displays ascii hexidecimal
- push dx ; save binary value on stack
- call cr_lf ; do a CR LF pair
- push si ; save buffer pointer
- mov si, OFFSET hexidecimal ; point to HEX =
- call write_string ; write it to screen
- pop si ; pop buffer pointer off stack
- call bin_2_aschex ; make DX value a ascii decimal
- call write_string ; write it to screen
- call cr_lf ; do a CR LF pair
- pop dx ; retrieve binary value off stack
- ret
- show_binary: ; routine displays ascii binary
- push dx ; save binary value on stack
- call cr_lf ; do a CR LF pair
- push si ; save buffer pointer
- mov si, OFFSET binary ; point to BINARY =
- call write_string ; write it to screen
- pop si ; pop buffer pointer off stack
- call bin_2_ascbin ; make DX value a ascii decimal
- call write_string ; write it to screen
- call cr_lf ; do a CR LF pair
- pop dx ; retrieve binary value off stack
- ret
- ;----------------------------------
- write_string: ; BIO's teletype function
- push si ; save SI on stack
- mov ah, 0eh ; to monitor
- mov bh, 0 ; page 0
- num_jump:
- lodsb ; get character
- cmp al, 0 ; 0 if end of string
- je done ; done if so
- int 10h
- jmp num_jump ; get another character
- done:
- pop si ; retrieve SI from stack
- ret
- ;----------------------------------
- cr_lf: ; CR LF routine
- mov ah, 0eh ; BIO's teletype function
- mov bh, 0
- mov al, 0dh ; carriage
- int 10h ; do it
- mov ah, 0eh
- mov al, 0ah ; linefeed
- int 10h ; do it
- ret
- ;----------------------------------
- clear_screen: ; clears screen routine
- mov ah, 8 ; retrieve attribute function
- mov bh, 0 ; page 0
- int 10h
- mov bh, ah ; current screen color
- mov ah, 6 ; scroll function
- mov al, 0 ; whole screen
- mov cx, 0 ; upper left
- mov dx, 184fh ; lower right
- int 10h
- mov ah, 2 ; set cursor
- mov bh, 0 ; page 0
- mov dx, 0 ; top left
- int 10h
- ret
- ;================================================================;
- ;================================================================;
- ; NUMBER CONVERTING SUBROUTINES FROM HERE DOWN. ;
- ; ;
- ; BIN_2_ASCDEC ----- binary to ascii decimal. ;
- ; ;
- ; BIN_2_ASCHEX ----- binary to ascii hexidecimal. ;
- ; ;
- ; BIN_2_ASCBIN ----- binary to ascii binary. ;
- ; ;
- ; ASCDEC_2_BIN ----- ascii decimal to binary. ;
- ; ;
- ; ASCHEX_2_BIN ----- ascii hexidecimal to binary. ;
- ; ;
- ; ASCBIN_2_BIN ----- ascii binary to binary. ;
- ; ;
- ;================================================================;
- ;================================================================;
- ;----------------------------------------------------------------;
- ; Convert 16-bit binary in DX register to ASCII decimal number. ;
- ; ;
- ; On entry: ;
- ; SI - points to 6 byte output buffer. ;
- ; DX = 16 bit binary number. ;
- ; On return: ;
- ; SI - points to resulting ASCII decimal number. ;
- ;----------------------------------------------------------------;
- bin_2_ascdec:
- mov di, si ; copy SI into DI
- mov cx, 6 ; 6 digits to clear
- mov al, 0 ; fill it with "0"s
- cld ; forward direction
- repe stosb ; clear 6 places
- sub di, 2 ; left 2 for start address
- std ; store in reverse order
- make_it_ascii:
- mov ax, dx ; add in numerator
- mov dx, 0 ; clear top half
- mov cx, 10 ; enter decimal divisor
- div cx ; perform division AX/CX
- xchg ax, dx ; get quotient
- add al, 30h ; make digit ASCII
- stosb ; store digit in buffer
- cmp dx, 0 ; test for end of binary
- jnz make_it_ascii ; continue if not end
- inc di ; right 1 for beginning
- mov si, di ; SI = start of number string
- cld ; restore direction flag
- ret
- ;----------------------------------------------------------------;
- ; Convert a 16-bit binary in the DX register to an ASCII ;
- ; hexadecimal number. ;
- ; ;
- ; On entry: ;
- ; SI - points to 6 byte output buffer. ;
- ; DX = 16 bit binary number. ;
- ; On return: ;
- ; SI - points to resulting ASCII hexidecimal number. ;
- ; ( number ends with H ) ;
- ;----------------------------------------------------------------;
- bin_2_aschex:
- mov di, si ; copy SI into DI
- push di ; save user's buffer pointer
- mov cx, 6 ; 6 digits to clear
- mov al, 0 ; fill it with "0"s
- cld ; forward direction
- repe stosb ; clear 6 places
- sub di, 2 ; left 2 for "H"
- mov BYTE PTR [di], 'H' ; place "H" in buffer
- pop di ; restore buffer pointer
- mov cx, 4 ; count 4 digits
- hex_cvr:
- push cx ; save counter
- mov cl, 4 ; 4 digits
- rol dx, cl ; rotate source left
- mov al, dl ; move digit into AL
- and al, 15 ; clear high nibble
- daa ; adjust AL if A through F
- add al, 240 ; and bump the carry
- adc al, 40h ; convert hex to ASCII
- stosb ; store in buffer
- pop cx ; restore digit counter
- loop hex_cvr ; continue with next digit
- ret
- ;-------------------------------------------------------------------;
- ; Convert a 16-bit binary number in DX into 16 ASCII binary digits. ;
- ; ;
- ; On entry: ;
- ; SI - points to 18 byte output buffer. ;
- ; DX = 16 bit binary number. ;
- ; On return: ;
- ; SI - points to resulting ASCII binary number. ;
- ; ( number ends with B ) ;
- ;-------------------------------------------------------------------;
- bin_2_ascbin:
- mov di, si ; copy SI into DI
- push di ; save user's buffer pointer
- mov cx, 18 ; 18 digits to clear
- mov al, 0 ; fill it with "0"s
- cld ; forward direction
- repe stosb ; clear 18 digits
- sub di, 2 ; left 2 for "B"
- mov BYTE PTR [di], 'B' ; place "B" in buffer
- pop di ; start of buffer
- mov cx, 8 ; convert 8 bits of MSB
- bin_cvr_dh:
- test dh, 128 ; test high-order bit
- jnz set_1_dh ; go set bit
- mov BYTE PTR [di], '0' ; set bit to 0
- jmp next_bin_dh
- set_1_dh:
- mov BYTE PTR [di], '1' ; set bit to 1
- next_bin_dh:
- inc di ; bump pointer
- sal dh, 1 ; shift bits left once
- loop bin_cvr_dh ; do all of DH
- mov cx, 8 ; convert 8 bits of LSB
- bin_cvr_dl:
- test dl, 128 ; test high-order bit
- jnz set_1_dl ; go set bit
- mov BYTE PTR [di], '0' ; set bit to 0
- jmp next_bin_dl
- set_1_dl:
- mov BYTE PTR [di], '1' ; set bit to 1
- next_bin_dl:
- inc di ; bump pointer
- sal dl, 1 ; shift bits left once
- loop bin_cvr_dl ; do all of DL
- ret
- ;------------------------------------------------------;
- ; Convert an ASCII decimal number to a binary value. ;
- ; ;
- ; On entry: ;
- ; SI - points to 5 digit ASCII decimal string. ;
- ; ( range 0 to 65535 ) ;
- ; On return: ;
- ; DX = resulting binary value. ;
- ;------------------------------------------------------;
- ascdec_2_bin:
- push si ; save pointer to buffer
- mov dx, 0 ; Clear binary output
- ascdecbin:
- lodsb ; get ascii value into AL
- sub al, 30h ; ASCII to decimal
- jl not_ascii ; exit if invalid ASCII
- cmp al, 9 ; test for highest value
- jg not_ascii ; exit if larger than 9
- cbw ; byte to Word
- push ax ; save digit in stack
- mov ax, dx ; move into output register
- mov cx, 10 ; decimal multiplier
- mul cx ; perform AX = AX * 10
- mov dx, ax ; move product to output register
- pop ax ; restore decimal digit
- add dx, ax ; add in digit
- jmp ascdecbin ; continue
- not_ascii:
- pop si ; restore start of buffer
- ret
- ;----------------------------------------------------------;
- ; Convert an ASCII hexidecimal number to a binary value. ;
- ; ;
- ; On entry: ;
- ; SI - points to 4 digit ASCII hexidecimal string. ;
- ; ( range 0 to FFFF ) ;
- ; On return: ;
- ; DX = resulting binary value. ;
- ;----------------------------------------------------------;
- aschex_2_bin:
- push si ; save pointer to buffer
- mov dx, 0 ; clear binary output
- aschexbin:
- lodsb ; get ASCII digit
- cmp al, '0' ; is it less then "0"
- jb ascii_not ; yes - invalid character
- cmp al, '9' ; equal or less then "9"
- jbe strip ; yes - go strip high 4 bits
- and al, 5fh ; make letter upper case
- cmp al, 'A' ; less then ascii "A"
- jb ascii_not ; yes - invalid character
- cmp al, 'F' ; greater then ascii "F"
- ja ascii_not ; yes - invalid character
- add al, 9 ; its good add 9 for strip
- strip:
- and al, 0fh ; strip off the high 4 bits
- mov cl, 4 ; set shift count
- shl dx, cl ; rotate DX 4 bits
- xor ah, ah ; zero out AH
- add dx, ax ; add digit to value
- jmp aschexbin ; continue
- ascii_not:
- pop si ; restore start of buffer
- ret
- ;-----------------------------------------------------------;
- ; Convert a 16-digit ASCII binary number to a binary value. ;
- ; ;
- ; On entry: ;
- ; SI - points to 16 character ASCII binary string. ;
- ; ( range 0 to 1111111111111111 ) ;
- ; CX = Length of ASCII binary string. ;
- ; On return: ;
- ; DX = resulting binary value. ;
- ;-----------------------------------------------------------;
- ascbin_2_bin:
- mov di, si ; copy SI into DI
- add di, cx ; point to end of string
- mov bx, 2 ; 2 = binary base value
- mov cx, 1 ; Initialize multiplier
- xor ax, ax ; zero out AX
- nxt_cvt:
- cmp di, si ; at front of string yet?
- je at_front ; if equal - have it all!
- dec di ; next character to left
- mov dl, [di] ; load the character
- sub dl, 30h ; convert to decimal
- xor dh, dh ; ZERO out DH
- push cx ; save CX on stack
- xchg ax, cx ; AX = multiplier
- ; CX = partial value
- mul dx ; digit value * multiplier
- add cx, ax ; add to partial value
- pop ax ; restore multiplier
- mul bx ; base times multiplier
- xchg ax, cx ; AX = paritial value
- ; CX = new multiplier
- jmp nxt_cvt ; go do next digit
- at_front:
- mov dx, ax ; copy result into DX
- ret
- ;------------------------------------------------------------
- code ENDS
-
- END start
-