CSC231 Printing & Inputting Decimal Numbers in Assembly

From dftwiki3
Revision as of 15:19, 20 September 2014 by Thiebaut (talk | contribs) (231Lib.asm)
Jump to: navigation, search

--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