5

我想将一个 16 位数除以二。我对该问题的解决方案如下

    lda $17 ;set high byte
    ldx $32    ;set low byte

divide:
    PHA         ;push A to stack        
    TXA         ;X > A  
    LSR         ;divide low byte by 2   
    TAX         ;A > X

    PLA         ;pull A from stack  
    LSR         ;divide high byte by 2
    BCC +       ;C=0, skip

    PHA         ;while C=1
    TXA         ;add $80 to the lsb
    ADC #$80
    TAX
    PLA 
+   
    +printDecimal $0400+120

所有PHA/PLA的诡计都是因为我的printDecimal宏从 A 读取 MSB,从 X 读取 LSB。

当我在网上查看替代方案时,我发现 4 指令替代我简陋的除法例程。但我不明白。

div2:
    LDA counter_hi       ;Load the MSB
    ASL                  ;Copy the sign bit into C
    ROR counter_hi       ;And back into the MSB
    ROR counter_lo       ;Rotate the LSB as normal

    LDA counter_hi
    LDX counter_lo      
    +printDecimal $0400+40    

这是如何工作的?

4

5 回答 5

9

除以 2(无符号数)与将所有位向右移动一位相同。例如,数字 100 以二进制表示:

01100100

将所有位置向右移动一位会产生

00110010

这是50的二进制表示。

ROR 命令将所有位置向右移动。字节的新 MSB 将等于进位标志的旧值,而进位标志的新值将等于字节的旧 LSB。

如果 16 位数字是无符号的,则将数字的高字节和低字节向右移动就足够了:

LSR counter_hi
ROR counter_lo

LSR 和 ROR 都将它们的参数向右移动,但 LSR 使 counter_hi 的 MSB 为 0,并将 counter_hi 的 LSB 移动到进位标志,而 ROR 使 counter_lo 的 MSB 等于 counter_hi 的(旧)LSB。

如果数字有符号,则需要存储符号位,并确保新数字的符号位相同。这就是您引用的代码的前两个命令所做的。请注意,这是有效的,因为该数字存储在二进制补码中。

于 2014-12-09T15:32:48.710 回答
4

它就像代码中的注释所说的那样工作;)不幸的是,在 6502 中没有算术右移,这会使符号位保持不变。所以需要模仿。为此,首先从高位字中提取符号位。请注意,这是使用累加器完成的,因此原始值不会更改。用ROR在高位字上,它旋转通过使用进位标志扩展操作数而产生的 9 位值。因此,当前在 CF 中的符号位将被循环到 MSB,其余位将右移,LSB 将最终在 CF 中。这完成了一个有符号的划分。低位字上的第二个ROR简单地将 LSB 从高位字传输到低位字的 MSB,并将其余位右移。

于 2014-12-09T15:24:51.923 回答
2

(显然你知道右移 N 位除以 2^N,同样左移乘以 2)

这个参考

ASL将高字节的最高有效位 (MSB)counter_hi放入进位寄存器(以便在我们移位时记住符号 - 除以正整数 (2) 不会改变我们 16 位数的原始符号)。

ROR counter_hicounter_hi1 位向右移动。重要的:

进位移入第 7 位,原始位 0 移入进位。

它有两个目的 - 保留原始符号,并且还将转移counter_hi第二个的 LSBROR

ROR counter_lo然后对低字节做同样的事情。的 LSBcounter_hi现在转移到的 MSBcounter_lo

于 2014-12-09T15:40:25.400 回答
1

不记得指令的所有寻址模式,但也许这没关系:

LSR
PHA
TXA
ROR
TAX
PLA
于 2014-12-09T15:45:51.670 回答
1

如果我没记错的话,ROR 和 ROL 会按照规定的方向移动位,并将最低有效位(对于 ROR)和最高有效位(对于 ROL)移动到进位标志中。

自从我查看任何 6502 以来,已经有 25 年了,虽然对我来说并不是很清楚,但这就是我认为它会立即完成的方式。

编辑:此外,在 ROR 和 ROL 中,进位标志的现有状态被转移到累加器的最低/最高有效位。

于 2014-12-09T15:19:57.760 回答