intel 8080:我在这段代码中遗漏了什么?

时间:2016-11-03 17:48:36

标签: unix assembly cpu-registers intel-8080

以下是取自rosettacode.com

的fibonnaci序列的代码
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?如果是这样,第二个DCR的价值会发生什么变化; JNZ指令看到或做了什么?

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

2 个答案:

答案 0 :(得分:3)

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开始为零(同时包含F(n-2)和F(n-1)的AB寄存器将多次溢出,从而导致结果无法使用...最后的正确结果我认为A = 13是233(懒得验证))

答案 1 :(得分: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。