x86_64 nasm read syscall isn t null-terminated
New to assembly. In fact this is my first hello world program. OS: Arch Linux (64-bit)
Logic
I have three functions. strlen
, stdin
and stdout
.
strlen
:
Find s the length of a string by looping through bytes until it finds a null-byte.
www.un.org/spanish/ecosoc 仅使用读写的回忆。
First, I ask for the user s input with stdout
(not important)
Then I create an input prompt using stdin
stdin
puts the input inside the string rl
Lastly, stdout
attempts to print the input.
The issue
If you recall how strlen
works. It loops until it finds a null-byte.
However stdin
doesn t null-terminate it s input.
Therefore when stdout
goes to find the length of the input it won t stop at the end of the input and will continue collecting garbage until it comes across a null-byte. But by then you will have something looking like this:
What is your name?
Logan
Logan
��
@ @@%)@1+@7L@>a@O@J @V @]▒ @hello.asmstrrlstrlenstrlen_nextstrlen_nullstdinstdoutExitSuccess__bss_start_edata_end.symtab.strtab.shstrtab.text.datam! @ ▒ P
▒ h!b�!
简单的办法应当是在扼杀结束时只增加一个无尽的字句。 我怎么办? 而且,正如我在开始时所说的那样,聚集起来还有很多新东西...... 因此,你的ancy子只会恐吓我。
Full program
global _start
section .data
str: db "What is your name?", 10, 0 ; db: Define byte (8 bits)
; Declare hw to be "Hello, world!"
; 10 = "
" (newline character)
rl: db 0
section .text
_start:
mov rsi, str
call stdout ; Write to STDOUT
call stdin
call stdout
jmp ExitSuccess ; Return with exit code 0
strlen:
push rsi ; Save string to stack
strlen_next:
cmp [rsi], byte 0 ; Compare char to null byte
jz strlen_null ; Jump if null byte
inc rcx ; Char wasn t null, increment rcx (string length)
inc rsi ; Next char
jmp strlen_next ; Repeat, until we get a null byte
strlen_null:
pop rsi ; Load string from the stack
ret ; Return to call
stdin:
mov rax, 0
mov rdi, 0
mov rsi, rl
mov rdx, strlen
syscall
ret
stdout:
mov rax, 1 ; syscall write
mov rdi, 1 ; File descriptor STDOUT
call strlen ; String length of rsi
mov rdx, rcx ; Move strlen of rsi into rdx
syscall
ret
ExitSuccess:
mov rax, 60 ; syscall exit
mov rdi, 0 ; Move exit code into rdi
syscall