计算数字偶数位和的汇编代码输出异常,请求技术排查
汇编代码错误排查:数字偶数位求和异常问题
用户提供的汇编代码:
global main section .data msgeven db "The sum of the even digits in the number is:",0 sum db 0 uc db 0 c db 0 num db 234 section .text main: mov ax,[num] _calculatesum: cmp ax,'0' je calculate_sum_done mov r8b,10 div r8b mov [uc],ah mov[c],al xor ebx,ebx mov bl,[uc] test bl,1 jnz _skip_odd_digit mov cl,[sum] add cl,bl _skip_odd_digit: jmp _calculatesum calculate_sum_done: add cl,'0' mov [sum],cl mov rax,1 mov rdi,1 mov rsi,msgeven mov rdx,50 syscall mov rax,1 mov rdi,1 mov rsi,sum mov rdx,1 syscall mov rax,60 mov rdi,0 syscall
问题描述
我编写了一段用于计算数字中偶数位之和的x86-64汇编代码,预期计算数字234的偶数位和为6,但运行程序后输出为‘The sum of the even digits in the number is:00�0’,无法得到正确结果,恳请帮忙排查错误原因。
错误点分析
- 数字存储与加载不匹配:
num db 234是字节型存储十进制234(对应十六进制0xEA),但代码用mov ax,[num]加载16位数据,会把num和后续的sum字节一起读入ax,导致初始数值错误。应将num改为16位定义:num dw 234,或者用mov al,[num]后零扩展到ax(xor ah,ah)。 - 循环终止条件错误:
cmp ax,'0'是将数值与字符'0'的ASCII码(0x30)比较,而ax中存储的是十进制数值,循环永远不会触发退出,会陷入死循环直到操作错误数据。正确终止条件应为cmp ax, 0,当数值被除至0时结束循环。 - 累加结果未保存:
add cl,bl完成偶数位累加后,没有将cl的值写回sum变量,导致每次循环sum始终是初始的0。需在add cl,bl后添加mov [sum],cl。 - 循环未更新被除数:每次除法后,商存在
al中并写入c变量,但未将商重新加载回ax,导致下一次循环仍使用原始ax值,无法处理高位数字。需在mov[c],al后添加mov ax,[c]。 - 字符串输出长度错误:
mov rdx,50指定的输出长度远大于msgeven实际长度,会输出后续内存中的垃圾数据(如sum、uc等变量内容),导致乱码。建议用自动计算长度的方式:
输出时使用msgeven db "The sum of the even digits in the number is:" msglen equ $ - msgevenmov rdx,msglen。
修正后的代码示例
global main section .data msgeven db "The sum of the even digits in the number is:" msglen equ $ - msgeven sum db 0 uc db 0 c db 0 num dw 234 ; 改为16位存储 section .text main: mov ax,[num] _calculatesum: cmp ax, 0 ; 改为判断数值是否为0 je calculate_sum_done mov r8b,10 div r8b mov [uc],ah mov [c],al mov ax,[c] ; 将商放回ax,继续处理高位 xor ebx,ebx mov bl,[uc] test bl,1 jnz _skip_odd_digit mov cl,[sum] add cl,bl mov [sum],cl ; 保存累加结果 _skip_odd_digit: jmp _calculatesum calculate_sum_done: mov cl,[sum] ; 重新读取最终sum值 add cl,'0' mov [sum],cl ; 输出提示字符串 mov rax,1 mov rdi,1 mov rsi,msgeven mov rdx,msglen ; 使用自动计算的长度 syscall ; 输出结果 mov rax,1 mov rdi,1 mov rsi,sum mov rdx,1 syscall ; 退出程序 mov rax,60 mov rdi,0 syscall
内容的提问来源于stack exchange,提问作者so_17
相关产品推荐
相关产品推荐

