home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.asm.x86      Ahh, the lost art of x86 assembly      4,675 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 4,025 of 4,675   
   Alex McDonald to Stephen Pelc   
   Re: Why does adding a 49 prefix to this    
   09 Mar 20 15:42:19   
   
   XPost: comp.lang.forth   
   From: alex@nospicedham.rivadpm.com   
      
   On 09-Mar-20 14:10, Stephen Pelc wrote:   
   > On 09 Mar 2020 07:39:30 GMT, albert@nospicedham.cherry (none) (albert)   
   > wrote:   
   >   
   >>> 58                               pop eax   
   >>> 48                               dec eax   
   >>> 81 C0 0C 00 00 00    add eax, 000000Ch   
   >>> 50                               push eax   
   >>> 48                               dec eax   
   >>> AD                              lodsd   
   >>> FF 20                          jmp dword ptr [eax]   
   >   
   > In AMD64, the 4x instructions are *all* REX prefices. The 48   
   > instruction is NOT a DEC reg instruction, it's a REX prefix.   
   >   
   > Stephen   
   >   
      
   As can be seen by disassembling in 32 bit mode and 64 bit mode;   
      
   mode64   
      
   10 constant ten   
   10. 2constant ten.   
   ' ten constant 'ten   
      
   code bar next;   
   code foo   
        mov al ten   
        mov ah ten   
        mov ax ten   
        mov eax ten   
        mov rax ten.   
        mov al  { 'ten }   
        mov ah { 'ten }   
        mov ax { 'ten }   
        mov eax { ' bar }   
        mov rax { 'ten }   
        movzx rax word { 'ten }   
        mov rax { 10. }   
        next;   
      
      
   see foo   
   code foo ( ? -- ? )   
   \ foo is defined in src/test1.fs at line 9   
   \ code=$41B9D1 len=73 type=129   
   ( $0 )    mov     al $A                             \ B00A   
   ( $2 )    mov     ah $A                             \ B40A   
   ( $4 )    mov     ax $A                             \ 66B80A00   
   ( $8 )    mov     eax $A                            \ B80A000000   
   ( $D )    mov     rax $A $0                       \ 48B8000000000A000000   
   ( $17 )   mov     al byte { rip ' ten }             \ 8A05B0FFFFFF   
   ( $1D )   mov     ah byte { rip ' ten }             \ 8A25AAFFFFFF   
   ( $23 )   mov     ax word { rip ' ten }             \ 668B05A3FFFFFF   
   ( $2A )   mov     eax dword { rip ' bar }           \ 8B05CAFFFFFF   
   ( $30 )   mov     rax qword { rip ' ten }           \ 488B0596FFFFFF   
   ( $37 )   movzx   rax word { rip ' ten }            \ 480FB7058EFFFFFF   
   ( $3F )   mov     rax qword { $A $0 }             \ 48A1000000000A000000   
   ( $49 )   ret                                       \ C3 ( end )   
      
   There are some interesting encodings that can be seen here, courtesy of   
   the REX prefix.   
      
   1. (at $D) the 64 bit immediate form of MOV RAX has a 64 bit operand.   
   (at $8) The EAX form is identical in effect if the constant is <= 32   
   bits (the high order bits in RAX are zeroed), but it encodes a good deal   
   shorter.   
      
   2. relative IP (RIP) addressing (there's an 8 bit form but it needs a   
   base register)   
      
   3. (at $3F) absolute addressing a 64 bit address.   
      
   When disassembled in 32 bit mode, yeuch. It's all wrong.   
      
   mode32   
   see foo   
   code foo ( ? -- ? )   
   \ foo is defined in src/test1.fs at line 9   
   \ code=$41B9D1 len=73 type=129   
   ( $0 )    mov     al $A                             \ B00A   
   ( $2 )    mov     ah $A                             \ B40A   
   ( $4 )    mov     ax $A                             \ 66B80A00   
   ( $8 )    mov     eax $A                            \ B80A000000   
   ( $D )    dec     eax                               \ 48   
   ( $E )    mov     eax $0                            \ B800000000   
   ( $13 )   or      al byte { eax }                   \ 0A00   
   ( $15 )   add     byte { eax } al                   \ 0000   
   ( $17 )   mov     al byte { $-50 }                  \ 8A05B0FFFFFF   
   ( $1D )   mov     ah byte { $-56 }                  \ 8A25AAFFFFFF   
   ( $23 )   mov     ax word { $-5D }                  \ 668B05A3FFFFFF   
   ( $2A )   mov     eax dword { $-36 }                \ 8B05CAFFFFFF   
   ( $30 )   dec     eax                               \ 48   
   ( $31 )   mov     eax dword { $-6A }                \ 8B0596FFFFFF   
   ( $37 )   dec     eax                               \ 48   
   ( $38 )   movzx   eax word { $-72 }                 \ 0FB7058EFFFFFF   
   ( $3F )   dec     eax                               \ 48   
   ( $40 )   mov     eax dword { $0 }                  \ A100000000   
   ( $45 )   or      al byte { eax }                   \ 0A00   
   ( $47 )   add     byte { eax } al                   \ 0000   
   ( $49 )   ret                                       \ C3 ( end )   
      
   It's still possible to write INC reg in 64 bit mode, and this is also   
   exactly the same code in 32 bit mode, becase theres a 2 byte form of the   
   $4x opcodes;   
      
   ( $0 )    inc     al                                \ FEC0   
   ( $2 )    inc     ah                                \ FEC4   
   ( $4 )    inc     ax                                \ 66FFC0   
   ( $7 )    inc     eax                               \ FFC0   
   ( $9 )    ret                                       \ C3 ( end )   
      
      
   --   
   Alex   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca