0 Replies - 21659 Views - Last Post: 21 March 2015 - 12:48 PM

#1 jch053   User is offline

  • New D.I.C Head
  • member icon

Reputation: 6
  • View blog
  • Posts: 29
  • Joined: 20-December 14

NASM Convert Base 10 numbers to Binary and Hexadecimal

Posted 21 March 2015 - 12:48 PM

What we'll be doing is prompting the user for Base 10 input (a decimal number), holding the input value in our bx register, then we will convert that value to binary and hexadecimal.

First things first, lets get our data section out of the way since that isn't very technical. Your data section should contain your prompt as well as your "In binary, the number you entered is: " strings.

org        100h

section .data
    prompt1:    db    "Please enter a decimal number: $"
    prompt2:    db    0Dh, 0Ah, "In binary, the number you entered is: "
    prompt3:    db    0Dh, 0AHn "In hexadecimal, the number you entered is: "




Now we need to do some actual work. We'll start by printing the prompt for the user to input their number. We will use int 21h function 9 in order to display the prompt:

section .text
start:
    mov    ah, 9           ;prints the prompt
    mov    dx, prompt1     ;tells what to print
    int    21h




Now we need to get the user input. We're going to use a loop and read character by character until the character that the user has selected is the carriage return (Enter). which is ASCII code 13. You can find ASCII code values here. In order to read the character that the user is selecting, we'll use int 21h function 1 - the input character function. This next code section I'm going to type is fairly long, but I've commented every line so you can follow along easily. Comments in x86 assembly language start with ";"

;input base 10 value.

        mov        bx, 0        ;bx holds input value
        mov        ah, 1        ;input char function
        int        21h          ;read character into al
top1:                           ;while (char != Carriage return)
        cmp        al, 13       ;is char = Carriage return?
        je         out1         ;If so, we're finished with input, jump to out
        and        ax, 000Fh    ;convert from ASCII to base 10 value
        push       ax           ;save it to stack
        mov        ax, 10       ;set up to multiply bx by 10
        mul        bx           ;dx:ax=bx*10
        pop        bx           ;saved value in bx
        add        bx, ax       ;bx = old bx*10 + new digit

        mov        ah, 1        ;input char function again for next digit
        int        21h          ;read next char
        jmp        top1         ;loop until cmp al, 13 = true
out1:
        mov        ah,9         ;print binary output label
        mov        dx,prompt2   ;this is specified in .data section
        int        21h



Now that we have the number the user has selected, we need to convert it to binary. This is done by using a "for" loop and bit rotation. We will initialize our count register, cx, to 16 in order to loop through our "top2" loop 16 times. We will be using int 21h function 2 in order to print single characters. Again, I have commented line by line so you can understand what I am doing:

; for 16 times do this:
        mov       cx, 16        ;loop counter
        
top2:
        rol        bx, 1        ;rotate most significant bit into carry flag
        jc         one          ;does carry flag = 1?
        mov        dl, '0'      ;if not, set up to print a 0
        jmp        print        ;now print it
one:
        mov        dl, '1'      ;printing a 1 if 0 is not true
print:
        mov        ah, 2        ;print char fcn 
        int        21h          ;now print it
        loop       top2         ;loop until done




