【问题标题】:Copying 4 bytes directly into a DWORD (MSB becomes LSB)将 4 个字节直接复制到 DWORD 中(MSB 变为 LSB)
【发布时间】:2014-01-12 13:59:33
【问题描述】:

所以我正在查看memcpy 的汇编指令,我想知道代码中嵌入的汇编指令是否负责在执行memcpy 之后(最高有效字节被更改为最低有效字节) .

http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/osfmk/x86_64/bcopy.s

ENTRY(memcpy)
    movq    %rdx,%rcx
    shrq    $3,%rcx             /* copy by 64-bit words */
    cld // is this instruction responsible for the MSB being switched to LSB
    rep
    movsq
    movq    %rdx,%rcx
    andq    $7,%rcx             /* any bytes left? */
    rep
    movsb
    ret

我希望memcpy 将Octet[0] 复制到DWORD 变量中,同时将其保留为最高有效字节。 (31-23)

#include <iostream>

using namespace std;

int main()
{

unsigned char Octet[4];

Octet[0] = 'A';
Octet[1] = 'B';
Octet[2] = 'C';
Octet[3] = 'D';

unsigned int Dword;

memcpy( &Dword, Octet, 4);

cout << hex << Dword << endl;

所以在调用 memcpy 之后,这些值会按以下顺序存储到 DWORD 中。

44434241

如果我在删除 CLD 指令的同时创建了一个自定义 memcpy 函数将保留字节顺序或将其替换为 SLD 将是获得所需结果的可行解决方案。

41424344

【问题讨论】:

  • Memcpy() 从不改变字节顺序。破解 CLD 只会使您的代码崩溃。你在初始化 Octet[] 时出错了。
  • 英特尔处理器是小端的,所以你得到的正是预期的(即,在多字节数中,第一个字节将是最不重要的)。如果您想将数字从 big-endian 转换为当前主机使用的任何值,请考虑使用类似 ntohl 的内容。
  • 一个 char 数组没有字节序,所以谈论这个甚至没有意义。

标签: c++ assembly x86 endianness


【解决方案1】:

我没有看过实际的汇编代码,但是在任何小端计算机上你都会得到你提到的结果。十六进制输出总是从 MSB 打印到 LSB,在小端计算机上,MSB 将是最后一个字节。

听起来你想要的最好通过以下方式完成:

Dword = Octet[0] << 24 | Octet[1] << 16 | Octet[2] << 8 | Octet[3];

这是我所知道的将 MSB 中的 Octet[0] 降低到 LSB 中的 Octet[3] 的唯一标准方法。

【讨论】:

  • 我明白这一点,但我想如果方向标志被改变了。我会得到想要的结果。
  • 好吧,您的问题令人困惑,因为您暗示 MSB/LSB 正在被更改/交换,而实际上它是字节形式时没有 MSB/LSB。
  • 我知道 shift 方法,但我正在寻找更多的东西。那不会进行多次复制/移位操作。好吧,我很抱歉改变了您的看法,但在低级时总是会变得如此痛苦。
  • 这不是感知问题。字符数组(这是 memcpy 的工作)没有 MSB 或 LSB。因此,说 memcpy 将 MSB 转换为 LSB 是不正确的。
【解决方案2】:

所以这是一个快速破解,但是我想知道其他平台是否支持类似于BSWAP 的类似指令。

    asm volatile ("movl %1,%%eax;\n"
                  "bswapl %%eax;\n"
                  "movl %%eax, %0;\n"
             : "=r" (Dword)
             : "r" (Dword)
             : "%eax"
             );

【讨论】:

  • 你不能用一条 asm 指令完成这个吗:asm ("bswapl %0" : "+r" (Dword) );?
猜你喜欢
  • 1970-01-01
  • 2010-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-17
  • 1970-01-01
  • 2011-11-09
相关资源
最近更新 更多