NASM Coding: More Programs

  1. ; A program that takes an input (integer) from the user, and prints its square to stdout.
    ; Example: If the user entered 3 as the input, the output will be:
    ; 9
    
    section .data
        newline db 10
    
    section .bss
        buffer resb 32  ; input buffer
        outbuf resb 32  ; output buffer
    
    section .text
        global _start
    
    _start:
    
        ; Read the input
        mov rax, 0      ; sys_read
        mov rdi, 0      ; stdin
        mov rsi, buffer
        mov rdx, 32
        syscall         ; rax = number of bytes read
    
        ; ASCII to integer
        mov rsi, buffer
        xor rax, rax    ; result = 0
    
    convert_loop:
        movzx rbx, byte [rsi]
    
        cmp rbx, 10     ; newline?
        je convert_done
    
        cmp rbx, 0      ; null terminator?
        je convert_done
    
        ; Convert character, e.g., '5', to 5d
        sub rbx, '0'
    
        imul rax, 10
        add rax, rbx
    
        inc rsi
        jmp convert_loop
    
    convert_done:
    
        ; Square the number
        imul rax, rax          ; rax = rax * rax
    
        ; Integer to string
        mov rbx, 10
        ; lea: store the address [outbuf + 31] (not the content) in rdi
        lea rdi, [outbuf + 31] ; point to end of buffer
    
        mov byte [rdi], 0      ; optional null terminator
        dec rdi                ; move back for digits
    
        ; handle zero explicitly
        cmp rax, 0
        jne convert_out
    
        mov byte [rdi], '0'
        dec rdi
        jmp conversion_done
    
    convert_out:
        xor rdx, rdx
        div rbx                ; rax = quotient, rdx = remainder
    
        add rdx, '0'
        mov [rdi], dl
    
        dec rdi
    
        cmp rax, 0
        jne convert_out
    
    conversion_done:
        inc rdi                ; rdi now points to start of string
    
        ; Compute string length
        mov rsi, rdi           ; start of string
    
        ; lea: store the address [outbuf + 32] (not the content) in rdx
        lea rdx, [outbuf + 32]
        sub rdx, rsi           ; length = end - start
    
        ; Print square result
        mov rax, 1             ; sys_write
        mov rdi, 1             ; stdout
        syscall
    
        ; Print newline
        mov rax, 1
        mov rdi, 1
        mov rsi, newline
        mov rdx, 1
        syscall
    
        ; Exit
        mov rax, 60
        xor rdi, rdi ; Same as rdi = 0;
        syscall