2012-02-15 62 views
2

我的印象是,如果程序为变量类型整数(其大小为8字节)保留内存,则保留的内存将是8个不同的寄存器,这些寄存器将在内存中顺序显示。如何使用内存寄存器来保存不同的类型?

我的问题如下:

1)假设的答案会有所不同是我上面一个很好的概括,通过不同类型的变量需要每个字节相当于出在内存使用1个寄存器变量? (即1个字节要求内存中有一个寄存器)

2)如果这是真的,那么每个寄存器在内存中的位数是多少?或者,如果我购买了32位计算机,这是否意味着内存中的每个寄存器都拥有32位?

3)如果整数类型8字节的大小需要8个不同的寄存器,每个不同的寄存器包含什么?

4)另外我想了解类型的想法。我知道,如果你有32位与你一起工作可以代表无符号整数值从0到4294967295.然而,如果我存储了无符号整数 4294967295在一个32位存储单元如何知道二进制文件在此存储单元内的表示需要解码为无符号整数格式?也就是说,为特定类型预留的内存是否指定某种类型或指针是指定类型还是可能完全不同的内容?

我通常对二进制算术,汇编语言,引用,指针以及变量和数组如何存储在内存堆中的知识有所了解(所以我会理解使用这些上下文的任何答案)。我可以用C,C++和Java编程。感谢任何帮助。

回答

2

1,2,3:不将内存称为寄存器;尽管我已经看到它在混淆之前完成。一个64位的处理器有8个字节宽的寄存器,而一个32位的处理器有4个字节宽的寄存器,但是当这些寄存器复制到RAM时,它只是存储器中的字节。哪个字节取决于处理器的字节顺序存储了哪个字节的部分:小端系统会将0x1中的1位存储在8字节的第一个(最低)地址中,而大端系统将存储它在最后。

4:CPU不知道也不在乎; “types”是一种高级语言结构,对一个CPU来说一切都是一个数字:“abcd”是一个数字,因为0xf0f0f0f0是一个数字。你必须根据你想要它做什么来给它指示,例如对于x86,如果您希望它将数字视为已签名,则使用IDIV而不是DIV。

2

类型对于程序设计语言的益处大部分是虚构的。对于处理器来说,位是位,它们在执行单条指令期间有时会暂时没有意义,在指令结束时失去它们的含义。

的Dijkstra:“计算机科学是没有更多的电脑比是天文望远镜左右”

需要TP指定你有兴趣在你的问题,或者你有兴趣的处理器一般的处理器。目前处理器的通用组合不同,从8位寄存器到64位或更大,其中8位,16位,32位,64位寄存器处理器都被表示出来。

也不会对一切都在寄存器中感到困惑,有些处理器有很多寄存器,并且在高级代码中有很多项目在寄存器中呆了一段时间,而其他处理器没有很多寄存器,并且大部分变量居住在内存中不在寄存器中。即使寄存器长时间保存这些数据,通常也不会有变量存在一些内存。优化器确实混淆了这种平衡,所以很难做出一般性陈述。

你说你知道汇编语言,借此汇编语言伪代码,例如:

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地址和从存储器加载它被放入或由一些码使用。

我们可能碰巧知道的位是存储器中结构数组存在的地址,但现在,对于mov指令,它只是位,我们正在将一个立即数加载到寄存器中。通常mov指令不会影响标志位,所以除了一些进入寄存器的位以外,它没有任何有符号或无符号或对cpu有任何意义。假设对于该伪代码

如前所述R0保持索引结构的阵列32位寄存器和地址空间,因此我们通过32相乘,移位左指令不关心,这是一个索引或5的移位与结构有关,它只是被送入alu的位,导致位移出一边,零位移到另一边。一些CPU将采取移出的最后一位入进位位,而不是作为一个进位,但作为级联转移的占位符,同样是zflag可能被计算和n标志(符号位),以防万一你认为这是一个二进制补码(转换后),或者想要在编程中使用一些快捷方式。但这些只是CPU的一小部分,没有意义。

在这一点上,我们作为人类认为R2作为持有的索引结构的阵列,但到CPU它只是位偏移到内存中。我们执行添加。我们认为一个操作数是一个地址,另一个是偏移量,但是对于CPU,它们只是被操作的位。添加的一般不约签署VS无符号的照顾,二进制补码的漂亮就可以提供给未签名并签署到同一加法器的逻辑,这往往计算进行标志(无符号溢出)和V标志(符号溢出)以及Z标志,零和n标志的负面结果,都在一个镜头中,没有,如果这对添加有任何意义,就像计算结果一样,如果你想使用标志的东西。在这种情况下,CPU无法知道我们正在计算地址。

现在我们在寄存器中作为地址位定义和执行的负荷。但是,只有cpu认为这是一条指令的地址,一段时间之后,刚才注册的那些位是一个加法操作的结果。

什么是我们从内存中读取?更多位,而不是浮点值,只有32位。现在一些cpus可能有一种直接的方法来将内存中的内容直接加载到浮点寄存器中,一些cpus没有浮点,并且它们都与通用寄存器合成。即使是那些与浮点例如如果上面的代码是做可能会使用GPRS浮点值,这样的:

mystruct[j].f=mystruct[i].f; 

你可能不会要刻录的FPU寄存器,如果你能,你可以使用一个GPR为我有以下。如果在这个代码附近没有实际的浮点数学运算,它只是将位从一个位置移动到另一个位置,没有理由涉及到fpu。

上面的代码行可能是这样的,当一切都成定局:

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] 

其中r0是我当进入这个代码和R3为j。除了少数例外情况,CPU不知道或关心这些位。因为ldr和str r2是在指令时间段内被认为是内存地址的东西。除此之外,没有结构或浮点或有符号或无符号整数。没有。只是位。

是的,通常当有人说32位计算机,他们的意思是32个寄存器。这是一个很好的概括,通常比特大小也是内存总线的地址大小,32位意味着您可以在理论上解决32位内存的价值4GBytes。正如你可能从x86或其他人那里得知的那样,这会变得有些模糊。通常,尤其是x86,你会看到一个64位的处理器在32位模式下运行,基本上运行的代码/指令期望32位寄存器不是64位,而x86中的“寄存器”有不同的访问方式8,16, 32或63位,所以你可以玩这些游戏。

所有这些问题你问,更是回答了在一个处理器的汇编语言。不幸的是,现在mips会迷惑你,而x86也是如此,所以要避免这些,首先要选择像msp430或者ARM或者ARM这样的简单模式来学习。

+0

TL;博士,但+1自耕农努力和记忆举Edsgar叔叔。 – 2012-02-18 03:22:53