在汇编中添加 2 个数字

Adding 2 numbers in assembly

您好,我们刚开始学习汇编的课程,我们有一个问题是在 16 位处理器中添加 2 个 32 位数字。这是我们的代码:

                ORIG    8000h
Num1            STR     8091h, 1201h
Num2            STR     8061h, 4f01h
Soma            TAB     2

                ORIG    0000h

                MOV     R1, Num1
                MOV     R2, Num2
                MOV     R3, Soma
                MOV     R4, M[R1]
                ADD     R4, M[R2]
                MOV     M[R3], R4
                INC     R1
                INC     R2
                INC     R3
                MOV     R4, M[R1]
                ADDC    R4, M[R2]
                MOV     M[R3], R4

Fim:            BR      Fim

我们的问题是第一次加法的进位没有加到第二次加法中,我们不知道为什么。

Carry位在Flags寄存器中,受很多操作影响,通常包括INC

您有多种选择来保留由 ADD:

产生的进位标志
  • 保存ADD之后的Flags寄存器,恢复ADDC之前的Flags寄存器。在 Intel 上,这是通过 pushfpopf 指令完成的。

  • 将进位存储到寄存器中。在 Intel 上,这是用 setc [8-bit-register] 完成的。或者,您可以使用条件跳转。 (在英特尔上,这将是 jc,进位跳跃;在您的模拟器中,这可能是 BRC)。第三种方式是 MOV R4, 0; ADC R4, R4.

  • 重新排序或重写代码,以便 ADDADDC 之间没有标志更改指令。这是首选解决方案,我将根据此选项继续。

首先,我将向您展示它是如何在 Intel 上完成的:

; add the low words
mov    ax, [Num1]
add    ax, [Num2]
mov    [Soma], ax

; Add the high words and the Carry bit
mov    ax, [Num1 + 2]
addc   ax, [Num2 + 2]
mov    [Soma +_2], ax

现在进行模拟器组装。

(我假设MOV R4, M[R1]的意思是将R1中内存地址的值放入R4)。

如果模拟器支持像M[R1 + 1]这样的操作数语法,那么递增寄存器的需求就消失了:

            MOV     R1, Num1
            MOV     R2, Num2
            MOV     R3, Soma

            MOV     R4, M[R1]
            ADD     R4, M[R2]
            MOV     M[R3], R4

            MOV     R4, M[R1+2]
            ADDC    R4, M[R2+2]
            MOV     M[R3+2], R4

此外,如果模拟器支持 M[Num1] 语法,您可能可以完全摆脱使用 R1, R3, R3

请注意,我添加的是 2,而不是 1,因为您添加的是 2 个字节长的单词。 您的 INC 可能需要加倍(模拟的 CPU 可以访问字节偏移量的内存,不是吗?)。例如 INC R1 会变成:

INC   R1
INC   R1

相当于

ADD   R1, 2

这清楚地显示了进位标志是如何被覆盖的。

如果模拟器不支持 M[register + constant] 语法,我们可以通过使用 R4 寄存器来解决这个问题,MOV M[R3], R4MOV R4, M[R1] 之间未使用该寄存器:

            MOV     R1, Num1
            MOV     R2, Num2
            MOV     R3, Soma

            MOV     R4, M[R1]
            ADD     R4, M[R2]
            MOV     M[R3], R4

            MOV     R4, 0
            ADC     R4, R4   ; R4 now contains the carry flag.

            INC     R1       ; Note you probably need to change
            INC     R2       ; these to  ADD R?, 2
            INC     R3

            ADD     R4, M[R1]
            ADD     R4, M[R2]                
            MOV     M[R3], R4

干杯!

您可以在递增值之前简单地添加进位:

                ORIG    8000h
Num1            STR     8091h, 1201h
Num2            STR     8061h, 4f01h
Soma            TAB     2

                ORIG    0000h

                MOV     R1, Num1
                MOV     R2, Num2
                MOV     R3, Soma
                MOV     R4, M[R1]
                ADD     R4, M[R2]
                MOV     M[R3], R4
                MOV     R4, R0
                ADDC    R4, R0
                INC     R1
                INC     R2
                INC     R3
                ADD     R4, M[R1]
                ADD     R4, M[R2]
                MOV     M[R3], R4

Fim:            BR      Fim