x86_64 nasm read syscall不是空终止的
新到装配。这是我的第一个Hello World程序。操作系统:Arch Linux(64位)
逻辑
我有三个功能。strlen
、stdin
和stdout
。strlen
:通过循环字节直到找到空字节来查找字符串的长度。stdin
和stdout
只使用读和写系统调用。
首先,我用stdout
请求用户的输入(不重要),然后我用stdin
stdin
创建一个输入提示,将输入放在字符串rl
中,最后,stdout
尝试打印输入。
问题
如果你还记得strlen
是如何工作的。它循环直到找到一个空字节。但是stdin
不会空终止它的输入。因此,当stdout
去寻找输入的长度时,它不会在输入的末尾停止,并且会继续收集垃圾,直到遇到空字节。但到那时,你会看到这样的东西:
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�!'
简单的解决方法应该是在字符串的末尾添加一个空字节。我怎么能这么做呢?就像我一开始说的,对组装来说很新...所以你的行话只会吓到我。
完整程序
global _start
section .data
str: db "What is your name?", 10, 0 ; db: Define byte (8 bits)
; Declare hw to be "Hello, world!"
; 10 = "\n" (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
1条答案
按热度按时间ghhkc1vu1#
必须做出两项改变:首先,我需要修复
strlen
函数。(我已经重命名为_strlen
)问题是,我忘记了设置rcx
为零之前,我开始计数,最后,直接在我们做stdin
的syscall
,然后添加一个空字节在缓冲区的末尾。(mov byte [rsi+rax-1], 0
)