Assembly 在汇编程序中交换最高有效字节和最低有效字节

Assembly 在汇编程序中交换最高有效字节和最低有效字节,assembly,x86,byte,cpu-registers,Assembly,X86,Byte,Cpu Registers,假设我们将数字1保存在EAX寄存器中,并将最高有效字节与最低有效字节交换。新交换的号码是256还是16777216 我在一个汇编程序中通过将AL-的值与AH寄存器的值交换来尝试它。我的成绩是256分。我不认为这是正确的,我也不理解结果。我认为EAX寄存器是32位,而不是16位 该问题与交换的正确结果有关。为此有一个特殊的操作码,称为BSWAP,例如: MOV EAX,1 ; EAX is 0x00000001 or 1 decimal BSWAP EAX

假设我们将数字1保存在EAX寄存器中,并将最高有效字节与最低有效字节交换。新交换的号码是256还是16777216

我在一个汇编程序中通过将AL-的值与AH寄存器的值交换来尝试它。我的成绩是256分。我不认为这是正确的,我也不理解结果。我认为EAX寄存器是32位,而不是16位


该问题与交换的正确结果有关。

为此有一个特殊的操作码,称为
BSWAP
,例如:

    MOV     EAX,1   ; EAX is 0x00000001  or 1 decimal  
    BSWAP   EAX     ; EAX is 0x01000000  or 16777216 decimal
它将交换任何32位通用寄存器的所有4字节。这会将小端32位值转换为大端值,反之亦然

FWIW,要交换16位值的字节,例如在
AX
中,可以执行以下操作

    MOV     AX,1    ; AX is 0x0001 or 1 decimal
    XCHG    AL,AH   ; AX is 0x0100 or 256 decimal
或者,根据@PeterCordes:

    MOV     AX,0x1234
    ROL     AX,8    ; AX is 0x3412 now
没有特殊的操作码,只能交换32位寄存器的高位字节和低位字节(并保持其他两个字节不变)。您只能执行以下操作:

编辑

正如@Fifoernik在评论中指出的(谢谢!),比我删除的代码简单得多的是:

    MOV     EAX,0x12345678
    ROL     EAX,8   ; EAX is 0x34567812  rotate left one byte: 12 34 56 78 --> 34 56 78 12
    XCHG    AL,AH   ; EAX is 0x34561278  swap 12 and 78:       34 56 78 12 --> 34 56 12 78
    ROR     EAX,8   ; EAX is 0x78345612  rotate back:          34 56 12 78 --> 78 34 56 12
编辑2 正如@PeterCordes所指出的,这可能会更快一些:

    MOV     EAX,0x12345678
    ROL     EAX,8   ; EAX is 0x34567812  rotate left one byte: 12 34 56 78 --> 34 56 78 12
    ROL     AX,8    ; EAX is 0x34561278  swaps 12 and 78:      34 56 78 12 --> 34 56 12 78
    ROR     EAX,8   ; EAX is 0x78345612  rotate back:          34 56 12 78 --> 78 34 56 12

但我都没有计时。

EAX的可能副本是32位,AX是EAX的低16位,AL和AH是AX的低字节和高字节。无法直接访问EAX的前16位。请参见相关内容:如果我可以使用AX寄存器获得较低的16位,那么如何获得EAX寄存器的高位?请参见上文……交换最低和最高有效字节时,
0x00000001
的值自然是
0x01000000
。如果您在将该值解释为整数时询问该值的十进制表示形式是什么,那么,是的,该值为16777216。也许可以向OP说明为什么交换ah和al会产生此结果。为什么在最后一段代码中坚持使用
BSWAP
?它只需要以下三个步骤:
roleax,8
XCHG-AL,AH
'ROR-EAX,8`。
ROL-AX,8
在大多数CPU上应该比
XCHG-AL,AH
更有效,因为它是1uop而不是3 uop。它还避免了Intel Haswell/Skylake上任何部分寄存器合并UOP。它也适用于任何注册,包括R8W…R15W。在英特尔HasWels/SkyLink的某些用途中,HE8寄存器比LoW8/LoW16寄存器慢一些;在写一个关于这个问题的问答的中间;当完成时,将发布一个链接。摘要:我认为只有AH与RAX、AL和AX不单独重命名。此外,阅读Ah增加了额外的1C延迟。我首先有一个2寄存器的解决方案,然后是1寄存器的解决方案,然后是由Fifoernik改进的以另一种方式旋转,现在连AX都由Peter Cordes旋转。尽管对于不熟悉x86汇编的人来说,
XCHG AL,AH
可能比
ROL AX,8
更容易理解,即使两者都实现了相同的功能。