2017-07-30 124 views
0

在为我的6502/NES仿真器创建指令函数时,我陷入了理解6502中的带符号字节和2的补码的概念。显然,诸如BMI的分支指令在内存中使用带符号字节来执行向前/向后分支,有些指令允许使用负数进行算术运算。负标志也检测累加器的第7位。 (二的补码)6502存储器中存储的字节是有符号还是无符号?

这是否意味着内存中的所有字节都有符号,我可以将内存初始化为int8_t CPUMEMORY[0x10000];而不是uint8_t CPUMEMORY[0x10000]

虽然困扰我的事情是,当运算结果超过无符号8位限制(即255)时,进位标志被设置。但是,如果所有字节都被签名,这应该不是127? (溢出标志是这样做的,但是进入标志有什么意义?)

回答

3

内存中的字节只是字节:它们既没有签名也没有未签名。然而,一个字节的值可以被解释为有符号数(int8_t)或无符号数(uint8_t)。两个连续字节(int16_t或uint16_t)的值和四个连续字节(int32_t或uint32_t)的值相同。

要处理这些字节,您有几条6502指令,允许您对签名和未签名解释执行多个操作。你只需要使用正确的指令,并使用正确的标志(携带,溢出,负面...)来做你需要做的事情。

+0

ADC和SBC是否将字节解释为无符号和有符号的指令示例?或者还有其他的吗? –

+1

事实上,你可以将加法或减法的操作数/结果解释为有符号或无符号。 –

+0

只是为了完整:**一些**指令甚至可以将字节解释为6502上的BCD。 –

1

进位用于多字节算术(除其他外)。

这些主题已经写了大约数百次,所以我只会引用good source。二进制补码

1.2 REVIEW(签名)NUMBERS

存在用于一个字节256个可能值;在十六进制中,它们是:$ 00到 $ FF。一个8位无符号数的范围是0($ 00)到255($ FF)。 16位无符号数的范围是0($ 0000)至65535($ FFFF), 依此类推。它们被称为无符号数,因为它们是零或更大,即没有(减号)符号。另一手牌上的有号码可以是负值或正值(或零)。术语“带符号的数字” 在下面用于表示二进制补码(尽管有其他表示有符号数字的方式)。 8位 有符号数的范围是-128到127.值-128到-1分别是十六进制 $ 80到$ FF。值0到127分别是 $ 00到$ 7F。因此,有签字号码 的最小值是$ 80,签名号码的最大值是$ 7F。 16位有符号数的范围是-32768($ 8000)到32767($ 7FFF)($ 8000到 $ FFFF是负数),依此类推。这看起来像是一种处理负数的奇怪方式,但这种方法有几个有用的属性。

首先,0-127(8位有符号范围和 无符号数的范围的重叠)在十六进制中为$ 00到$ 7F,而不管 数是有符号还是无符号。其次,当数字是非负数(0到127)时,最高有效位(对于8位数的第7位)为零 ,并且当数字是 负数时为0。事实上,这就是6502的N(负)标记如何得到它的名字 。 (注意N标志,当受指令影响时, 反映该指令结果的第7位)另外一个注意事项:在 数学中,零不是正数或负数,而是在 计算机世界中,事情不那么正式;术语“正数” 通常包括零,因为(a)其最高有效位为零的有符号数的所有其他可能值 都是正数 数,以及(b)无符号的所有其他可能值 数字是正数。

三,审议补充如下:

CLC 
LDA #$FF 
ADC#$01 

结果(在累加器)为$ 00,进位设置。另外,在无符号数字中,是:255 + 1 = 256(记住,进位 被设置)。在有符号数字中,加法是-1 + 1 = 0.在其他 单词中,添加(和减去)有符号数与完全相同,即 添加(和减去)无符号数。

6502.org也有关于sign and the overflow flag的详细讨论。