汇编字符计数程序输出始终为0的错误排查请求
汇编字符计数程序输出始终为0的错误排查请求
嗨,我帮你排查下这段x86-64汇编代码里的问题,你遇到的输出始终为0的情况,主要是这几个关键错误导致的:
1. print 函数中输出地址的错误
这是导致输出0的核心问题!在你的print函数里,你写了:
mov rsi, [buffer2]
sys_write系统调用要求rsi是输出缓冲区的内存地址,而不是缓冲区里存储的值。你现在的写法是把buffer2里的内容(也就是你转成ASCII的计数值)当成了地址,这会导致系统去错误的内存位置读取数据,大概率读出来的是0,所以输出始终为0。
应该改成直接使用buffer2的地址:
mov rsi, buffer2
2. 循环计数的逻辑冗余且顺序有误
你的loop_start循环里有重复的换行符判断,而且逻辑顺序会导致计数不准确:
loop_start: mov al, [rdi + rbx] cmp al, 0x0a je found inc rcx inc rbx cmp al, 0x0a ; 这里的判断完全多余,而且al的值还是上一次的 jne loop_start
第二个cmp al, 0x0a完全没必要,因为如果第一个判断没跳走,说明当前字符不是换行符,直接跳回循环开头取下一个字符就行。修正后的循环应该是:
loop_start: mov al, [rdi + rbx] cmp al, 0x0a ; 先判断是不是换行符 je found ; 是就跳出循环 inc rcx ; 不是就计数+1 inc rbx ; 指针后移一位 jmp loop_start ; 继续循环
3. 换行符定义错误
你定义的newline是字符串"0a",这对应的是ASCII字符'0'和'a',而不是换行符的十六进制值0x0a。正确的定义应该是:
newline db 0x0a newline_len equ $ - newline
修正后的完整代码
section .data msg db "Enter the text: ", 0 msg_len equ $ - msg newline db 0x0a newline_len equ $ - newline section .bss buffer1 resb 100 buffer2 resb 2 section .text global _start _start: ; 提示输入 mov rax, 1 mov rdi, 1 mov rsi, msg mov rdx, msg_len syscall ; 获取输入 mov rax, 0 mov rdi, 0 mov rsi, buffer1 mov rdx, 100 syscall ; 字符计数部分 mov rdi, buffer1 xor rcx, rcx ; 计数器清零 xor rbx, rbx ; 偏移量清零 loop_start: mov al, [rdi + rbx] cmp al, 0x0a je found inc rcx inc rbx jmp loop_start found: add rcx, '0' ; 转成ASCII字符(注意:这里只支持计数0-9,超过10需要多位数处理) mov [buffer2], rcx call print print: ; 输出计数结果 mov rax, 1 mov rdi, 1 mov rsi, buffer2 ; 这里改为直接传buffer2的地址 mov rdx, 1 syscall ; 输出换行 mov rax, 1 mov rdi, 1 mov rsi, newline mov rdx, newline_len syscall call exit exit: ; 退出程序 mov rax, 60 mov rdi, 0 syscall
另外补充一点:当前代码只支持计数0-9的情况,如果输入字符数超过10,转ASCII的逻辑需要修改(比如拆分十位和个位),不过这是后续功能扩展的问题啦。
备注:内容来源于stack exchange,提问作者BL4CKF0Xk
相关产品推荐
相关产品推荐

