1

这是从 rosettacode.com 获取的斐波那契序列的代码

FIBNCI: MOV  C,  A  ; C will store the counter
    DCR  C      ; decrement, because we know f(1) already
    MVI  A,  1
    MVI  B,  0
LOOP:   MOV  D,  A
    ADD  B      ; A := A + B
    MOV  B,  D
    DCR  C
    JNZ  LOOP   ; jump if not zero
    RET         ; return from subroutine

如果取自 A 的值原本为 0,我们将 C 递减,C 会变成 -1 吗?如果是这样,在第 2 次 DCR 时该值会发生什么变化;JNZ 指令看到或做什么?

这是我第一次接触汇编语言,所以现在有点困惑。我在想,如果 C 已经是 -1 并且在我们到达 JNZ 指令时计数,那么这段代码不会陷入循环吗?还是 JNZ 正在寻找其他地方?

4

2 回答 2

4

Intel 8080 寄存器A, B, C, ...是 8 位的。

因此,如果A0,则C变为-1,它以 8 位编码为0b11111111(所有 8 位设置为 1)。当您将其视为无符号 8 位值时,它等于255.

现在,如果您将该值增加 1,它将变为 256,在二进制中是0b100000000-> 因为C是 8 位宽,该值将被截断为0b00000000,即0. 所以 -1 + 1 = 0,正如预期的那样(无符号数学中的 255 + 1 = 0,因为你达到了 8 位限制,所以值“溢出”)。

第二个DCR将减少 -1/255 值,然后 C 将包含 -2(等于 254 无符号,如 255 - 1 = 254,二进制看起来像0b11111110)。

JNZ将循环到零,这意味着循环将运行 255 次(对于 A=0 参数,对于 A=1,它将运行 256 次),直到C从 255 再次达到零(同时A包含BF(n -2) 和 F(n-1) 会溢出很多次,从而使结果无法使用......我认为最后一个正确的结果是 A=13 是 233(懒得验证))

于 2016-11-03T18:47:48.913 回答
2

对于输入 < 2 的开始检查:

FIBNCI: CPI     2           ;return if A < 2
        RC                  ;F(0) = 0, F(1) = 1

其余的代码似乎没问题。F(2) = 1, F(3) = 2, F(4) = 3, ...

您可以修改代码以使用双加 (DAD) 来获得 16 位结果。8 位结果的最大输入为十进制 13:fib(13) = 233。16 位结果的最大输入为 24:F(24) = 46368。

于 2016-11-03T19:09:47.800 回答