Assembly 6502 asm中如何将16位数字除以2?
我想把一个16位的数字除以2。我对这个问题的解决办法如下Assembly 6502 asm中如何将16位数字除以2?,assembly,6502,c64,Assembly,6502,C64,我想把一个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 ;pu
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
这是如何工作的?如果我没记错的话,ROR和ROL会按照指定的方向移动位,最低有效位(ROR)和最高有效位(ROL)会移动到进位标志中 我已经有25年没有看过6502了,虽然我不太清楚,但我马上就想到了
编辑:此外,在ROR和ROL中,进位标志的现有状态被转移到累加器的最低/最高有效位。它的作用与代码中的注释相同,例如;) 在6502中,不幸的是没有算术右移,这将使符号位保持不变。因此,它需要被模仿。为此,首先从高位字中提取符号位。请注意,这是使用累加器完成的,因此原始值不会更改。
ROR
用于高位字,该高位字旋转通过使用进位标志扩展操作数得到的9位值。因此,当前在CF中的符号位将旋转到MSB中,其余的位将右移,LSB将结束在CF中。这完成了符号除法。低位字上的第二个ROR
简单地将高位字的LSB传输到低位字的MSB,并将其余位右移。除以2(无符号数)等于将所有位右移一个位置。例如,数字100用二进制表示为:
01100100
将所有位置向右移动一个会产生收益
00110010
这是50的二进制表示
ROR命令将所有位置向右移动。字节的新MSB将等于进位标志的旧值,而进位标志的新值将等于字节的旧LSB
如果16位数字是无符号的,则将数字的高字节和低字节向右移位即可:
LSR counter_hi
ROR counter_lo
LSR和ROR都将其参数右移,但LSR使计数器_hi的MSB为0,并将计数器_hi的LSB移到进位标志中,而ROR使计数器_lo的MSB等于计数器_hi的(旧)LSB
如果号码有符号,则需要存储符号位,并确保新号码的符号位相同。这就是您引用的代码的前两个命令所做的。请注意,这是因为数字存储在。(显然,您知道右移N位除以2^N,类似地,左移乘以2)
发件人:
ASL
将高字节计数器\u hi
的最高有效位(MSB)放入进位寄存器(以便在移位时记住该符号-除以正整数(2)不会改变16位数字的原始符号)
ROR counter\u hi
将计数器\u hi
向右移动1位。重要的是:
进位移到第7位,原始位0移到进位
这有两个目的-保留原始标志,还将为第二个ROR
ROR计数器低
然后对低字节执行相同的操作。计数器\u hi
的LSB现在被移到计数器\u lo
的MSB中。不记得指令的所有寻址模式,但这可能是正常的:
LSR
PHA
TXA
ROR
TAX
PLA
这乘法和除法(2的倍数)只不过是向左或向右的位移位。”LSR hi字节、ROR lo字节’将实现16位除法目标,无需大量循环码、寄存器交换等。