我正试图在自己设计的一个非常破旧的体系结构下模拟一台32位计算机。我可能每件事都做错了,但这只是一件有趣的事情,我正在自学C。我遇到了一个小问题,我不知道应该将一个数字的多少字节保存到内存中。
现在我有一个指令,看起来像这样:CODE, (addressing info), add-a, add-b, add-c
。操作码和寻址信息为4位长,地址为8位长。如果我加上2个32位数字(b和c),它们会保存在地址a。当我的数字小于32位时,就会出现问题。例如,如果我有一个1字节字符的数组,无论出于什么原因,我想在其中一个数字上加1,当我将1字节字符保存回该数组时,它将被写为32位数字,从而覆盖随后的3个字符。
我真的不确定解决这个问题的最佳方法,但我有一些想法。
想法1:只需在32位块中完成所有操作。让程序员自己处理这个问题。(做一些时髦的逐位操作,将1字节的字符重新放入数组。也许可以使用掩码)我不想这样做,因为这会使代码变得混乱。
想法2:只允许每32位有一个地址。如果每个数字都是32位长,则不会覆盖任何数字。据我所知,这很糟糕,没有什么能做到这一点。这将使保存较小的数字所占用的内存是所需内存的4倍
想法3:停止使用32位数字。只有加法,减法,存储,得到8位数字。这会起作用,可能不会那么乱,但也会很烦人。添加32位数字会突然花费至少4行代码,然后程序运行速度会变慢。这也意味着移动代码行也需要至少4行代码,因为每行代码有4个字节长。
基本上我不知道自己在做什么,我可以在网上找到任何人谈论这件事。我确信要么有明显的东西,要么我在做一些愚蠢的事情,我需要重新设计整个系统。。。
另请注意,我不确定这是否是问这种问题的正确地方,但如果不是,我很想知道在哪里
您提到的所有想法似乎都有一个共同的概念,即通过(a)从较小的存储单元组装较大的物品,反之亦然,(b)将较小的物品打包到较大的存储单元中,来限制硬件的功能,并使软件满足其剩余的需求。
一般来说,这就是计算的工作方式,只提供有限的硬件功能,并让软件弥补任何不足。理想情况下,有限的功能与常见的软件模式非常匹配,例如字符串、各种大小的整数、浮点等
多年来,许多处理器多次改变了硬件内置功能和软件补偿之间的界限。
软件通常必须在当今任何机器组织中同时完成这两项工作。如果你想要一个布尔值数组,那么你可能想把它们打包成字节(或字),并从中设置/提取比特,这就是(b)。另一方面,如果你想要长字符串或多字数字数据,那么软件会将一些更大数量的存储单元组装成一个整体,这就是(a)。
现代64位硬件提供至少1字节、2字节、4字节和8字节的数据(模向量)。通过提供这些数据大小,我们的意思是它提供了直接对这些大小进行操作的指令,即用它们做有用事情的单个指令。
然而,没有现代的位可寻址机器,所以如果你想要小于一个字节(有时很合理),你必须用软件来处理。
此外,如果你想要3、5、6或7字节的数据,硬件不一定直接提供——尽管对未对齐加载的支持有帮助,因为这样你就可以加载更大的大小并屏蔽坏的部分;存储类似于读-修改-写。
如果您想要9字节或更大的字节,则必须使用多个加载和存储指令,尽管硬件中的错位功能有助于解决奇数大小的问题。
一些指令集通过移除字节加载&存储指令(同时保持字节可寻址),尽管提供了从寄存器中的字提取正确字节的专用指令,以便仍然为没有未对齐负载的硬件上的字节操作提供一些硬件加速,因为在没有字节负载、未对齐能力或特殊辅助指令的情况下,从字中提取适当的字节可能需要多个指令和/或重复加载相同的存储器字以进行顺序访问。
我提倡加载/存储模式。这意味着丰富的负载&存储指令:,加载有符号字节,加载无符号字节,有符号半,无符号半,字(32),双。在这样的模型中,算术是寄存器对寄存器的,所以你不需要小于单词大小的加法。没有一种主流编程语言需要字节加法,而字节算术甚至不能在加载/存储体系结构中提供优化。
但是,在设计单独的指令时,您需要将体系结构作为一个整体来考虑。