BITS 32
;---------------------------------------------------------------------
;Filename simpleio.asm
;
;In the file you'll find simple basic IO subroutines for writing to and
;reading from a Linux console.
;
;This file is created for Artvabas project:
;               Learning programming on a mathematics way of approach
;
;And it used for the lessons Assembly, for interaction with user input
;and showing the mathematical results on the screen.
;----------------------------------------------------------------------
;For using standard IO, we need the use abilitiy of the kernel. 
;In case of Linix we need to setup some registers and then send the
;interrupt 0x80. (0x80 interrupt for making system calls)
;register setup:
;               edx - the number of total characters to write or reading
;               ecx - the address of the first character of string or buffer
;               ebx - 1 > write to standards system file
;                     0 > read from standard system file
;                       (standard system file is usually the console)
;               eax - 4 > invoke Sys_write
;                     3 > invoke Sys_read
;----------------------------------------------------------------------
;subroutines in this file:
;       strlen     - for calculating the total characters in a null
;                    terminated string 
;       printstr   - for writing a null terminated string on the console
;       printstrlf - for writing a null terminated string with 
;                    linefeed attached on the console
;       exit       - terminating the program 
;----------------------------------------------------------------------
;Written by: Αρθούρος του Μπάστεν
;Aliases   : αρτηνρ - Uther Pendragon
;
;(c) 2022 www.artvabas.com 
;under approval of MIT License 
;-----------------------------------------------------------------------

section .data
    msg1 db 'What is your name? ',0x0 ;our test string
    msg2 db 'Your name is: ',0x0 
    error1 db 'ERROR (strlen) - String to print is empty!', 0x0

segment .bss
    inputstr: resb 255

section .text

global _start

_start:

    mov eax, msg1
    call printstrlf
    
    ;call readstr
    
    mov eax, msg2
    call printstr
    
    ;mov eax, inputstr
    ;call printstr
    
    
    mov eax, 0  ;Place the exit code 0 in eax (no error)
    call exit   ;Call the exit program routine

;------------------------------------------------------------------ 
;strlen - calculate the total amount of characters in a null terminated string 
;
;Recieves: EAX = address of the first character of the null terminated string
;Returns: EAX = Value with the total amount of characters
;
;Use: EBX = placeholder of the address of the first character of the string 
;-------------------------------------------------------------------
strlen:
    push ebx        ;Save current value on the stack
    mov ebx, eax    ;move the address of first character into ebx 
 
;loop for going through all the characters in string 
nextchar:
    cmp byte [eax], 0   ;compare the byte in eax against null (null means end of string)
    jz  finished        ;is zero flag set? Yes then jump to finished
    inc eax             ;increment the address Ina eax  by one byte
    jmp nextchar        ;jump to the beginning of this loop
 
finished:
    sub eax, ebx    ;Calculate the total amount of characters
                    ;eax -> last address [minus] ebx -> first address
                    ;after subtraction, eax holds total amount of characters 
    pop ebx         ;Restore ebx old value stored on the stack         
    ret             ;return the to the caller

;------------------------------------------------------------------ 
;printstr - Write a null terminated string on the console screen 
;
;Recieves: EAX = address of the first character of the null terminated string
;Returns: Nothing
;
;Use: EDX = placeholder of total amount of characters
;     ECX = placeholder of adress of the first character of the string 
;     EBX = 1 (Write to Stdout file)
;     EAX = process register (used for different purposes)
;-------------------------------------------------------------------
 
printstr:
    push edx    ;Store current register values on the stack
    push ecx
    push ebx

    mov ecx, eax    ;Move address of first character into ecx 
    call strlen     
                    
    cmp eax, 0      ;Compare value of eax against null. Does strlen returned empty?
    jz errorhandle1 ;If zero flag is set, jump to errrorhandle1. Yes, show error 
    
    mov edx, eax    ;Move total amount of characters into edx 
    mov ebx, 1      ;Write to Stdout file 
    mov eax, 4      ;invoke Sys_write (kernel opco 4)
    int 0x80        ;call the kernal with interrupt 0x80 (console)

    pop ebx     ;Restore all the old values back into their registers         
    pop ecx
    pop edx
    ret         ;Return to the caller
    
    ;strlen returned empry. There was no string to print, show error message
    errorhandle1:
        mov ecx, error1 ;Move address of first character of error message into ecx 
        mov eax, ecx    ;The same for EAX, is needed for strlen
        call strlen     
        mov edx, eax    ;Move total amount of characters into edx
        mov ebx, 1      ;Write to Stdout file  
        mov eax, 4      ;invoke Sys_write (kernal opco 4)
        int 0x80        ;call the kernal with interrupt 0x80 (console)
        mov eax, 1      ;Put number 1 in EAX, is needed for exit (1 means error)
        call exit       ;Call exit for terminating the program

