Memory 如何使用内存寄存器来保存不同的类型?

Memory 如何使用内存寄存器来保存不同的类型?,memory,assembly,memory-management,cpu-registers,Memory,Assembly,Memory Management,Cpu Registers,我的印象是,如果一个程序为一个变量类型integer(大小为8字节)保留内存,则保留的内存将是8个不同的寄存器,它们依次出现在内存中 我的问题如下: 1) 假设答案会有所不同,那么我上面的陈述是否是一个很好的概括,即不同类型的变量所需的每个字节都等同于使用内存中的1个寄存器得到的变量?(即1字节需要内存中的一个寄存器) 2) 如果这是真的,那么内存中的每个寄存器可以容纳多少位?或者,如果我买了一台32位计算机,这是否意味着内存中的每个寄存器都能容纳32位 3) 如果integer类型需要8个不同

我的印象是,如果一个程序为一个变量类型integer(大小为8字节)保留内存,则保留的内存将是8个不同的寄存器,它们依次出现在内存中

我的问题如下:

1) 假设答案会有所不同,那么我上面的陈述是否是一个很好的概括,即不同类型的变量所需的每个字节都等同于使用内存中的1个寄存器得到的变量?(即1字节需要内存中的一个寄存器)

2) 如果这是真的,那么内存中的每个寄存器可以容纳多少位?或者,如果我买了一台32位计算机,这是否意味着内存中的每个寄存器都能容纳32位

3) 如果integer类型需要8个不同的寄存器来处理其8字节的大小,那么每个不同的寄存器中包含什么

4) 我还试图理解类型的概念。我知道如果你有32位,你可以表示0到4294967295之间的无符号整数。然而,如果我将无符号整数4294967295存储在32位的存储单元中,CPU如何知道该存储单元中的二进制表示需要解码为无符号整数格式?也就是说,为特定类型预留的内存是指定该特定类型,还是指针指定了该类型,或者是完全不同的类型


我对二进制算术、汇编语言、引用、指针以及如何将变量和数组存储在内存堆中的概念有着广泛的了解(因此我将理解使用这些上下文的任何答案)。我可以用C、C++和java编程。谢谢你的帮助

1,2,3:不要将内存称为寄存器;虽然我以前见过这种情况,但它令人困惑。64位处理器有8字节宽的寄存器,32位处理器有4字节宽的寄存器,但当这些寄存器复制到RAM中时,内存中只有字节。整数的哪个部分存储在哪个字节中取决于处理器的端序:小端序系统将把0x1中的1位存储在8个字节的第一个(最低)地址中,大端序系统将把它存储在最后一个地址中


4:CPU不知道也不关心;“类型”是一种高级语言结构,对于CPU来说,一切都是一个数字:“abcd”是一个数字,0xF0是一个数字。您必须根据您希望它执行的操作向它发出指令,例如,对于x86,如果您希望它将数字视为有符号的,请使用IDIV而不是DIV。

类型在很大程度上是虚构的,以利于编程语言。对于处理器来说,位就是位,它们没有任何意义,只是在执行单个指令的过程中有时会短暂出现,在指令结束时失去意义

Dijkstra:“计算机科学与计算机的关系,正如天文学与望远镜的关系一样。”

您需要指定您对问题感兴趣的处理器,或者您对处理器总体感兴趣。如今,处理器的常见组合从具有8位寄存器的处理器到具有8位、16位、32位、64位寄存器的64位或更大的处理器都有所不同

另外,不要对寄存器中的所有内容感到困惑,有些处理器有很多寄存器,高级代码中的许多项在寄存器中存在一段时间,而其他处理器没有很多寄存器,大多数变量都存在于ram中,而不是寄存器中。更常见的情况是,即使寄存器长时间保存数据,变量也会有一些ram。优化器确实破坏了这种平衡,所以很难做出一般性的陈述

你说你知道汇编语言,就拿这个汇编语言伪代码为例:

mov r1,#0x20000000
shl r2,r0,5
add r1,r2
ldr r0,[r1]
这类似于如果您有一个大小为32字节的结构数组,并且希望得到第一个元素,比如说它是一个单精度浮点。你想要从寄存器r0中的数组中的元素号得到浮点值,我们不在乎元素号是什么,代码对它进行操作

struct 
{
  float f;
  stuff...32 bits total
} mystruct[MYSTRUCTSIZE];
...
unsigned int i;
...
something=mystruct[i].f
...
上面的程序集伪代码计算mystruct[i].f地址,并将其从内存加载到something代码中或由something代码使用

我们可能碰巧知道的位0x20000000是这个结构数组所在内存中的某个地址,但现在,对于mov指令,它只是位,我们正在加载到寄存器中的一个立即值。通常,mov指令不影响标志,因此这对cpu来说没有符号或无符号或任何意义,除了一些进入寄存器的位。假设此伪代码有32位寄存器和地址空间

如前所述,r0将索引保存在结构数组中,因此我们乘以32,左移位指令不关心这是索引还是移位5与结构有关。它只是将位馈入alu,导致位向一侧移位,零向另一侧移位。一些CPU将最后一位移到进位位,不是作为进位位,而是作为级联移位的位置保持器,同样可以计算ZFLAG和N标志(符号位),以防万一您认为这是一个二进制补码数(移位之后),或者在编程中需要一些捷径。但这些只是cpu的位,没有意义

在这一点上,我们人类认为r2在内存中保留了一个偏移量,用于结构数组的索引,但对于cpu来说,它只是一个位。我们执行add。我们认为一个操作数是一个地址,另一个是偏移量,但是对CPU来说,它们只是运行的位。加法通常不关心有符号和无符号,两个补码的优点是可以将无符号和有符号输入到同一加法器逻辑中,这通常会计算执行标志(无符号溢出)和v标志(有符号溢出)加上z标志,z
mystruct[j].f=mystruct[i].f;
ldr r1,mystruct_base
shl r2,r0,#5
add r2,r2,r1
ldr r0,[r2]
shl r2,r3,#5
add r2,r2,r1
str r0,[r2]