It's that easy to convert base 10 to binary, but let's kick it up a notch. You might think Hexadecimal numbers may be trickier due to the fact that it is not just ones and zeroes. Now we're using numbers 0-9 as well as letters A-F in order to construct numbers. Sounds hairy, but it actually isn't all that bad. Again, we'll be using int 21h function 2 in order to print single characters, but this time instead of putting 16 in our count register, we're only putting 4! It's also helpful to know what a nybble is in this situation. I've added a link to the word so you can read up on them. Again, commented line by line for easy reading (we're almost done!!):

        mov        cx, 4        ;loop counter

top3:
        rol        bx, 4        ;rotate top nybble into the bottom
        mov        dl, bl       ;put a copy in dl
        and        dl, 0Fh      ;we only want the lower 4 bits
        cmp        dl, 9        ;is it in [0-9]?
        ja         AF           ;if not, process characters [A-F]
        or         dl, 30h      ;convert 0-9 to '0'-'9'
        jmp        print2       ;now print

AF:
        add        dl, 55       ;convert 10-15 to 'A'-'F'

print2:
        mov        ah, 2        ;print character function
        int        21h          ;print it
        loop       top3         ;loop until done




And that's that. We've just converted Base-10 numbers to binary and hexadecimal. Now we just need to exit the program. This is pretty simple using int 21h function 04Ch -DOS function:

Exit:
        mov        ah, 04Ch     ;DOS function: Exit program
        mov        al, 0        ;Return exit code value
        int        21h          ;Call DOS. Terminate Program




All of this can be compiled in NASM using command line: nasm -f bin filename.asm -o filename.com

And you can run it in DOSbox by calling commands:
mount a ~/Path/To/Directory
a:
filename.com

Hope this helped!

Full code here:
org	100h

section .data
   prompt1: db	"Please enter a decimal number: $"
   prompt2: db	0Dh,0Ah, "In binary, the number you entered is:    $"
   prompt4: db	0Dh,0Ah, "In octal, the number you entered is:    $"
   prompt3: db	0Dh,0Ah, "In hexadecimal, the number you entered is:    $"

section .text
start:
	mov	    ah,9		    ; print prompt
	mov	    dx,prompt1
	int 	    21h

; input base 10 value
	mov   	    bx,0	      ; bx holds input value
	mov	    ah,1	      ; input char function
	int	    21h		      ; read char into al
top1:				      ; while (char != Carriage Return)
	cmp	    al,13	      ; is char = Carriage Return?
	je	    out1	      ; if so, we're done
	and	    ax,000Fh	      ; convert from ASCII to base 10 value
	push	    ax		      ; and save it on stack
	mov	    ax,10	      ; set up to multiply bx by 10
	mul	    bx		      ; dx:ax = bx*10
	pop   	    bx		      ; saved value in bx
	add	    bx,ax             ; bx = old bx*10 + new digit

        mov	    ah,1	      ; input char function
	int	    21h		      ; read next character
	jmp	    top1	      ; loop until done

; now, output it in binary
out1:
	mov	    ah,9	      ; print binary out text
	mov	    dx,prompt2
	int         21h

; for for i = 0, i < 16, i++:
	mov	    cx, 16            ; loop counter

top2:
        rol         bx,1              ; rotate most significant bit into carry flag
	jc    	    one		      ; carry flag = 1?
	mov    	    dl,'0'	      ;  if no, prepare to print 0
	jmp	    print             ; now print
one:
        mov    	    dl,'1'	      ; printing a 1
print:
        mov   	    ah,2	      ; print char function
	int	    21h		      ; print it
	loop	    top2	      ; loop until done

; output it again, only this time in hexadecimal
out3:
	mov	    ah,9	      ; print hex output label
	mov	    dx,prompt3
	int 	    21h

; for 4 times do this:
	mov    	    cx, 4             ; loop counter

top4:
        rol	    bx,4              ; rotate top nybble into the bottom
	mov	    dl,bl	      ; put a copy in dl
	and	    dl,0Fh            ; we only want the lower 4 bits
	cmp	    dl,9	      ; is it in [0-9]?
	ja	    AF	    	      ; if not, process [A-F]
	or	    dl,30h	      ; convert 0-9 to '0'-'9'
	jmp	    print2            ; now print

AF:
        add   	    dl,55	      ; convert 10-15 to 'A'-'F'

print2:
        mov	    ah,2	      ; print char
	int	    21h
	loop	    top4	     ; loop until done

Exit:
	mov         ah,04Ch          ;DOS function: Exit program
	mov         al,0             ;Return exit code value
	int         21h              ;Call DOS.  Terminate program



Is This A Good Question/Topic? 0
  • +

Page 1 of 1