CSC231 Printing & Inputting Decimal Numbers in Assembly
--D. Thiebaut (talk) 16:16, 20 September 2014 (EDT)
This page presents two program that will display a byte, word, and double word in decimal. This code will work on 32-bit and 64-bit Linux machines.
There are 2 programs:
- testLib.asm, the test program
- 231Lib.asm, the library containing I/O functions
To assemble, link, and run the programs, execute the following commands:
nasm -f elf 231Lib.asm nasm -f elf testLib.asm ld -melf_i386 testLib 231Lib ./testLib x = 127 y = 10000 z = 100000
231Lib.asm
;;; A simple I/O library for CSC231.
;;; (This library can be expanded as needed)
;;; D. Thiebaut
;;; Taken from Swarnali Ahmed's 2002 program: mytools.inc
;;; http://cs.smith.edu/dftwiki
;;;
;;; Contains several functions for performing simple I/O of
;;; data.
;;; _printDec: function that prints an integer on the screen
;;; _printString: function that prints a string on the screen
;;; _println: moves the cursor to the next line on the screen
%assign SYS_EXIT 1
%assign SYS_WRITE 4
%assign STDOUT 1
global _printDec
global _printString
global _println
section .text
;;; ;------------------------------------------------------
;;; ;------------------------------------------------------
;;; ; _printDec: takes the double word in eax and prints it
;;; ; to STDOUT in decimal.
;;; ;
;;; ; Examples:
;;; ; print a byte variable
;;; ; mov eax, 0
;;; ; mov al, byte[someVar]
;;; ; call _printDec
;;; ;
;;; ; print a word variable
;;; ; mov eax
;;; ; mov ax, word[otherVar]
;;; ; call _printDec
;;; ;
;;; ; print a double-word variable
;;; ; mov eax, dword[thirdVar]
;;; ; call _printDec
;;; ;
;;; ; print register edx in decimal
;;; ;
;;; ; mov eax, edx
;;; ; call _printDec
;;; ;
;;; ;REGISTERS MODIFIED: NONE
;;; ;------------------------------------------------------
;;; ;------------------------------------------------------
_printDec:
;;; saves all the registers so that they are not changed by the function
section .bss
.decstr resb 10
.ct1 resd 1 ; to keep track of the size of the string
section .text
pushad ; save all registers
mov dword[.ct1],0 ; assume initially 0
mov edi,.decstr ; edi points to decstring
add edi,9 ; moved to the last element of string
xor edx,edx ; clear edx for 64-bit division
.whileNotZero:
mov ebx,10 ; get ready to divide by 10
div ebx ; divide by 10
add edx,'0' ; converts to ascii char
mov byte[edi],dl ; put it in sring
dec edi ; mov to next char in string
inc dword[.ct1] ; increment char counter
xor edx,edx ; clear edx
cmp eax,0 ; is remainder of division 0?
jne .whileNotZero ; no, keep on looping
inc edi ; conversion, finish, bring edi
mov ecx, edi ; back to beg of string. make ecx
mov edx, [.ct1] ; point to it, and edx gets # chars
mov eax, SYS_WRITE ; and print!
mov ebx, STDOUT
int 0x80
popad ; restore all registers
ret
;;; ; ------------------------------------------------------------
;;; ; _printString: prints a string whose address is in
;;; ; ecx, and whose total number of chars
;;; ; is in edx.
;;; ; Examples:
;;; ; Assume a string labeled msg, containing "Hello World!",
;;; ; and a constant MSGLEN equal to 12. To print this string:
;;; ;
;;; ; mov ecx, msg
;;; ; mov edx, MSGLEN
;;; ; call _printSTring
;;; ;
;;; ; REGISTERS MODIFIED: NONE
;;; ; ------------------------------------------------------------
;;; ;save eax and ebx so that it is not modified by the function
_printString:
push eax
push ebx
mov eax,SYS_WRITE
mov ebx,STDOUT
int 0x80
pop ebx
pop eax
ret
;;; ; ------------------------------------------------------------
;;; ; _println put the cursor on the next line.
;;; ;
;;; ; Example:
;;; ; call _println
;;; ;
;;; ; REGISTERS MODIFIED: NONE
;;; ; ------------------------------------------------------------
_println:
section .data
.nl db 10
section .text
push ecx
push edx
mov ecx, .nl
mov edx, 1
call _printString
pop edx
pop ecx
ret
testLib.asm
;;; -----------------------------------------------------
;;; testLib.asm
;;; D. Thiebaut
;;; Simple demo program for simple I/O operations
;;;
;;; To assemble, link and run:
;;; nasm -f elf 231Lib.asm
;;; nasm -f elf testLib.asm
;;; ld -melf_i386 testLib 231Lib
;;; ./testLib
;;; -----------------------------------------------------
;;; extern functions that will be linked to this program
;;; contained in 231Lib.asm
extern _printDec
extern _printString
extern _println
;;; -----------------------------------------------------
;;; data section
;;; -----------------------------------------------------
section .data
x db 127
y dw 10000
z dd 100000
msgX db "x = "
msgY db "y = "
msgZ db "z = "
;;; -----------------------------------------------------
;;; code section
;;; -----------------------------------------------------
section .text
global _start
_start:
;;; display x
mov ecx, msgX
mov edx, 4
call _printString
mov eax, 0
mov al, byte[x]
call _printDec
call _println
;;; display y
mov ecx, msgY
mov edx, 4
call _printString
mov eax, 0
mov ax, word[y]
call _printDec
call _println
;;; display z
mov ecx, msgZ
mov edx, 4
call _printString
mov eax, dword[z]
call _printDec
call _println
;;; ; exit
mov ebx, 0
mov eax, 1
int 0x80