在NES使用的6502上的减法操作(sbc asm指令)期间发生借位(即进位标志被清除)时?每次结果都是负数(-1到-128)吗?
非常感谢!谢谢斯滕
在 6502SBC n
上是完全一样的ADC (n EOR $FF)
——它是一个补码。A + (operand ^ 0xff) + existing carry
所以当小于 256时进位是明确的。
编辑:所以,如果设置了进位,那么减法不会发生借位。如果进位清零,则借位发生减法。因此,如果在减法之后设置进位,则没有借位。如果进位清晰,则有借位。
如果要测试结果是否为负,请通过 aBMI
或隐式检查符号位BPL
。
如果在通用 6502 上处于十进制模式但 NES 变体没有十进制模式,则它比这要复杂一些,因此请忽略您所读到的任何内容。
澄清一下:下面的评论;如果您将数字视为有符号,则127
is +127
,128
is-128
等。正常的二进制补码。没什么特别的。例如
LDA #-63 ; i.e. 1100 0001
SEC
SBC #65 ; i.e. 0100 0001
; result in accumulator is now -128, i.e. 1000 0000,
; and carry remains set because there was no borrow
BPL somewhere ; wouldn't jump, because -128 is negative
BMI somewhereElse ; would jump, because -128 is negative
就内部工作而言,以下内容完全相同:
LDA #-63 ; i.e. 1100 0001
SEC ; ... everything the same up until here ...
ADC #65 ; i.e. 1011 1110 (the complement of 0100 0001)
; result = 1100 0001 + 1011 1110 + 1 = [1] 0111 1111 + 1 = [1] 1000 0000
; ^
; |
; carry
; = -128
因此,如上所述,根据 6502 手册和“坐在累加器中的东西”的普通编程含义定义“结果”,您可以如上所述测试结果是正面还是负面,例如
SBC $23
BMI resultWasNegative
resultWasPositive: ...
如果您对完整结果是否为负(即是否将其装入累加器)感兴趣,那么您还可以检查溢出标志。如果设置了溢出,则意味着由于 8 位限制,累加器中的任何内容都具有错误的符号。因此,您可以在溢出和符号之间执行相当于异或的操作:
SBC $23
BVC signIsTheOpposite
BMI resultWasNegative
JMP resultWasPositive
signIsTheOpposite:
BPL resultWasNegative
JMP resultWasPositive
汤米的回答是正确的,但我有一个更简单的方式来看待它。
6502 的 ALU 中的运算都是 8 位的,因此您可以考虑这样的减法(分别为 65 美元和 64 美元):
01100101
-01100100
========
00000001
我所做的是想象减法是一个 9 位(无符号)操作,累加器的第 9 位设置为 1,所以 $65 - $64 看起来像这样:
1 01100101
- 01100100
==========
1 00000001
而 $64 - $65 看起来像这样
1 01100100
- 01100101
==========
0 11111111
新的进位位是结果的虚数第 9 位。
本质上,当被解释为无符号数的操作数大于被解释为无符号数的累加器时,设置进位。或者迂腐的时候
A < operand - 1 + oldcarry
不,结果也可能是积极的。
例子:
lda #$10
sec
sbc #$f0
之后,进位将被清除,累加器将为 20 美元。
要在减法后测试正/负值,请使用状态寄存器的 N(负)标志和评估它的分支(BMI/BPL)。