UMBC | CMSC 313 -- 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