解释缺少适用于字符串的字节序

问题描述

对于这个问题,我将假设每个字符都是单字节ascii。如果我的理解是正确的,则字节顺序适用于多字节字的字节顺序。因为字符串每个字符只有一个字节,所以没有字节序。

但是这使我有些困惑,因为字符串通常在字符串的“结尾”处以nul字符存储,就字节顺序而言这不重要吗?例如,

.data
my_string: .asciz "Save"

现在进入gdb,以打印S a v e的存储位置:

>>> x/cb &string
0x4000b9:   'S'
>>> x/cb (char *) &string+1
0x4000ba:   'a'
>>> x/cb (char *) &string+2
0x4000bb:   'v'
>>> x/cb (char *) &string+3
0x4000bc:   'e'          # LSB at highest memory address (big endian??)

这里的字符串实际上不是'big endian'吗,因为最低有效字节(e)存储在最高内存地址(string+3)中吗?

我缺少哪一部分的尾数对字符串有无影响?我想也许我可能误认为char-array索引的字节顺序,但是要明确指出答案会很棒。

解决方法

字节序只能存在于以较大访问大小作为单个字节访问的数据。如果要对字符串数据进行DWORD加载,则字节序将决定register &= 0xFF是否将字符串的第一个或最后一个字符隔离。 (在x86上,movzx edx,al会隔离第一个字节,因为x86是little-endian:低地址字节结束于寄存器中更接近右移的位置。)

如果不这样做,仅查看每个字节的地址,则不适用整个字节序的概念。字节的顺序由其地址决定。最后包括ASCII NUL '\0' aka 0字节。在这方面并不特殊。

,

在这种情况下,地址空间基于字节,单个地址指向字节。因此,您不能使用字节数量的字节序,它必须是多个字节。

如果有

0x1000 'S'  (0x53)
0x1001 'a'  (0x61)
0x1002 'v'  (0x76)
0x1003 'e'  (0x65)

那里没有字节序。字符串是各个字节,它们按顺序地址线性表示内存中的字符。

如果要检查那些BYTES,则不再是字符,而是带有32位WORD视图的字节

0x1000: 0x53617665 is a typical big endian view
0x1000: 0x65766153 is a typical little endian view

对于32位读取时地址0x1000处的相同数据。这时不是字符串,而是在某个地址一次查看32位字节。如果您试图以字节AND形式查看/使用数据,并且由于某种原因试图对同一数据进行两次查看,那将是AND的事情。我们不是这样认为ASCII字符串的。

请注意字符串,整数,浮点数,布尔值,地址,所有数据类型均与处理器无关,位是位,使用时它们对处理器和用户均不重要。否则,它们只是没有意义的位。您可以通过像memcpy()那样进行字读写来“复制”(n ASCII)“字符串”,对您来说,它是一个字符串,但是例如,它只是要复制的字节。大字节序或小字节序无关紧要,所有字节按组拾取和放下,当由该处理器及其寻址方式视为线性字节字符串时,它仍然看起来像字符串。

基于处理器的这些一般性声明有一些例外,这些处理器具有不同的字节序模式和我当然已经经历过的各种其他非典型情况,但在这里无需混淆。通常的理解是,低位地址字节是访问中的最高有效(大字节序)或最低有效(小字节序)字节,访问字节大小为多个字节(16位,32位,64位等)。假设一个字节是系统的8位,则9个字节和其他大小的字节不会改变,这只会更改访问的大小。

字节序的最大问题是人们试图使它过于复杂。 “ OMG这是X字节序处理器,我习惯了Y字节序处理器,这将使我的生活变得困难,我将不得不玩具有寻址功能的游戏,并做所有这些额外的工作。”不,总的来说,您只是创造了一个不存在的问题,现在您必须修复一些错误。

正确的答案是首先了解系统,而不用想到那个电子词,然后,当您看到总线或外围设备及其接口或数据对象时,您需要从网络或文件系统等中移动。然后,您将它们与计算机的e-word进行比较,并从系统工程的角度决定是否已经对此系统的e-word进行了访问,或者是否需要移动或字节交换或否则转换数据,以便当我对该数据执行操作X时,它的方向正确。如果您不必执行实际操作,添加一些数字等等,您是否还关心呢?如果您只是将数据从A点传输到B点,并且系统工程表明不需​​要进行任何数据处理(从硬盘驱动器中读取文件并通过网络进行传输),则无需考虑或交谈关于电子词。