UMBC CMSC 313 -- PUTHEX8.ASM  


PUTHEX8.ASM

;;============================================================================
;;
;;	puthex8 will do the conversion of a unsigned byte from binary to
;;      hex characters.  Two subprograms are used.  One is to convert a
;;      nybble to a hex character and is invoked twice, once for each nybble.
;;      This improves the version in Lecture 06, but we still have the limitation
;;      that this only works with a single byte.  The solution to that part
;;      will be covered when we get to arrays.
;;
;;============================================================================

section .data
hex	DW	0
	DB	10
prompt  DB      'Enter a number in the range of 0 - 255: ', 0
input	DB	'%d',0

section .bss
inbyte	resd	1		;  scanf will get an int

section .text
    global main                       ;must be declared for linker (ld)
    extern scanf
    extern printf

main:                                 ;tell linker entry point

;; We need a clean eax register
	mov	eax, 0
	
;; Get the value to convert
	push	prompt
	call	printf
	add	esp, 4

	push	inbyte
	push	input
	call	scanf			; scanf will but the value into binary for us.
	add	esp, 8

;; 
	mov 	al, byte [ inbyte ]     ; the number must fit into a single byte

;;	
	call    mkhex8
	mov	[hex], ax

;;
;;	getting fancy here, explain:
;;      We have the most significant nybble in the lower half of AX.
;;      When that gets transferred to memory, the two bytes will be reverse,
;;      because things are stored in little-endian format.  I have also
;;      put a CR in the following byte, so I don't have to write additional code to
;;      output the newline if it piggy-backs along, so I output one more byte.
;;
	mov	edx, 3                        
	mov	ecx, hex
	mov	ebx, 1
	mov	eax, 4
	int	80h	


;; The final part of the program must be a call to the operating system to exit
;; the program.
        mov     ebx,0   ;successful termination of program
        mov     eax,1   ;system call number (sys_exit)
        int     0x80    ;call kernel

;;============================================================================
;;
;; Analysis:  
;;      input:        AL holds a byte to convert to two hex digits
;;      output:       AL holds the high hex character
;;                    AH holds the low hex character
;;      formula:      Get the high nybble and put it into the low nybble.
;;                    convert using mkHex.
;; 		      Get the low nybble and convert it.
;;                    Store in memory in output order.
;;      constraints:  Number must be in the range of 0 to 255.
;;      assumptions:  No negative numbers will be attempted.
;;                    No range checking is necessary, because by definition
;;                    AL can only hold the proper values.
;;
;;============================================================================

mkhex8:
	push	cx		; Play nice and no not affect any register	
	push	dx		; except AX to return the results.

	push	ax
	and	al, 0F0h        ; Clear out the bottom four bits
	mov	cl, 4           ; Adjust the upper nybble so it is in bits 0-3
	shr	ax, cl
	call	mkHex
	mov	dl, al          ; Save it until the other character is converted.

;; Now we need to get back the original value and convert the bottom nybble.
	pop	ax
	and	al, 0Fh

	call	mkHex

;; Now set up to return the two characters, but put them into reverse order first.

	mov	ah, al
	mov	al, dl

	pop	dx		; Clean up your mess!
	pop	cx

	ret

;;============================================================================
;;
;; Analysis:  
;;      input:        AL holds the four bits that will be converted
;;                    to a single hex character 
;;      output:       AL holds the hex character
;;      formula:      0 becomes '0', the difference from zero is added to '0'
;;                    to get the hex digit.  Howver, there is a gap of
;;                    seven between '9' and 'A' that must be accounted for.
;;      constraints:  None
;;      assumptions:  AL holds a value for 0 to 15.
;;                    No output will be done in the subprogram
;;
;;============================================================================

mkHex:
;; The conversion algorithm starts here.

	cmp	al, 10                  ; Is this a digit or letter?
	jl	OK1
	add	al, 7                   ; There is a gap in the ASCII table to account for
OK1:
	add	al, '0'                 ; Convert to a hex character
	ret


©2004, Gary L. Burt