存储在 6502 内存中的字节是有符号的还是无符号的?
Are the bytes stored in 6502 memory signed or unsigned?
在为我的 6502/NES 模拟器创建指令函数时,我在理解 6502 中带符号字节和二进制补码的概念时遇到了困难。显然,BMI 等分支指令在内存中使用带符号字节 forwards/backwards 分支,一些指令允许对负数进行算术运算。负标志也检测累加器的第 7 位。 (补码)
这是否意味着内存中的所有字节都已签名,我可以将内存初始化为 int8_t CPUMEMORY[0x10000];
而不是 uint8_t CPUMEMORY[0x10000]
?
但令我困扰的是,当运算结果超过无符号 8 位限制(即 255)时,会设置进位标志。但是,如果所有字节都已签名,这不应该是 127 吗? (溢出标志可以做到这一点,但是有一个进位标志有什么意义呢?)
内存中的字节只是字节:它们既没有签名也没有未签名。但是,字节的值可以解释为有符号数 (int8_t) 或无符号数 (uint8_t)。两个连续字节(int16_t或uint16_t)的值和四个连续字节(int32_t或uint32_t)的值相同。
为了处理这些字节,您有几条 6502 指令允许您对有符号和无符号解释执行多个操作。您只需使用正确的指令并使用正确的标志(进位、溢出、负...)来完成您需要做的事情。
进位用于多字节运算(除其他外)。
这些话题已经写了上百次了,所以我只引用一个good source。
1.2 REVIEW OF TWOS COMPLEMENT (SIGNED) NUMBERS
There are 256 possible values for a byte; in hex, they are: [=11=] to
$FF. The range of an 8-bit unsigned number is 0 ([=11=]) to 255 ($FF).
The range of a 16-bit unsigned number is 0 ([=11=]00) to 65535 ($FFFF),
and so on. They are called unsigned numbers because they are zero or
greater, i.e. there is no (minus) sign. A signed number, on the other
hand, can be negative or positive (or zero). The term "signed number"
is used below to mean a twos complement number (although there are
other ways of representing signed numbers). The range of an 8-bit
signed number is -128 to 127. The values -128 through -1 are, in hex,
through $FF, respectively. The values 0 through 127 are, in hex,
[=11=] through F, respectively. So the minimum value of a signed number
is and the maximum value of a signed number is F. The range of a
16-bit signed number is -32768 (00) to 32767 (FFF) (00 through
$FFFF are the negative numbers), and so on. This may seem like a
strange way of handling negative numbers, but this method has several
useful properties.
First, 0 to 127 (the overlap of the ranges of 8-bit signed and
unsigned numbers) is, in hex, [=11=] to F, regardless of whether the
number is signed or unsigned.
Second, the most significant bit (bit 7 for an 8-bit number) is zero
when the number is non-negative (0 to 127), and one when the number is
negative. In fact, this is how the N (negative) flag of 6502 got its
name. (Notice that the N flag, when affected by an instruction,
reflects bit 7 of the result of that instruction.) One other note: in
mathematics, zero is not a postive or a negative number, but in the
computer world, things are less formal; the term "positive number"
typically includes zero because (a) all of the other possible values
of a signed number whose most significant bit is zero are positive
numbers, and (b) all of the other possible values for an unsigned
number are positive numbers.
Third, consider the following addition:
CLC
LDA #$FF
ADC #
The result (in the accumulator) is [=11=], and the carry is set. The
addition, in unsigned numbers, is: 255 + 1 = 256 (remember, the carry
is set). The addition, in signed numbers, is -1 + 1 = 0. In other
words, adding (and subtracting) signed numbers is exactly the same as
adding (and subtracting) unsigned numbers.
6502.org也有关于sign and the overflow flag的详细讨论。
在为我的 6502/NES 模拟器创建指令函数时,我在理解 6502 中带符号字节和二进制补码的概念时遇到了困难。显然,BMI 等分支指令在内存中使用带符号字节 forwards/backwards 分支,一些指令允许对负数进行算术运算。负标志也检测累加器的第 7 位。 (补码)
这是否意味着内存中的所有字节都已签名,我可以将内存初始化为 int8_t CPUMEMORY[0x10000];
而不是 uint8_t CPUMEMORY[0x10000]
?
但令我困扰的是,当运算结果超过无符号 8 位限制(即 255)时,会设置进位标志。但是,如果所有字节都已签名,这不应该是 127 吗? (溢出标志可以做到这一点,但是有一个进位标志有什么意义呢?)
内存中的字节只是字节:它们既没有签名也没有未签名。但是,字节的值可以解释为有符号数 (int8_t) 或无符号数 (uint8_t)。两个连续字节(int16_t或uint16_t)的值和四个连续字节(int32_t或uint32_t)的值相同。
为了处理这些字节,您有几条 6502 指令允许您对有符号和无符号解释执行多个操作。您只需使用正确的指令并使用正确的标志(进位、溢出、负...)来完成您需要做的事情。
进位用于多字节运算(除其他外)。
这些话题已经写了上百次了,所以我只引用一个good source。
1.2 REVIEW OF TWOS COMPLEMENT (SIGNED) NUMBERS
There are 256 possible values for a byte; in hex, they are: [=11=] to $FF. The range of an 8-bit unsigned number is 0 ([=11=]) to 255 ($FF). The range of a 16-bit unsigned number is 0 ([=11=]00) to 65535 ($FFFF), and so on. They are called unsigned numbers because they are zero or greater, i.e. there is no (minus) sign. A signed number, on the other hand, can be negative or positive (or zero). The term "signed number" is used below to mean a twos complement number (although there are other ways of representing signed numbers). The range of an 8-bit signed number is -128 to 127. The values -128 through -1 are, in hex, through $FF, respectively. The values 0 through 127 are, in hex, [=11=] through F, respectively. So the minimum value of a signed number is and the maximum value of a signed number is F. The range of a 16-bit signed number is -32768 (00) to 32767 (FFF) (00 through $FFFF are the negative numbers), and so on. This may seem like a strange way of handling negative numbers, but this method has several useful properties.
First, 0 to 127 (the overlap of the ranges of 8-bit signed and unsigned numbers) is, in hex, [=11=] to F, regardless of whether the number is signed or unsigned.
Second, the most significant bit (bit 7 for an 8-bit number) is zero when the number is non-negative (0 to 127), and one when the number is negative. In fact, this is how the N (negative) flag of 6502 got its name. (Notice that the N flag, when affected by an instruction, reflects bit 7 of the result of that instruction.) One other note: in mathematics, zero is not a postive or a negative number, but in the computer world, things are less formal; the term "positive number" typically includes zero because (a) all of the other possible values of a signed number whose most significant bit is zero are positive numbers, and (b) all of the other possible values for an unsigned number are positive numbers.
Third, consider the following addition:
CLC LDA #$FF ADC #
The result (in the accumulator) is [=11=], and the carry is set. The addition, in unsigned numbers, is: 255 + 1 = 256 (remember, the carry is set). The addition, in signed numbers, is -1 + 1 = 0. In other words, adding (and subtracting) signed numbers is exactly the same as adding (and subtracting) unsigned numbers.
6502.org也有关于sign and the overflow flag的详细讨论。