16 位系统中的程序如何访问大于 65535 的整数但不能访问地址
How a program in 16 bit system can access integers more than 65535 but not address
16 位系统最多只能访问 64kbytes 的 RAM(正常情况下)。有一个内存地址的概念,即 16 位系统可以访问 2^16 个数字,因此在无符号整数中它只能访问 2^16 = 65536 个整数(0 到 65535)。因此 16 位系统最多只能使用 64kbytes 的地址(经过小的计算得出结论)。现在主要问题。当我们将整数定义为 'long int' 时,它如何访问大于 65535 的整数?
这里有一堆误解post:
I came to know in previous days that a 16 bit system can only access RAM upto 64kbytes
这实际上是错误的,8086 有一个 20 位的外部地址总线,因此它可以访问 1,048,576 字节(~1MB)。您可以在此处阅读有关 8086 架构的更多信息:https://en.wikipedia.org/wiki/Intel_8086.
Is that when we define an integer to be 'long int' than how can it access integers more than 65535?
你问的是寄存器大小吗?在那种情况下,答案很简单:不会。它可以访问前 16 位,然后它可以访问其他 16 位,无论应用程序如何处理这 2 个 16 位值都取决于它(以及使用的框架,如 C 运行时)。
至于如何仅用 16 位整数访问 20 位的完整地址 space,答案是地址分段。您有第二个寄存器(8086 上的 CS、DS、SS 和 ES)存储地址的高位部分,并且 CPU "stitches" 它们一起发送到内存控制器。
计算机可以对大于机器字的值执行算术运算,其方式与人类对大于数字的值执行算术运算的方式大致相同:将运算分成多个部分,并跟踪 "carries"会在它们之间移动数据。
以8086为例,如果AX持有32位数字的下半部分,DX持有上半部分,序列:
ADD AX,[someValue]
ADC DX,[someValue+2]
将添加到 DX::AX 的 32 位值,其下半部分位于地址 [someValue],其上半部分位于 [someValue+2]。 ADD 指令将更新一个 "carry" 标志,指示加法是否有进位,如果设置了进位标志,ADC 指令将额外添加一个 1。
有些处理器没有进位标志,但有一条指令可以比较两个寄存器,如果第一个大于第二个,则将第三个寄存器设置为 1,否则为 0。在这些处理器上,如果要将 R1::R0 添加到 R3::R2 并将结果放入 R5::R4,可以使用序列:
Add R0 to R2 and store the result in R4
Set R5 to 1 if R4 is less than R0 (will happen if there was a carry), and 0 otherwise
Add R1 to R5, storing the result in R5
Add R3 to R5, storing the result in R5
比普通的单字加法慢四倍,但至少还是有点实用。请注意,虽然进位标志方法很容易扩展到对任何大小的数字进行操作,但将这种方法扩展到两个单词之外要困难得多。
16 位系统最多只能访问 64kbytes 的 RAM(正常情况下)。有一个内存地址的概念,即 16 位系统可以访问 2^16 个数字,因此在无符号整数中它只能访问 2^16 = 65536 个整数(0 到 65535)。因此 16 位系统最多只能使用 64kbytes 的地址(经过小的计算得出结论)。现在主要问题。当我们将整数定义为 'long int' 时,它如何访问大于 65535 的整数?
这里有一堆误解post:
I came to know in previous days that a 16 bit system can only access RAM upto 64kbytes
这实际上是错误的,8086 有一个 20 位的外部地址总线,因此它可以访问 1,048,576 字节(~1MB)。您可以在此处阅读有关 8086 架构的更多信息:https://en.wikipedia.org/wiki/Intel_8086.
Is that when we define an integer to be 'long int' than how can it access integers more than 65535?
你问的是寄存器大小吗?在那种情况下,答案很简单:不会。它可以访问前 16 位,然后它可以访问其他 16 位,无论应用程序如何处理这 2 个 16 位值都取决于它(以及使用的框架,如 C 运行时)。
至于如何仅用 16 位整数访问 20 位的完整地址 space,答案是地址分段。您有第二个寄存器(8086 上的 CS、DS、SS 和 ES)存储地址的高位部分,并且 CPU "stitches" 它们一起发送到内存控制器。
计算机可以对大于机器字的值执行算术运算,其方式与人类对大于数字的值执行算术运算的方式大致相同:将运算分成多个部分,并跟踪 "carries"会在它们之间移动数据。
以8086为例,如果AX持有32位数字的下半部分,DX持有上半部分,序列:
ADD AX,[someValue]
ADC DX,[someValue+2]
将添加到 DX::AX 的 32 位值,其下半部分位于地址 [someValue],其上半部分位于 [someValue+2]。 ADD 指令将更新一个 "carry" 标志,指示加法是否有进位,如果设置了进位标志,ADC 指令将额外添加一个 1。
有些处理器没有进位标志,但有一条指令可以比较两个寄存器,如果第一个大于第二个,则将第三个寄存器设置为 1,否则为 0。在这些处理器上,如果要将 R1::R0 添加到 R3::R2 并将结果放入 R5::R4,可以使用序列:
Add R0 to R2 and store the result in R4
Set R5 to 1 if R4 is less than R0 (will happen if there was a carry), and 0 otherwise
Add R1 to R5, storing the result in R5
Add R3 to R5, storing the result in R5
比普通的单字加法慢四倍,但至少还是有点实用。请注意,虽然进位标志方法很容易扩展到对任何大小的数字进行操作,但将这种方法扩展到两个单词之外要困难得多。