x86-64 Linux汇编程序二次读取用户输入失效问题
x86-64 Linux汇编程序读取输入问题排查
我开发的x86-64架构Linux汇编程序中,首次读取用户输入的syscall执行正常,但在后续的_cels和_fahr分支中调用read系统调用读取温度值时,程序未等待用户输入就直接跳转回_start,无法获取温度输入。已在代码中标注出两个问题区域,并添加jmp _start语句用于调试,代码如下:
bits 64 global _start section .text _start: ;Setting mov rax, 1 mov rsi, unit mov rdx, unitlen syscall mov rax, 0 mov rsi, unitre ; assigns unitre in memory mov rdx, 1 syscall mov al, [unitre] ; gets the value of the first character through pointing at unitre ; which is the first pointer of the string cmp al, 'q' je exit cmp al, 'c' je _cels cmp al, 'f' je _fahr jmp exit _cels: mov rax, 1 mov rdi, 1 mov rsi, numC mov rdx, numClen syscall ; Problem area pt. 1 mov rax, 0 mov rdi, 1 mov rsi, numre mov rdx, 1 ;int 0x80 jmp _start ;convert numre to degrees fahrenheit mov rax, [numre] imul rax, 9 mov rbx, 5 idiv rbx add rax, 32 mov rax, 1 mov rdi, 1 mov rsi, numre mov rdx, numrelen syscall mov rsi, deg mov rdi, 1 mov rdx, degl syscall ;jmp _start _fahr: mov rax, 1 mov rdi, 1 mov rsi, numF mov rdx, numFlen syscall ; Problem area pt. 2 mov rax, 0 mov rdi, 1 mov rsi, numre mov rdx, numrelen syscall jmp _start ; Convert numre to degrees celsius mov rax, [numre] sub rax, 32 imul rax, 5 mov rbx, 9 idiv rbx mov rax, 1 mov rdi, 1 mov rsi, numre mov rdx, numrelen syscall mov rsi, deg mov rdi, 1 mov rdx, degl syscall ;jmp _start exit: ;Exits program mov rax, 60 xor rdi, rdi syscall section .data ;Conversion unit: db "Unit ('c' for Celsius or 'f' for Fahrenheit): ", 10 unitlen: equ $ - unit unitre: db "", 10 numC: db "Degrees(C): ", 10 numClen: equ $ - numC numF: db "Degrees(F): ", 10 numFlen: equ $ - numF numre: db "", 0 numrelen: equ $ - numre deg: db "degrees", 10 degl: equ $ - deg ;testing num1 db 1
我的目标是实现摄氏温度与华氏温度的转换,但目前无法获取用户输入的温度值,请求帮助排查问题。
问题排查与修复建议
核心问题点
- read系统调用的文件描述符错误:x86-64架构下,
read系统调用(rax=0)的第一个参数rdi需要传入文件描述符,标准输入的文件描述符是0,但代码中错误地使用了1(标准输出),导致读取操作无效,无法获取用户输入。 - 调试跳转语句直接跳过读取逻辑:
_cels和_fahr分支中,read调用后立刻执行jmp _start,直接跳回程序入口,程序根本没有机会等待用户输入完成,也无法执行后续的转换逻辑。 - 输入缓冲区容量不足:
numre仅定义了1字节的存储空间(db "",0),无法容纳多位数字的温度值,且numrelen计算结果为1,限制了读取长度,无法获取完整的输入。 - 未处理输入残留的换行符:首次读取单位时,用户输入字符后按回车,回车的换行符会留在输入缓冲区中,后续
read调用会直接读取这个换行符,导致程序误判为用户输入完成。
修复步骤
- 修正read调用的文件描述符:将两个问题区域中的
mov rdi, 1改为mov rdi, 0,指向标准输入。 - 移除调试用的跳转语句:删除
_cels和_fahr分支中read调用后的jmp _start,让程序执行完读取、转换和输出逻辑。 - 扩大输入缓冲区:修改
.data段中的numre定义为足够容纳多位数字的空间,例如:numre: db 10 dup(0) ; 预留10字节空间存储输入 numrelen: equ $ - numre - 处理输入残留的换行符:在首次读取单位后,添加额外的
read调用读取并丢弃输入缓冲区中的换行符,避免影响后续温度值的读取。 - 完善数值转换逻辑:当前代码直接对
numre中的ASCII字符进行运算,需要先将ASCII字符转换为数值(例如将'5'转换为5),运算完成后再将数值转换回ASCII字符输出。
内容的提问来源于stack exchange,提问作者Ghosttxii
相关产品推荐
相关产品推荐

