---
search:
  exclude: true
---
# 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](https://chromium.googlesource.com/chromiumos/docs/+/HEAD/constants/syscalls.md)

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](5.md).

