【问题标题】:Adding 2 numbers in assembly在汇编中添加 2 个数字
【发布时间】:2016-01-20 21:18:36
【问题描述】:

您好刚开始学习汇编的课程,我们有一个问题是在 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

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

【问题讨论】:

  • 出于好奇,这是用于什么机器架构的?
  • P3 处理器,我们使用它的模拟器。它使用 16 位
  • 奔腾 3?它看起来像 Intel 语法,但实际上并非如此。无论如何,INC 会影响标志,因此当您到达 ADDC 时,您会从 ADD 中丢失进位位。

标签: assembly add 32-bit 16-bit


【解决方案1】:

进位位在标志寄存器中,受很多操作影响,通常包括INC

您有多种选择来保留 ADD 产生的进位标志:

  • ADD 之后保存标志寄存器,并在ADDC 之前恢复它。在 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 个字节长的单词。 您的INCs 可能需要加倍(模拟的 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

干杯!

【讨论】:

  • 非常感谢您的详细解答!我会尝试你所说的一切,希望它会奏效!这是很大的帮助!干杯
【解决方案2】:

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

                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

【讨论】:

    猜你喜欢
    • 2018-12-28
    • 1970-01-01
    • 1970-01-01
    • 2014-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多