如何在6502 asm中将16位数除以2?

wiz*_*wor 5 assembly c64 6502

我想将16位数除以2.我对这个问题的解决方案如下

    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
Run Code Online (Sandbox Code Playgroud)

所有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    
Run Code Online (Sandbox Code Playgroud)

这是怎么回事?

Hoo*_*pje 9

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

01100100
Run Code Online (Sandbox Code Playgroud)

将所有位置向右移动产生

00110010
Run Code Online (Sandbox Code Playgroud)

这是50的二进制表示.

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

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

LSR counter_hi
ROR counter_lo
Run Code Online (Sandbox Code Playgroud)

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

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

  • LSR = CLC + ROR (5认同)