为何这段NASM代码中用rax而非rdx存储read宏读取的字符串长度?
为何NASM汇编中read系统调用后用rax而非rdx记录输入长度?
在以下NASM汇编代码中,read宏调用系统调用后直接将rax的值存入[count]以记录输入字符串的长度,但我认为应将rdx的值移入rax后再存储(附原代码与修改后代码),请问为何原代码使用rax而非rdx存储字符串长度?
原代码
section .data msg db 10 "Enter string" msg_len equ $-msg smsg db 10 "Length is: " smsg_len equ $-smsg section .bss char_ans resb 2 string resb 50 string_len equ $-string count resb 1 ;---------------------------------- %macro print 2 mov rax, 1 mov rdi, 1 mov rsi, %1 mov rdx, %2 syscall %endmacro %macro read 2 mov rax, 0 mov rdi, 0 mov rsi, %1 mov rdx, %2 syscall %endmacro %macro exit 0 mov rax, 60 mov rsi, 0 syscall %endmacro ;---------------------------------- section .text global _start _start: print msg, msg_len read string, string_len mov [count], rax print smsg, smsg_len mov rax, [count] call display exit display: mov rbx, 16 mov rcx, 2 mov rsi, char_ans+1 cnt: mov rdx, 0 div rbx cmp dl, 09h jbe add30 add dl,37h add30: add dl, 30h mov [rsi], dl dec rsi dec rcx jnz cnt print char_ans, 2 ret
修改后的代码(我的思路)
section .text global _start _start: print msg, msg_len read string, string_len mov rax, rdx ;VALUE OF RDX MOVED TO RAX SINCE string_leN STORED IN rdx mov [count], rax print smsg, smsg_len mov rax, [count] call display exit
解答
这是因为Linux系统调用的返回值规则:
- 调用
read系统调用时(通过rax=0指定),内核会将实际读取到的字节数返回在rax寄存器中,这个值包含用户输入的所有字符,包括换行符。 - 你传入的
rdx是调用read时的输入参数,它表示允许读取的最大字节数(也就是string_len定义的50),这个值在系统调用过程中不会改变。如果用户输入的字符串长度小于50,rdx仍然是50,显然不能用来表示实际输入长度。
举个实际场景:如果用户只输入了"hello"加换行,那么rax会返回6(5个字符+1个换行符),而rdx还是50,这时候只有rax的值是真实的输入长度。
额外说明:如果read系统调用出错,rax会返回负数(错误码的补码形式),原代码没有处理这种异常情况,但不影响核心逻辑——rax确实是Linux规定的用来返回read实际读取长度的寄存器。
内容的提问来源于stack exchange,提问作者Nitin Pandita
相关产品推荐
相关产品推荐

