在为我的6502 / NES仿真器创建指令函数时,我在6502中理解了有符号字节和二进制补码的概念。显然,BMI等分支指令在内存中使用了一个带符号的字节。向前/向后分支,一些指令允许带负数的算术运算。负标志也检测累加器的第7位。 (两个补充)
这是否意味着内存中的所有字节都已签名,我可以将内存初始化为int8_t CPUMEMORY[0x10000];
而不是uint8_t CPUMEMORY[0x10000]
?
令我困扰的是,当操作结果超过无符号8位限制(即255)时,进位标志置位。但如果所有字节都被签名,那么这不应该是127吗? (溢出标志执行此操作,但是有一个进位标志的重点是什么?)
答案 0 :(得分:3)
内存中的字节只是字节:它们既不是有符号也不是无符号。但是,字节的值可以解释为带符号数(int8_t)或无符号数(uint8_t)。两个连续字节(int16_t或uint16_t)的值和四个连续字节(int32_t或uint32_t)的值相同。
要处理这些字节,您有几条6502指令,允许您对有符号和无符号解释执行多个操作。你只需要使用正确的指令并使用正确的标志(携带,溢出,消极......)来完成你需要做的事情。
答案 1 :(得分:1)
进位用于多字节算术(除其他外)。
这些主题已经写了大约数百次,所以我只引用一个good source。
1.2审查两个补充(签名)号码
一个字节有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。范围a 16位有符号数是-32768($ 8000)到32767($ 7FFF)($ 8000到 $ FFFF是负数),依此类推。这可能看起来像一个 处理负数的奇怪方法,但这种方法有几种 有用的属性。
首先,0到127(8位有符号范围的重叠和 无符号数字),十六进制,$ 00到$ 7F,无论是否 号码已签名或未签名。
其次,最高有效位(8位数的第7位)为零 当数字为非负数(0到127)时,数字为数字时为1 负。事实上,这就是6502的N(负)旗帜如何得到它 名称。 (注意N标志受指令影响时, 反映了该指令结果的第7位。)另一个注意事项:in 数学,零不是正数或负数,而是在数字中 计算机世界,事情不那么正式;术语“正数” 通常包括零,因为(a)所有其他可能的值 最高有效位为零的带符号数字是正数 数字,以及(b)无符号的所有其他可能值 数字是正数。
第三,考虑以下补充:
foo
结果(在累加器中)为$ 00,并设置进位。该 另外,在无符号数字中,是:255 + 1 = 256(记住,进位 已设定)。有符号数字的加法是-1 + 1 = 0.在另一个中 单词,添加(和减去)签名数字完全相同 添加(和减去)无符号数。
6502.org也有关于sign and the overflow flag的详细讨论。