You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写比较两数的汇编代码遇问题:仅比较数字最后一位

汇编多位数比较错误修复:仅比较最后一位问题

问题描述

我正在编写一段用于比较两个数字的汇编代码,目前该代码仅能正确处理单数字输入。当输入两位数时会出现错误:例如输入25和12时输出25,但输入21和13时却输出13。经排查发现,程序仅比较数字的最后一位(如25和12比较5和2,21和13比较1和3),而非整个数字。

原始代码

section .text
     global _start
_start:
;Prompt user to input first number
mov eax , 4
mov ebx , 1
mov ecx , msg1
mov edx , lenmsg1
int 0x80

;input first number
mov eax, 3
mov ebx, 2
mov ecx,num1
mov edx, 5
int 0x80

;prompt user to input second number
mov eax, 4
mov ebx, 1
mov ecx, msg2
mov edx, lenmsg2
int 0x80

;input second number
mov eax, 3
mov ebx, 2
mov ecx, num2
mov edx, 5
int 0x80

mov ecx, [num1]
CMP ecx ,[num2]
JG outcondition
;resmsg
mov eax, 4
mov ebx, 1
mov ecx, resmsg
mov edx, lenresmsg
int 0x80

;resultmsg
mov ecx, num2
mov eax , 4
mov ebx, 1
mov ecx, ecx
mov edx ,2
int 0x80

JMP exit


outcondition:
mov ecx , num1
mov eax, 4
mov ebx, 1
mov ecx, resmsg
mov edx, lenresmsg
int 0x80

;resultmsg
mov ecx, num1
mov eax , 4
mov ebx, 1
mov ecx,ecx
mov edx ,2
int 0x80

exit:
mov eax, 1
int 0x80


section .bss
num1 resb 5
num2 resb 5

section .data
msg1 db "Enter your first number ", 0xA , 0xD
lenmsg1 equ $ - msg1

msg2 db "Enter your second number ", 0xA , 0xD
lenmsg2 equ $ - msg2

resmsg db "The bigger number is " , 0xA , 0xD
lenresmsg equ $ - resmsg

问题根源

你直接通过CMP ecx, [num2]比较内存中的原始输入数据,但输入的数字是以ASCII字符串形式存储的(比如"25"对应ASCII码0x32 0x35,加上换行符0x0A)。直接比较双字内存值时,是把这些字节当作无符号整数对比,这和数值大小的逻辑完全不符。单数字能正常工作只是因为单个数字的ASCII值和数值大小正相关('0'-'9'对应0x30-0x39)。

修复方案

需要先将ASCII字符串转换为整数,再进行数值比较。以下是修改后的代码:

section .text
     global _start
_start:
; Prompt user to input first number
mov eax, 4
mov ebx, 1
mov ecx, msg1
mov edx, lenmsg1
int 0x80

; Input first number
mov eax, 3
mov ebx, 2
mov ecx, num1
mov edx, 5
int 0x80

; Convert first string to integer
mov ecx, num1
call str_to_int
mov [num1_val], eax

; Prompt user to input second number
mov eax, 4
mov ebx, 1
mov ecx, msg2
mov edx, lenmsg2
int 0x80

; Input second number
mov eax, 3
mov ebx, 2
mov ecx, num2
mov edx, 5
int 0x80

; Convert second string to integer
mov ecx, num2
call str_to_int
mov [num2_val], eax

; Compare the two integers
mov eax, [num1_val]
cmp eax, [num2_val]
jg print_num1

; Print result for num2
mov eax, 4
mov ebx, 1
mov ecx, resmsg
mov edx, lenresmsg
int 0x80

mov eax, 4
mov ebx, 1
mov ecx, num2
; Find length of num2 (until newline)
mov edx, 0
count_num2:
cmp byte [num2 + edx], 0xA
je count_num2_done
inc edx
jmp count_num2
count_num2_done:
int 0x80
jmp exit

print_num1:
; Print result for num1
mov eax, 4
mov ebx, 1
mov ecx, resmsg
mov edx, lenresmsg
int 0x80

mov eax, 4
mov ebx, 1
mov ecx, num1
; Find length of num1 (until newline)
mov edx, 0
count_num1:
cmp byte [num1 + edx], 0xA
je count_num1_done
inc edx
jmp count_num1
count_num1_done:
int 0x80

exit:
mov eax, 1
int 0x80

; String to integer function
; Input: ecx = pointer to ASCII string
; Output: eax = integer value
str_to_int:
mov eax, 0
mov esi, 0
loop_start:
movzx ebx, byte [ecx + esi]
cmp ebx, 0xA  ; Check for newline (end of input)
je loop_end
cmp ebx, 0x20  ; Check for space (ignore)
je skip_char
; Convert ASCII digit to number (subtract 0x30)
sub ebx, 0x30
; Multiply current value by 10 and add new digit
imul eax, 10
add eax, ebx
skip_char:
inc esi
jmp loop_start
loop_end:
ret

section .bss
num1 resb 5
num2 resb 5
num1_val resd 1  ; Store integer value of num1
num2_val resd 1  ; Store integer value of num2

section .data
msg1 db "Enter your first number: ", 0xA, 0xD
lenmsg1 equ $ - msg1

msg2 db "Enter your second number: ", 0xA, 0xD
lenmsg2 equ $ - msg2

resmsg db "The bigger number is: ", 0xA, 0xD
lenresmsg equ $ - resmsg

关键修改点

  1. 字符串转整数函数:新增str_to_int函数,遍历ASCII字符串,将每个字符转换为数字并累加为整数,自动跳过空格和终止于换行符。
  2. 存储数值:在.bss段添加num1_val和num2_val存储转换后的整数。
  3. 数值比较:基于转换后的整数进行cmp和jg判断,确保逻辑正确。
  4. 动态输出长度:输出结果时计算输入字符串的实际长度(直到换行符),避免固定输出2个字符的问题。

内容的提问来源于stack exchange,提问作者Retr0_Xan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 00:24:17