x86架构Debian系统下,如何获取汇编输入字符串的长度?
x86汇编中读取输入长度并输出的问题修复
代码中的核心问题
- 输出参数错误:
get_length标签里的mov ecx, [input_length]完全错误——system_write(eax=4)要求ecx是字符串的内存地址,你这里传的是读取到的长度数值,系统会把这个数值当作内存地址去读,大概率是非法地址,因此没有输出。 - 长度存储的位数不匹配:
input_length定义为resb 1(1字节),但eax是32位寄存器,执行mov [input_length], eax只会存储eax的低8位,虽然当前输入最多10字节不会出问题,但规范上应该用resd 1(4字节)来存储32位的返回值。 - 跳转逻辑错误:
cmp edx, 10毫无意义,因为edx就是你设置的最大读取数10,永远相等,jl get_length永远不会触发。你应该比较的是eax(实际读取的字节数)和10,判断是否读满缓冲区。 - 输出长度错误:
system_write的edx应该传实际读取的长度(eax中的数值),而非固定10,否则会输出缓冲区里的垃圾数据。
修复后的代码
section .data filename db 'test.txt' introduce db 'Put file name here: ' introduce_len equ $ - introduce ; 自动计算字符串长度,避免硬编码 section .bss input resb 10 input_length resd 1 ; 用4字节存储32位的长度值 section .text global _start _start: ; 打印提示文本 mov eax, 4 ; system_write mov ebx, 1 ; std_out mov ecx, introduce mov edx, introduce_len ; 使用自动计算的长度,更可靠 int 0x80 ; 读取用户输入 mov eax, 3 ; system_read mov ebx, 0 ; std_in mov ecx, input mov edx, 10 ; 最多读10字节 int 0x80 ; 保存实际读取的长度 mov [input_length], eax ; 判断是否读满缓冲区(可选,根据你的错误提示需求) cmp eax, 10 jl get_length ; 如果读取长度小于10,说明输入没填满缓冲区(用户按了回车) ; 这里可以添加输入过长的错误提示逻辑 get_length: ; 打印用户输入 mov eax, 4 ; system_write mov ebx, 1 ; std_out mov ecx, input ; 传输入字符串的地址,不是长度! mov edx, [input_length] ; 传实际读取的长度 int 0x80 ; 退出程序 mov eax, 1 int 0x80
关键说明
system_read(eax=3)执行后,eax寄存器会返回实际读取的字节数(包含用户输入的换行符),这就是你需要的输入长度,直接存入input_length即可。- 打印输入时,ecx必须是
input的内存地址,edx用实际读取的长度,才能正确输出用户输入的内容。 - 用
introduce_len equ $ - introduce自动计算提示文本的长度,比硬编码数值更可靠,修改文本后无需手动调整长度值。
内容的提问来源于stack exchange,提问作者skami0_0
相关产品推荐
相关产品推荐

