Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 读奇怪的地址,半个字?_Assembly_Cross Platform_Endianness_Cpu Architecture_Word Size - Fatal编程技术网

Assembly 读奇怪的地址,半个字?

Assembly 读奇怪的地址,半个字?,assembly,cross-platform,endianness,cpu-architecture,word-size,Assembly,Cross Platform,Endianness,Cpu Architecture,Word Size,众所周知,许多CPU体系结构(ARM、PPC)不能读取奇数地址,但如果强制也会生成异常,而其他CPU体系结构也可以,但读取速度稍慢。(x86) 但是有没有CPU只能处理32位(甚至更大)的字呢?也就是说,它不能寻址16位字?也许是amd64 我正在尝试编写一个可移植但快速的C malloc类分配器,并希望正确地对齐内存访问。目前,我的目标是ARM、i386和amd64,这些我可以查找特性,但我认为最好保持警惕 我想一个具体的提问方式是 是否有CPU从地址0x2读取16位(为了论证接近0的地址范围

众所周知,许多CPU体系结构(ARM、PPC)不能读取奇数地址,但如果强制也会生成异常,而其他CPU体系结构也可以,但读取速度稍慢。(x86)

但是有没有CPU只能处理32位(甚至更大)的字呢?也就是说,它不能寻址16位字?也许是amd64

我正在尝试编写一个可移植但快速的C malloc类分配器,并希望正确地对齐内存访问。目前,我的目标是ARM、i386和amd64,这些我可以查找特性,但我认为最好保持警惕

我想一个具体的提问方式是

是否有CPU从地址0x2读取16位(为了论证接近0的地址范围通常是有效的,我知道有些CPU不使用第一页)会产生总线错误,其中CPU=MIPS、ARM、x86、amd64、68k、88000、SH、OpenRISC、Sparc、PPC、Cell/SPE中的任何一个


(顺便说一句,我是从C程序员的角度来看这整件事的。所以我假设C编译器给了我所有正常的C类型,比如char、uint32\t等等。)

如果你能处理一个16位的数量,那么你肯定可以读取16位对齐的数量。我认为您可能假设您将有一个字节可寻址的地址空间。您可能不会,因此建议谨慎。可以肯定的是,某些体系结构(特别是嵌入式体系结构)可能不是字节或甚至16位可寻址的——尽管我不知道具体的(和当前的)示例

这真的重要吗?如果你碰巧有一台32位可寻址字长的可字寻址机器,那么你永远也不可能只寻址16位。不过要小心sizeof

您询问了有关amd64(x86-64)的信息。它对内存对齐的访问没有限制,但您可能会因为未对齐的访问而丢失周期。请记住,未对齐的访问永远不会是可移植的

更新:什么是对齐地址

类型T的对齐地址是sizeof(T)的倍数,其中sizeof(T)是该值占用的可寻址单元数。例如,如果在字节可寻址空间中有32位字大小,则对齐的地址至少是4的每一个倍数。但是,如果机器可寻址为16位单位,则每个2的倍数地址都将是32位数量的对齐地址

如果您正在读取16位量,则有三种情况:

  • 字节寻址:奇数地址可能未对齐。体系结构可以自由地将它们视为对齐的,但没有太多
  • 可寻址单元为16位:所有地址针对16位数量对齐
  • 可寻址单元更大:实际上没有16位的数量。它们更大
  • 更新2:是否有CPU从地址0x2读取16位(假设地址范围有效)会导致总线错误

    除非可寻址单元低于8位,否则永远不会有这样的CPU。原因是地址0x2的对齐方式是2个可寻址单元。如果可寻址单元为8位,则为16位对齐

    此外,16位的意图排除了可寻址单元大小的奇怪值。如果16位值是体系结构的实际数量,则可寻址单元的值必须是16的系数。所以它只能是1、2、4、8或16位。如果它恰好更高,对齐就非常满意


    由于地址小于8位的体系结构不值得费心,您几乎可以保证地址0x2将是16位数量的对齐地址。

    一些早期IBM Power处理器只能读取/写入项目大小边界,但会使用陷阱(异常)处理程序处理未对齐的数据。(我认为甚至有一个早期版本会说“OK”,然后默默地给出对齐单词的内容,忽略地址的低位。)

    可以肯定的是,旧的IBM 7000系列机器只能在36位边界(字大小)上读/写一个完整的字,这仅仅是因为没有比这更细粒度的地址概念。但我相信他们有读/写低/高半字操作

    HP 2100系列处理器IIRC只有字(16位)地址,但可以进行字节索引。但是,该索引仅被解释为字节ops的字节索引,否则它就是一个单词索引


    不过,就对齐malloc而言,通常应该在缓存线边界上对齐。否则,在MP环境中很难防止缓存抖动。

    单元的SPE只有16字节四字加载/存储,并且必须在16字节边界上对齐

    如果需要以更精细的粒度进行寻址,则必须读修改写,并使用位掩码仅更新数据的相关部分

    显然,在C/C++中,编译器将对此提供帮助,并且指令集中支持生成和使用掩码


    对于从地址“2”读取16位的示例,您必须从地址“0”读取128位并屏蔽所需的位。如果要将16位写入地址“2”,则需要先读取所有128位,然后更新相应的16位,然后将整批写回。

    DSP样式的单元如何?同样在b4中,您的编程问题是什么?DSP风格的单元,我对它知之甚少@长颈鹿船长可以随意向问题列表中推荐另一个CPU@CaptainGiraffeCell的SPE只能读/写16字节的四字:)(显然你可以绕过这个限制进行编码,就像我想象你在大多数arch上所做的那样)@JasonD,SPE,显然可以用标准的C编译器()进行编码,所以我把它包括在我感兴趣的列表中。如果你把你的评论作为一个回答并详细阐述一下,我会接受的。真的是这样吗?我是说68000