在x86汇编中将Little Endian四字节长整数转换为Big Endian的最佳方法,反之亦然

时间:2014-02-08 05:51:02

标签: assembly x86

所以我想出了如何在C:

中反转四字节长int的endianess
unsigned int swapWord (unsigned int n){
   return (n>>24) | ((n<<8) & 0x00FF0000) |((n>>8) & 0x0000FF00) | (n<<24);
}

现在我知道我可以反汇编这个,我做了,这是不错的代码,但我确信有一种更有效的方法来扭转结束。有什么想法吗?

编辑:这是反汇编的代码:

00000000004005a3 <swapWord>:
      4005a3:   55                      push   %rbp
      4005a4:   48 89 e5                mov    %rsp,%rbp
      4005a7:   89 7d fc                mov    %edi,-0x4(%rbp)
      4005aa:   8b 45 fc                mov    -0x4(%rbp),%eax
      4005ad:   c1 e8 18                shr    $0x18,%eax
      4005b0:   89 c2                   mov    %eax,%edx
      4005b2:   8b 45 fc                mov    -0x4(%rbp),%eax
      4005b5:   c1 e0 08                shl    $0x8,%eax
      4005b8:   25 00 00 ff 00          and    $0xff0000,%eax
      4005bd:   09 c2                   or     %eax,%edx
      4005bf:   8b 45 fc                mov    -0x4(%rbp),%eax
      4005c2:   c1 e8 08                shr    $0x8,%eax
      4005c5:   25 00 ff 00 00          and    $0xff00,%eax
      4005ca:   09 c2                   or     %eax,%edx
      4005cc:   8b 45 fc                mov    -0x4(%rbp),%eax
      4005cf:   c1 e0 18                shl    $0x18,%eax
      4005d2:   09 d0                   or     %edx,%eax
      4005d4:   5d                      pop    %rbp
      4005d5:   c3                      retq   
      4005d6:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
      4005dd:   00 00 00 

1 个答案:

答案 0 :(得分:4)

对于80486及更高版本,有一条名为bswap的指令在双字中交换字节。

对于较旧的80386 CPU,我很想使用这样的东西:

                     ;eax = 0xAABBCCDD
    xchg ah,al       ;eax = 0xAABBDDCC
    rol eax,16       ;eax = 0xDDCCAABB
    xchg ah,al       ;eax = 0xDDCCBBAA

对于更老的CPU(8086到80286),你必须使用一对16位寄存器(因为没有32位寄存器),它最终会像这样:

                     ;dx:ax = 0xAABBCCDD
                     ;ax:dx = 0xCCDDAABB
    xchg ah,al       ;ax:dx = 0xDDCCAABB
    xchg dh,dl       ;ax:dx = 0xDDCCBBAA

注意:您可以使用xchg ah,alror ax,8,而不是rol ax,8。我怀疑你使用这三条指令中的哪一条会有很大的不同。