section .bss
num: resb 3
section .text
global _start
_start:
; Read input
mov eax, 3
mov ebx, 0
mov ecx, num
mov edx, 3
int 80h
sub byte [num+2], 1
cmp byte [num+2], 255
jne skip_borrow
sub byte [num+1], 1
cmp byte [num+1], 255
jne skip_borrow
sub byte [num], 1
skip_borrow:
cmp byte [num], 0
jne skip_carry
mov byte [num+1], 9
mov byte [num+2], 9
skip_carry:
mov eax, 4
mov ebx, 1
mov ecx, num
mov edx, 3
int 80h
mov eax, 1
mov ebx, 0
int 80h
代码读取三位输入号码和一位输入号码。小于 100 和大于 100 减去一位数有效。然而,从 100、200、300 中减去会给出错误的输出。例如,100 减 1 得到 10/而不是 99 或 099,200 减 1 得到 20/而不是 199。我该如何解决这个问题。
例如,100 减 1 给出的是 10/,而不是 99 或 099
num处的输入由字符“1”、“0”和“0”组成。它们的 ASCII 值为 49、48 和 48。
sub byte [num+2], 1 cmp byte [num+2], 255 jne skip_borrow
因为
sub
指令从 [48,57] 范围内的数字减 1,所以您得到 [47,56] 范围内的结果。所以这永远不会产生数字 255,因此 jne skip_borrow
将始终被采用。
然后到达skip_borrow
skip_borrow: cmp byte [num], 0 jne skip_carry mov byte [num+1], 9 mov byte [num+2], 9 skip_carry:
您希望这部分代码能够生成 99,但这永远不会发生,因为条件永远不会成立! num 处的第一个字节是 [48,57] 范围内的 ASCII 代码,因此永远不会为 0,因此将始终采用
jne skip_carry
。
以上所有结果都会产生两个未修改的字节,后跟一个递减的字节(如果是“0”,将显示“/”)。对于 1000 个可能的输入中的任何一个,都会发生这种情况。我会说这句话:“从低于 100 和高于 100 的数字中减去一位数字works。”证明您没有进行足够的测试...
下一个代码将 3 位 ASCII 计数器递减,从“000”到“999”:
mov ecx, num
dec byte [ecx+2]
cmp byte [ecx+2], '0'
jnb done
mov byte [ecx+2], '9'
dec byte [ecx+1]
cmp byte [ecx+1], '0'
jnb done
mov byte [ecx+1], '9'
dec byte [ecx]
cmp byte [ecx], '0'
jnb done
mov byte [ecx], '9'
done:
mov edx, 3
mov ebx, 1
mov eax, 4
int 80h
你可以把它写成循环:
mov eax, num+3
more:
dec eax
dec byte [eax]
cmp byte [eax], '0'
jnb done
mov byte [eax], '9'
cmp eax, num
jne more
done:
mov edx, 3
mov ecx, num
mov ebx, 1
mov eax, 4
int 80h