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