Assembly EAX寄存器的反向字节顺序

Assembly EAX寄存器的反向字节顺序,assembly,x86,masm,endianness,masm32,Assembly,X86,Masm,Endianness,Masm32,示例:0xAABBCCDD将变成0xDDCCBBAA 我的程序崩溃了,因为在第一个XOR操作中发生了访问冲突异常 似乎有一个更好的简单解决方案,使用移动或旋转,但无论如何,代码如下: ;; ######################################################################### .486 .model flat, stdcall option casemap :none ; case sens

示例:
0xAABBCCDD
将变成
0xDDCCBBAA

我的程序崩溃了,因为在第一个XOR操作中发生了访问冲突异常

似乎有一个更好的简单解决方案,使用移动或旋转,但无论如何,代码如下:

  ;; #########################################################################

      .486
      .model flat, stdcall
      option casemap :none   ; case sensitive

;; #########################################################################

      include \masm32\include\masm32.inc
      include \masm32\include\kernel32.inc

      includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\masm32.lib


.code
;; The following program will flip the sequence of the bytes in the eax
;; example : 0xAABBCCDD will turn into 0xDDCCBBAA
start:
MOV eax, 0AABBCCDDh 
XOR BYTE PTR [eax], al ;; Swap first byte and last byte
XOR al, BYTE PTR [eax]
XOR BYTE PTR [eax], al 
XOR BYTE PTR [eax+1], ah ;; Swap 2nd byte of eax and 3rd byte
XOR ah, BYTE PTR [eax+1]
XOR BYTE PTR [eax+1], ah
end_prog:
    ;;Exit the program, eax is the exit code
    push eax
    call ExitProcess
END start
我做错了什么?有更好的解决方案吗?

为什么不简单地:

 mov  eax, 0AABBCCDDh
 bswap eax
我不确定您试图在程序中做什么,但可以说出CPU实际尝试做什么(但不能,这就是崩溃的原因):

这个:

XOR BYTE PTR [eax], al 
尝试计算寄存器AL中的值(字节大小)和地址0AABBCCDDh(EAX寄存器的内容)处内存中字节的值的异或运算。只要这个地址上没有操作系统分配的内存,程序就会因GPF而崩溃

不使用bswap的正确字节交换如下(感谢):

那么

    mov eax, 0AABBCCDDh
    xchg al, ah ; 0AABBDDCCh
    rol eax, 16 ; 0DDCCAABBh
    xchg al, ah ; 0DDCCBBAAh

这难道不符合一个登记册的要求吗?我看到X.J已经发布了(向左旋转,向右旋转-相同的结果)必须快速击败你们

仅使用
rol
说明的替代解决方案:

mov eax,0xAABBCCDDh
rol ax,8            ; 0AABBDDCCh
rol eax,16          ; 0DDCCAABBh
rol ax,8            ; 0DDCCBBAAh

我相信,在大多数情况下,这将比使用
xchg
指令稍微快一点,尽管我认为没有理由不简单地使用
bswap
,它更干净而且可能更快。

,因为我从来不知道有这样的操作码:),而且无论如何,你能看出程序崩溃的原因吗?或者如果有另一种解决方案不使用bswap操作码?我仍然不知道到底出了什么问题。我试图在0xAA和0xDD之间进行异或操作。(第一个字节和最后一个字节),但您正试图在DD(在AL中)和地址AABBCCDD处的某个内存字节之间执行异或操作。你了解内存和寄存器之间的区别吗?还要注意的是,在x86中,您对寄存器的上16位没有字节访问权限。例如,您可以生成XOR AH,AL(无方括号!),它将生成XOR 0CCh,0DDh,但EAX的上部没有字节寄存器;ror-eax,16;xchg-ah;现代的x86 CPU有并且你甚至不需要MOV那么BSWAPWow,这是一个伟大的解决方案,谢谢!我会+1你,因为我已经接受了约翰的答案,这是一个非常酷的解决方案,但请记住,它可能会慢一些。使用部分寄存器通常非常昂贵,因为大多数x86 CPU不维护不同的寄存器,并且在每次部分写入时必须进行昂贵的合并。是的,这比现代CPU上的
bswap
慢,但比
xchg
快得多,因为
rol reg,imm
是一个uop(),并且因为它避免了写入AH()因此,在Sandybridge家族中,部分寄存器合并比较便宜或不存在。基于
xchg
的版本在386(更小的代码大小)上可能更好。使用此功能时,您需要与古老的CPU兼容(
bswap
需要486),但需要关注现代CPU,因为
xchg
是多uop。
mov eax,0xAABBCCDDh
rol ax,8            ; 0AABBDDCCh
rol eax,16          ; 0DDCCAABBh
rol ax,8            ; 0DDCCBBAAh