在汇编程序中交换最重要的字节和最低有效字节

Raz*_*zmo 3 x86 assembly byte cpu-registers

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

我在汇编程序中通过交换AL-的值和AH-Register的值来尝试它.我的结果是256.我不认为这是正确的,我也不理解256的结果.我认为EAX寄存器是32位,而不是16位.

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

Rud*_*uis 6

这有一个特殊的操作码BSWAP,例如:

    MOV     EAX,1   ; EAX is 0x00000001  or 1 decimal  
    BSWAP   EAX     ; EAX is 0x01000000  or 16777216 decimal
Run Code Online (Sandbox Code Playgroud)

它将交换任何32位通用寄存器的所有 4个字节.这会将little-endian 32位值转换为big-endian,反之亦然.

FWIW,交换16位值的字节,例如AX,你可以做到

    MOV     AX,1    ; AX is 0x0001 or 1 decimal
    XCHG    AL,AH   ; AX is 0x0100 or 256 decimal
Run Code Online (Sandbox Code Playgroud)

或者,根据@PeterCordes:

    MOV     AX,0x1234
    ROL     AX,8    ; AX is 0x3412 now
Run Code Online (Sandbox Code Playgroud)

没有特殊的操作码来交换只有一个32位寄存器的顶部和低字节(并保留其他两种完整).你只能这样做:

编辑

<删除代码使用ROR,XCHG AL,AH,ROLBSWAP>

正如@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
Run Code Online (Sandbox Code Playgroud)

编辑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
Run Code Online (Sandbox Code Playgroud)

但我没有时间.