Three small errors
section .data
text db "You wroted: "
text_len equ $ - text
A small spelling error (typo). Correct is: "You wrote: " without the d.
mov rax, SYS_READ
mov rdi, STDOUT
mov rsi, uinput
mov rdx, uinput_len
syscall
For SYS_READ you need to use STDIN instead of STDOUT.
mov rax, SYS_EXIT
mov rsi, 0 ; successful exit
syscall
The first parameter goes in the RDI
register instead of RSI
.
Three small improvements
section .bss
uinput resb 24 ; 24 bytes for user string
uinput_len equ $ - uinput ; get length of user input
It's strange to see a calculation for the uinput_len variable given that the length is a hardcoded 24. What you can write is:
section .bss
uinput_len equ 24 ; 24 bytes for user input
uinput resb uinput_len
Be nice for the person that uses your program and show a prompt of some kind before expecting an input.
For the final result you currently show the whole inputbuffer. What if the user didn't input that much characters? Best to only show the characters that were effectively inputted. You obtain this count in the RAX
register upon returning from SYS_READ. e.g. If the user inputs 5 characters then RAX
will hold 6. Those 5 characters plus the terminating newline character (0Ah).
Same code, different style
You should offset you tail comments so that they all start in the same column. This will improve readability.
And because readability is very very important, I've applied the same rule to the labels, mnemonics, and operands.
SYS_READ equ 0 ; read text from stdin
SYS_WRITE equ 1 ; write text to stdout
SYS_EXIT equ 60 ; terminate the program
STDIN equ 0 ; standard input
STDOUT equ 1 ; standard output
; --------------------------------
section .bss
uinput_len equ 24 ; 24 bytes for user input
uinput resb uinput_len ; buffer for user input
; --------------------------------
section .data
prompt db "Please input some text: "
prompt_len equ $ - prompt
text db 10, "You wrote: "
text_len equ $ - text
; --------------------------------
section .text
global _start
_start:
mov rdx, prompt_len
mov rsi, prompt
mov rdi, STDOUT
mov rax, SYS_WRITE
syscall
mov rdx, uinput_len
mov rsi, uinput
mov rdi, STDIN
mov rax, SYS_READ
syscall ; -> RAX
push rax ; (1)
mov rdx, text_len
mov rsi, text
mov rdi, STDOUT
mov rax, SYS_WRITE
syscall
pop rdx ; (1)
mov rsi, uinput
mov rdi, STDOUT
mov rax, SYS_WRITE
syscall
xor edi, edi ; successful exit
mov rax, SYS_EXIT
syscall
Instead of mov rdi, 0
, I've used xor edi, edi
which is shorter and faster and leaves the same result (0) in the RDI
register.
I always prefer to write the function number directly above the syscall
instruction. I find this clearer. As a consequence I've also inversed the order of the other parameters, again for clarity.
You can learn a lot about 64-bit Linux programming from the .PDF that you can download here
It provides good examples that deal with console input and console output and more.