;------------------------------------------------------------------ 
;printstrlf - Write a null terminated string with a linefeed on the console screen 
;
;Recieves: EAX = address of the first character of the null terminated string
;Returns: Nothing
;
;Use: ESP = Pointer to the last item that is pushed on the stack
;     EAX = Process register (all kind of purposes)
;-------------------------------------------------------------------
printstrlf:
    call printstr   ;First write the string to the console screen
    push eax        ;Store current register value to the stack
    mov eax, 0x0A   ;move the linefeed symbol into eax 
    push eax        ;Store the linefeed symbol on the stack
    mov eax, esp    ;move the address of last added item on the stack into eax (linefeed symbol)
    call printstr   ;eax hold now the address, so we can call printstr for printing the new-line symbol
    pop eax         ;Clear the stack
    pop eax 
    ret             ; return to caller

;------------------------------------------------------------------ 
;readstr -  
;
;Recieves: EAX = Exit code (0 means no error)
;Returns: Nothing
;
;Use: EBX = Placeholder for the exit code
;     EAX = 1 System_exit
;-------------------------------------------------------------------
readstr:
    mov edx, 255;Move total amount of buffer into edx 
    mov ecx, inputstr   ;Move the begin address of buffer into ecx  
    mov ebx, 0          ;Stdin file
    mov eax, 3          ; System_reard (kernel opcode 3)
    int 0x80            ;call the kernel with interrupt 0x80 (console)
    
    
;------------------------------------------------------------------ 
;exit - Exit the program 
;
;Recieves: EAX = Exit code (0 means no error)
;Returns: Nothing
;
;Use: EBX = Placeholder for the exit code
;     EAX = 1 System_exit
;-------------------------------------------------------------------
exit:
    mov ebx, eax    ;Move the exit code ebx
    mov eax, 1      ;invoke System_exit (kernel opco 1)
    int 0x80        ;call the kernal with interrupt 0x80 (console)

     

Assembly Online Compiler

Write, Run & Share Assembly code online using OneCompiler's Assembly online compiler for free. It's one of the robust, feature-rich online compilers for Assembly language. Getting started with the OneCompiler's Assembly compiler is simple and pretty fast. The editor shows sample boilerplate code when you choose language as Assembly and start coding.

About Assembly

Assembly language(asm) is a low-level programming language, where the language instructions will be more similar to machine code instructions.

Every assembler may have it's own assembly language designed for a specific computers or an operating system.

Assembly language requires less execution time and memory. It is more helful for direct hardware manipulation, real-time critical applications. It is used in device drivers, low-level embedded systems etc.

Syntax help

Assembly language usually consists of three sections,

  1. Data section

    To initialize variables and constants, buffer size these values doesn't change at runtime.

  2. bss section

    To declare variables

  3. text section

    _start specifies the starting of this section where the actually code is written.

Variables

There are various define directives to allocate space for variables for both initialized and uninitialized data.

1. To allocate storage space to Initialized data

Syntax

variable-name    define-directive    initial-value 
Define DirectiveDescriptionAllocated Space
DBDefine Byte1 byte
DWDefine Word2 bytes
DDDefine Doubleword4 bytes
DQDefine Quadword8 bytes
DTDefine Ten Bytes10 bytes

2. To allocate storage space to un-initialized data

Define DirectiveDescription
RESBReserve a Byte
RESWReserve a Word
RESDReserve a Doubleword
RESQReserve a Quadword
RESTReserve a Ten Bytes

Constants

Constants can be defined using

1. equ

  • To define numeric constants
CONSTANT_NAME EQU regular-exp or value

2. %assign

  • To define numeric constants.
%assign constant_name value

3. %define

  • To define numeric or string constants.
%define constant_name value

Loops

Loops are used to iterate a set of statements for a specific number of times.

mov ECX,n
L1:
;<loop body>
loop L1

where n specifies the no of times loops should iterate.

Procedures

Procedure is a sub-routine which contains set of statements. Usually procedures are written when multiple calls are required to same set of statements which increases re-usuability and modularity.

procedure_name:
   ;procedure body
   ret