UMBC CMSC 313 -- Assembly Language Segment Previous | Next


An Application -- Outputing Hex Values Without printf

Let's look at the situation where we want to output a hexadecimal representation of a byte, without using printf. Originally, we looked at using a System Call and INT 80h. We will use that here. First we have to set up the registers.
	mov	edx, 1          ; How much are we going to output
	mov	ecx, hex        ; Where is what we are going to output
	mov	ebx, 1          ; Which file are we going to use
                                ; 1 is stdout
	mov	eax, 4          ; Use system call number 4
	int	80h             ; Just do it!

We have not studied subprograms, arrays, and system calls yet, so we will do this by brute force. This is not a good way to do this, obviously. But it is a good lead-in for the next lecture.

Algorithm

We will convert a byte by taking the high four bits, shifting them into the low four bits (which clears out the low nybble), and convert it to ASCII. We will then print it out with the write system call. If it is in the range of 0Ah to 0Fh, we must adjust the ASCII character because there is a gap in the ASCII code between '9' (39h) and 'A' (41h) of eight positions.

After we print the high nybble, then we will convert the low nybble.The low nybble does not need the high nybble, so we clear it out with an AND instruction. The we we repeat what we did before. We will convert it to ASCII. We will then print it out with the write system call.If it is in the range of 0Ah to 0Fh, we must adjust the ASCII character because there is a gap in the ASCII code between '9' (39h) and 'A' (41h) of eight positions.

Finally, we will print out a new line character for a nice display.

The code


section .data
hex	DB	0
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
	
	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

;; 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
	mov	[hex], al               ; Save it in the output buffer

;; Use the write system call to output our hex character
	mov	edx, 1                  ; How much are we going to output
	mov	ecx, hex                ; Where is what we are going to output
	mov	ebx, 1                  ; Which file are we going to use
                                        ; 1 is stdout
	mov	eax, 4                  ; Use system call number 4
	int	80h                     ; Just do it!

;; Now we need to get back the original value and convert the bottom nybble.

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

	and	al, 0Fh

;; Now just repeat what we did before.......BAD EXAMPLE
;; NEVER WRITE THE SAME CODE TWICE!!!!

	cmp	al, 10
	jl	OK2
	add	al, 7
OK2:
	add	al, '0'
	mov	[hex], al

	mov	edx, 1
	mov	ecx, hex
	mov	ebx, 1
	mov	eax, 4
	int	80h	

	mov	byte [hex], 10  	; start a new line
	mov	edx, 1
	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


Areas for improvement

Repeated Code

Converting the low four bits was done twice. As you know, that should have been a subprogram! It is easy to do.

Specific Solution

This only works for a byte and requires a one-byte buffer be allocated for that purpose. Does not work with words, double words, or quad words.

Performed Output

General solutions let the caller do the output, allowding for a more general solution.


Previous | Next

©2004, Gary L. Burt