assembly 将4位十进制输入从ASCII转换为正确的ASCII形式

mwecs4sa  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(92)

我输入一个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。
我不知道该怎么补救。

7y4bm7vi

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的错误转换。

相关问题