| 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