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