我正在制作一个6502仿真器,并且我已经在开始时(或者我认为我至少)(实现ADC操作)。问题是我必须确定是否存在进位或溢出。问题是,在我的实现中,我无法真正理解它们之间的区别。我知道进位是在操作后出现第9位的时候,我知道当结果大于255时会发生溢出。这不是确定进位和溢出标志是一样的吗?
if(result > 255) {
carry = 1;
overflow = 1;
} else {
carry = 0;
overflow = 0;
}
这不正确吗?如果不是,那么什么是正确的,为什么?
答案 0 :(得分:11)
溢出标志表示数字符号何时发生不正确的变化。因此,如果添加两个正数并得到否定结果,则会出现溢出。如果你添加两个负数并得到一个肯定的结果,也会有溢出。
添加两个不同的符号时,您不会溢出,因为范围不允许。最小的正负加最大的负数是0 +( - 128),这很合适 - 0加上任何适合8位的东西显然都适合8位。最小的负数加上最大的正数是-1 + 127 = 126.哪个适合。
(编辑:甚至带进位,0 + -128 + 1 = -127,适合,-1 + 127 + 1 = 127,适合)
如果具有相同符号的两个输入产生具有不同符号的结果,则设置溢出。否则很清楚。
您可以将其表示为对符号位的简单按位操作。假设你有一个+ b = c。
a ^ b
如果符号不同,符号位将为1。你想知道相反的情况。所以:
~(a ^ b)
如果符号相同,在符号位中给出1。这是测试的第一部分。假设a和b具有相同的符号,则可以针对它们中的任何一个测试c。这次你确实想测试差异,所以这只是:
a ^ c
你需要在测试的两个部分都设置测试位,这样你就可以将它们与二进制文件结合起来(留下很多括号以链接到语言推理):
(~(a ^ b))&(a ^ c)
你只想要符号位,所以掩盖了:
(~(a ^ b))&(a ^ c)&0x80
如果溢出标志应该清除,则评估为0x00
,如果应设置溢出标志,则评估为0x80
。所以只需将其转移到位。
(除了:虽然在6502上有许多指令设置了标志,只有一个暴露了状态寄存器,因此仿真器通常会以任何方便的形式单独保存标志并根据需要组成状态寄存器,在这种情况下你不会打扰转移和撰写,你只需存储结果)