我输入一个4位数并存储在一个变量中。这部分非常好。然后我可以检索值并打印它。我试图将其转换为整数,以便我可以对其执行算术运算。
这是我使用的代码:
; ASCII -> Integer
mov al, [operand1 + 2] ; Load the first digit
sub al, 30h ; Subtract 30h
mov ah, 0 ; Clear AH
mov cx, 3 ; Set the loop counter to 3
lea si, [operand1 + 2] ; Load the address of the first digit
@loop:
mov bl, 10 ; Load 10
mul bl ; Multiply AX by 10
inc si ; Increment SI
mov dl, [si] ; Load the next digit
sub dl, 30h ; Subtract 30h
adc al, dl ; Add the digit to AL with carry
loop @loop ; Repeat until CX = 0
; The result is in AX
字符串
我在这里使用的概念是,如果操作数1存储1234,则第一位被加载(1)并在从ASCII 31H中减去30H后转换为整数。之后,我将此数字乘以10,因此01H最终变为0aH,即十进制10。1实际上是千位,所以通过乘以10三次,我希望达到1000。下一个数字正在被添加,并移动到下一个更高的地方以及。
当我在Operand1中输入1234时,代码工作正常,但当我输入5678时,它会导致022E而不是正确的162E。
我不知道该怎么补救。
1条答案
按热度按时间7y4bm7vi1#
检查
mul bl
的指令手册-即执行al × bl
=>ax
,因此它是一个扩展的8位乘法。值123(十六进制0x 7 B)适合8位,因此123 × 10的乘法与扩大乘法一起产生0x 4CE(1230),您可以将其添加4以获得1234。
然而,对于另一个数字,5678,567需要两个字节来表示,在十六进制中,我们有0x 237,所以做一个8位乘法,忽略上面的字节,乘以0x 37 × 10,结果是0x 226,然后加上8,得到0x 22 e。
看起来你也在做8位加法,这似乎对许多数字都有效,但是以4096为例,没有进位到
ah
中将导致不正确的加法。你需要将下一个字符从数字转换为数字转换为完整的16位,然后做16位加法(例如在ax
上)。因此,对于4096,我们有409 × 10 = 4090,在十六进制0xFFA中,那么6的16位加法将产生正确的0x 1000,而6的8位加法将是0xFA + 6,也就是0x 100,尽管加法没有扩大,所以1丢失了,8位加法的结果是0x 00,而满寄存器将保持0xF 00,即4096的错误转换。