3 votes

Echanger l'octet le plus significatif et l'octet le moins significatif en assembleur

Supposons que nous sauvegardions le nombre 1 dans le registre EAX et que nous échangions l'octet le plus significatif avec l'octet le moins significatif. Le nouveau nombre échangé est-il 256 ou 16777216 ?

Je l'ai essayé dans un programme assembleur en échangeant la valeur de l'AL- avec la valeur du AH-Registre. Mon résultat était de 256. Je ne pense pas que ce soit correct et je ne comprends pas non plus le résultat de 256. Je pensais que le registre EAX était de 32 bits et non de 16 bits.

La question est liée au résultat correct de l'échange.

6voto

Rudy Velthuis Points 11477

Il existe un opcode spécial pour cela, appelé BSWAP par exemple :

    MOV     EAX,1   ; EAX is 0x00000001  or 1 decimal  
    BSWAP   EAX     ; EAX is 0x01000000  or 16777216 decimal

Il échangera tous 4 octets de n'importe quel registre général de 32 bits. Cela permet de convertir les valeurs 32 bits little-endian en big-endian et vice versa.

Pour information, pour permuter les octets d'une valeur de 16 bits, par exemple en AX vous pouvez faire

    MOV     AX,1    ; AX is 0x0001 or 1 decimal
    XCHG    AL,AH   ; AX is 0x0100 or 256 decimal

Ou, selon @PeterCordes :

    MOV     AX,0x1234
    ROL     AX,8    ; AX is 0x3412 now

Il n'y a pas d'opcode spécial pour échanger seulement les octets supérieurs et inférieurs d'un registre de 32 bits (et laisser les deux autres intacts). Vous pouvez seulement faire quelque chose comme ceci :

Editar

<Suppression du code utilisant ROR , XCHG AL,AH , ROL y BSWAP >

Comme @Fifoernik l'a fait remarquer dans un commentaire (merci !), beaucoup plus facile que le code que j'ai supprimé est le suivant :

    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

Edit 2

Comme le souligne @PeterCordes, cela pourrait même être un peu plus rapide :

    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

Mais je n'ai chronométré ni l'un ni l'autre.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X