Assembly x86_64 - User Input

Assembly Code

We're going to use vim to write our code


[ 192.168.0.18/24 ] [ /dev/pts/88 ] [~/binexp/asm]
→ vim 4.asm


section .data
        mytext1 db "What is your name? "
        mytext2 db "Hello, "

section .bss
        myname resb 16  ; we reserve 16 bytes and we can access it with the label 'myname'

section .text
        global _start

_start:
        call _printText1
        call _getName
        call _printText2
        call _printName


        mov rax, 60
        mov rdi, 0
        syscall


_printText1:            ;print 'what your the name ?'
        mov rax, 1              ; syscall ID 1 (write text)
        mov rdi, 1              ; first arg  = 1
        mov rsi, mytext1        ; second arg = our text1 (what is your name?)
        mov rdx, 19             ; third arg  = the text limit
        syscall                 ;run the syscall
        ret             ; finish the function

_getName:               ;get user input
        mov rax, 0              ; syscall ID 0 (read user input)
        mov rdi, 0              ; first arg 0 is stdin, 1 is stdout, 2 is stderr
        mov rsi, myname         ; second arg (where will we store user input?)
        mov rdx, 16             ; third arg the limit of user input characters we want
        syscall         ;make the syscall
        ret             ;finish the function

_printText2:            ;print 'Hello'
        ;same as printtext1
        mov rax, 1
        mov rdi, 1
        mov rsi, mytext2
        mov rdx, 7
        syscall
        ret

_printName:             ;print the name
        ;same as pritntext 1 and 2
        mov rax, 1
        mov rdi, 1
        mov rsi, myname ; this is the myname label with it's 16 reserved bytes from earlier
        mov rdx, 16
        syscall
        ret

Now this code contains what we learned previously, with the exception of the following chunks of code:


section .bss
        myname resb 16 

this is used to declare a variable called 'myname' and we reserve 16 bytes for it. Ideally to store our user input string of text.


_getName:               
        mov rax, 0              ; syscall ID 0 (read user input)
        mov rdi, 0              
        mov rsi, myname         
        mov rdx, 16     
        syscall         
        ret             

The _getName function first sets the rax register as 0 (syscall ID 0) to read the user input, more info here

the first arguement (rdi) is set to 0 because we want stdin (1 is stdout and 2 is stderr)

the second arguement (rsi) is the variable we want to store our user input to,

the third arguement (rdx) is set to 16 because that is the maximum size of reserved bytes for our 'myname' variable.

and lastly we just run the syscall and end the function.

Compiling

Here we're going to use nasm to compile our assembly code and then use ld to create the binary out of the .o file:


[ 192.168.0.18/24 ] [ /dev/pts/89 ] [~/binexp/asm]
→ nasm -f elf64 4.asm -o 4.o

[ 192.168.0.18/24 ] [ /dev/pts/89 ] [~/binexp/asm]
→ ld 4.o -o 4

[ 192.168.0.18/24 ] [ /dev/pts/89 ] [~/binexp/asm]
→ ./4
What is your name? Pierre
Hello, Pierre


And that's it ! in the next tutorial we will cover math operations and the stack, you can click here.