void AES::AsmEncrypt(const byte* inBlock, byte* outBlock, void* boxes) const
{

    PROLOG()

    #ifdef OLD_GCC_OFFSET
        AS2(    mov   edx, DWORD PTR [ecx + 60]     )   // rounds
        AS2(    lea   edi, [ecx + 64]               )   // rk
    #else
        AS2(    mov   edx, DWORD PTR [ecx + 56]     )   // rounds
        AS2(    lea   edi, [ecx + 60]               )   // rk
    #endif

    AS1(    dec   edx                           )
    AS2(    movd  mm6, edi                      )   // save rk
    AS2(    movd  mm5, edx                      )   // save rounds
  
    AS2(    mov   eax, DWORD PTR [esi]                                  )
    AS2(    mov   ebx, DWORD PTR [esi + 4]                              )
    AS2(    mov   ecx, DWORD PTR [esi + 8]                              )
    AS2(    mov   edx, DWORD PTR [esi + 12]                             )

    AS1(    bswap eax                                                   )
    AS1(    bswap ebx                                                   )
    AS1(    bswap ecx                                                   )
    AS1(    bswap edx                                                   )

    AS2(    xor   eax, DWORD PTR [edi]               )   // s0
    AS2(    xor   ebx, DWORD PTR [edi +  4]          )   // s1
    AS2(    xor   ecx, DWORD PTR [edi +  8]          )   // s2
    AS2(    xor   edx, DWORD PTR [edi + 12]          )   // s3

#ifdef _MSC_VER
    AS1( loop1: )  // loop1
#else
    AS1(1:  )      // loop1
#endif
            /* Put0 (mm0) =  
                Te0[get0,rs 24] ^
                Te1[get1,rs 16] ^
                Te2[get2,rs  8] ^
                Te3[get3,rs  0]
            */
       
    AS2(    mov   esi, eax                                              )
    AS2(    shr   esi, 24                                               )
    AS2(    mov   esi, DWORD PTR [ebp + esi*4]                          )
                                                    
    AS2(    mov   edi, ebx                                              )
    AS2(    shr   edi, 16                                               )
    AS2(    and   edi, 255                                              )
    AS2(    xor   esi, DWORD PTR [ebp + 1024 + edi*4]                   )

    AS2(    movzx edi, ch                                               )
    AS2(    xor   esi, DWORD PTR [ebp + 2048 + edi*4]                   )

    AS2(    movzx edi, dl                                               )
    AS2(    xor   esi, DWORD PTR [ebp + 3072 + edi*4]                   )

    AS2(    movd  mm0, esi                                              )

             /* Put1 (mm1) =  
                Te0[get1,rs 24] ^
                Te1[get2,rs 16] ^
                Te2[get3,rs  8] ^
                Te3[get0,rs  0]
            */

    AS2(    mov   esi, ebx                                              )
    AS2(    shr   esi, 24                                               )
    AS2(    mov   esi, DWORD PTR [ebp + esi*4]                          )

    AS2(    mov   edi, ecx                                              )
    AS2(    shr   edi, 16                                               )
    AS2(    and   edi, 255                                              )
    AS2(    xor   esi, DWORD PTR [ebp + 1024 + edi*4]                   )

    AS2(    movzx edi, dh                                               )
    AS2(    xor   esi, DWORD PTR [ebp + 2048 + edi*4]                   )

    AS2(    movzx edi, al                                               )
    AS2(    xor   esi, DWORD PTR [ebp + 3072 + edi*4]                   )

    AS2(    movd  mm1, esi                                              )


             /* Put2 (mm2) =  
                Te0[get2,rs 24] ^
                Te1[get3,rs 16] ^
                Te2[get0,rs  8] ^
                Te3[get1,rs  0] 
            */

    AS2(    mov   esi, ecx                                              )
    AS2(    shr   esi, 24                                               )
    AS2(    mov   esi, DWORD PTR [ebp + esi*4]                          )

    AS2(    mov   edi, edx                                              )
    AS2(    shr   edi, 16                                               )
    AS2(    and   edi, 255                                              )
    AS2(    xor   esi, DWORD PTR [ebp + 1024 + edi*4]                   )

    AS2(    movzx edi, ah                                               )
    AS2(    xor   esi, DWORD PTR [ebp + 2048 + edi*4]                   )

    AS2(    movzx edi, bl                                               )
    AS2(    xor   esi, DWORD PTR [ebp + 3072 + edi*4]                   )

    AS2(    movd  mm2, esi                                              )

             /* Put3 (edx) =  
                Te0[get3,rs 24] ^
                Te1[get0,rs 16] ^
                Te2[get1,rs  8] ^
                Te3[get2,rs  0] 
            */

    AS2(    mov   esi, edx                                              )
    AS2(    shr   esi, 24                                               )
    AS2(    mov   edx, DWORD PTR [ebp + esi*4]                          )

    AS2(    mov   edi, eax                                              )
    AS2(    shr   edi, 16                                               )
    AS2(    and   edi, 255                                              )
    AS2(    xor   edx, DWORD PTR [ebp + 1024 + edi*4]                   )

    AS2(    movzx esi, bh                                               )
    AS2(    xor   edx, DWORD PTR [ebp + 2048 + esi*4]                   )

    AS2(    movzx edi, cl                                               )
    AS2(    xor   edx, DWORD PTR [ebp + 3072 + edi*4]                   )

            // xOr

    AS2(    movd   esi, mm6                      )   //  rk

    AS2(    movd   eax, mm0                                             )
    AS2(    add    esi, 16                                              )
    AS2(    movd   ebx, mm1                                             )
    AS2(    movd   mm6, esi                      )   //  save back
    AS2(    movd   ecx, mm2                                             )

    AS2(    xor   eax, DWORD PTR [esi]                                  )
    AS2(    xor   ebx, DWORD PTR [esi +  4]                             )
    AS2(    movd  edi, mm5                                              )
    AS2(    xor   ecx, DWORD PTR [esi +  8]                             )
    AS2(    xor   edx, DWORD PTR [esi + 12]                             )

    AS1(    dec   edi                                                   )
    AS2(    movd  mm5, edi                                              )

#ifdef _MSC_VER
    AS1(    jnz   loop1)  // loop1
#else
    AS1(    jnz   1b )    // loop1
#endif

            // last round
            /*
            Put0 (mm0) =
                (Te4[get0, rs24] & 0xff000000) ^  h = 4278190080
                (Te4[get1, rs16] & 0x00ff0000) ^  h =   16711680
                (Te4[get2, rs 8] & 0x0000ff00) ^  h =      65280
                (Te4[get3, rs 0] & 0x000000ff)    h =        255
            */
    AS2(    mov   esi, eax                                              )
    AS2(    shr   esi, 24                                               )
    AS2(    mov   esi, DWORD PTR [ebp + 4096 + esi*4]                   )
    AS2(    and   esi, 4278190080                                       )

    AS2(    mov   edi, ebx                                              )
    AS2(    shr   edi, 16                                               )
    AS2(    and   edi, 255                                              )
    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   edi, 16711680                                         )
    AS2(    xor   esi, edi                                              )

    AS2(    movzx edi, ch                                               )
    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   edi, 65280                                            )
    AS2(    xor   esi, edi                                              )

    AS2(    movzx edi, dl                                               )
    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   edi, 255                                              )
    AS2(    xor   esi, edi                                              )

    AS2(    movd  mm0, esi                                              )

            /*
            Put1 (mm1) =
                (Te4[get1, rs24] & 0xff000000) ^  h = 4278190080
                (Te4[get2, rs16] & 0x00ff0000) ^  h =   16711680
                (Te4[get3, rs 8] & 0x0000ff00) ^  h =      65280
                (Te4[get0, rs 0] & 0x000000ff)    h =        255
            */
    AS2(    mov   esi, ebx                                              )
    AS2(    shr   esi, 24                                               )
    AS2(    mov   esi, DWORD PTR [ebp + 4096 + esi*4]                   )
    AS2(    and   esi, 4278190080                                       )

    AS2(    mov   edi, ecx                                              )
    AS2(    shr   edi, 16                                               )
    AS2(    and   edi, 255                                              )
    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   edi, 16711680                                         )
    AS2(    xor   esi, edi                                              )

    AS2(    movzx edi, dh                                               )
    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   edi, 65280                                            )
    AS2(    xor   esi, edi                                              )

    AS2(    movzx edi, al                                               )
    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   edi, 255                                              )
    AS2(    xor   esi, edi                                              )

    AS2(    movd  mm1, esi                                              )

            /*
            Put2 (mm2) =
                (Te4[get2, rs24] & 0xff000000) ^  h = 4278190080
                (Te4[get3, rs16] & 0x00ff0000) ^  h =   16711680
                (Te4[get0, rs 8] & 0x0000ff00) ^  h =      65280
                (Te4[get1, rs 0] & 0x000000ff)    h =        255
            */
    AS2(    mov   esi, ecx                                              )
    AS2(    shr   esi, 24                                               )
    AS2(    mov   esi, DWORD PTR [ebp + 4096 + esi*4]                   )
    AS2(    and   esi, 4278190080                                       )

    AS2(    mov   edi, edx                                              )
    AS2(    shr   edi, 16                                               )
    AS2(    and   edi, 255                                              )
    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   edi, 16711680                                         )
    AS2(    xor   esi, edi                                              )

    AS2(    movzx edi, ah                                               )
    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   edi, 65280                                            )
    AS2(    xor   esi, edi                                              )

    AS2(    movzx edi, bl                                               )
    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   edi, 255                                              )
    AS2(    xor   esi, edi                                              )

    AS2(    movd  mm2, esi                                              )

            /*
            Put3 (edx) =
                (Te4[get3, rs24] & 0xff000000) ^  h = 4278190080
                (Te4[get0, rs16] & 0x00ff0000) ^  h =   16711680
                (Te4[get1, rs 8] & 0x0000ff00) ^  h =      65280
                (Te4[get2, rs 0] & 0x000000ff)    h =        255
            */
    AS2(    mov   esi, edx                                              )
    AS2(    shr   esi, 24                                               )
    AS2(    mov   edx, DWORD PTR [ebp + 4096 + esi*4]                   )
    AS2(    and   edx, 4278190080                                       )

    AS2(    mov   edi, eax                                              )
    AS2(    shr   edi, 16                                               )
    AS2(    and   edi, 255                                              )
    AS2(    mov   esi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   esi, 16711680                                         )
    AS2(    xor   edx, esi                                              )

    AS2(    movzx esi, bh                                               )
    AS2(    mov   edi, DWORD PTR [ebp + 4096 + esi*4]                   )
    AS2(    and   edi, 65280                                            )
    AS2(    xor   edx, edi                                              )

    AS2(    movzx edi, cl                                               )
    AS2(    mov   esi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   esi, 255                                              )
    AS2(    xor   edx, esi                                              )

    
            // xOr
    AS2(    movd   eax, mm0                                             )
    AS2(    movd   esi, mm6                      )   //  rk
    AS2(    movd   ebx, mm1                                             )
    AS2(    add    esi, 16                                               )
    AS2(    movd   ecx, mm2                                             )

    AS2(    xor   eax, DWORD PTR [esi]                                  )
    AS2(    xor   ebx, DWORD PTR [esi +  4]                             )
    AS2(    xor   ecx, DWORD PTR [esi +  8]                             )
    AS2(    xor   edx, DWORD PTR [esi + 12]                             )

    // end
    AS2(    movd  ebp, mm7                                              )

            // swap
    AS1(    bswap eax                                                   )
    AS1(    bswap ebx                                                   )

            // store
    #ifdef __GNUC__
        AS2(    movd esi, mm4                       )   //  outBlock
    #else
        AS2(    mov  esi, DWORD PTR [ebp + 12]      )   //  outBlock
    #endif

    AS1(    bswap ecx                                                   )
    AS1(    bswap edx                                                   )

    AS2(    mov DWORD PTR [esi],      eax                               )
    AS2(    mov DWORD PTR [esi +  4], ebx                               )
    AS2(    mov DWORD PTR [esi +  8], ecx                               )
    AS2(    mov DWORD PTR [esi + 12], edx                               )


    EPILOG()
}
void AES::AsmEncrypt(const byte* inBlock, byte* outBlock, void* boxes) const
{

    PROLOG()

    #ifdef OLD_GCC_OFFSET
        AS2(    mov   edx, DWORD PTR [ecx + 60]     )    
        AS2(    lea   edi, [ecx + 64]               )    
    #else
        AS2(    mov   edx, DWORD PTR [ecx + 56]     )    
        AS2(    lea   edi, [ecx + 60]               )    
    #endif

    AS1(    dec   edx                           )
    AS2(    movd  mm6, edi                      )    
    AS2(    movd  mm5, edx                      )    
  
    AS2(    mov   eax, DWORD PTR [esi]                                  )
    AS2(    mov   ebx, DWORD PTR [esi + 4]                              )
    AS2(    mov   ecx, DWORD PTR [esi + 8]                              )
    AS2(    mov   edx, DWORD PTR [esi + 12]                             )

    AS1(    bswap eax                                                   )
    AS1(    bswap ebx                                                   )
    AS1(    bswap ecx                                                   )
    AS1(    bswap edx                                                   )

    AS2(    xor   eax, DWORD PTR [edi]               )    
    AS2(    xor   ebx, DWORD PTR [edi +  4]          )    
    AS2(    xor   ecx, DWORD PTR [edi +  8]          )    
    AS2(    xor   edx, DWORD PTR [edi + 12]          )    

#ifdef _MSC_VER
    AS1( loop1: )   
#else
    AS1(1:  )       
#endif
             
       
    AS2(    mov   esi, eax                                              )
    AS2(    shr   esi, 24                                               )
    AS2(    mov   esi, DWORD PTR [ebp + esi*4]                          )
                                                    
    AS2(    mov   edi, ebx                                              )
    AS2(    shr   edi, 16                                               )
    AS2(    and   edi, 255                                              )
    AS2(    xor   esi, DWORD PTR [ebp + 1024 + edi*4]                   )

    AS2(    movzx edi, ch                                               )
    AS2(    xor   esi, DWORD PTR [ebp + 2048 + edi*4]                   )

    AS2(    movzx edi, dl                                               )
    AS2(    xor   esi, DWORD PTR [ebp + 3072 + edi*4]                   )

    AS2(    movd  mm0, esi                                              )

              

    AS2(    mov   esi, ebx                                              )
    AS2(    shr   esi, 24                                               )
    AS2(    mov   esi, DWORD PTR [ebp + esi*4]                          )

    AS2(    mov   edi, ecx                                              )
    AS2(    shr   edi, 16                                               )
    AS2(    and   edi, 255                                              )
    AS2(    xor   esi, DWORD PTR [ebp + 1024 + edi*4]                   )

    AS2(    movzx edi, dh                                               )
    AS2(    xor   esi, DWORD PTR [ebp + 2048 + edi*4]                   )

    AS2(    movzx edi, al                                               )
    AS2(    xor   esi, DWORD PTR [ebp + 3072 + edi*4]                   )

    AS2(    movd  mm1, esi                                              )


              

    AS2(    mov   esi, ecx                                              )
    AS2(    shr   esi, 24                                               )
    AS2(    mov   esi, DWORD PTR [ebp + esi*4]                          )

    AS2(    mov   edi, edx                                              )
    AS2(    shr   edi, 16                                               )
    AS2(    and   edi, 255                                              )
    AS2(    xor   esi, DWORD PTR [ebp + 1024 + edi*4]                   )

    AS2(    movzx edi, ah                                               )
    AS2(    xor   esi, DWORD PTR [ebp + 2048 + edi*4]                   )

    AS2(    movzx edi, bl                                               )
    AS2(    xor   esi, DWORD PTR [ebp + 3072 + edi*4]                   )

    AS2(    movd  mm2, esi                                              )

              

    AS2(    mov   esi, edx                                              )
    AS2(    shr   esi, 24                                               )
    AS2(    mov   edx, DWORD PTR [ebp + esi*4]                          )

    AS2(    mov   edi, eax                                              )
    AS2(    shr   edi, 16                                               )
    AS2(    and   edi, 255                                              )
    AS2(    xor   edx, DWORD PTR [ebp + 1024 + edi*4]                   )

    AS2(    movzx esi, bh                                               )
    AS2(    xor   edx, DWORD PTR [ebp + 2048 + esi*4]                   )

    AS2(    movzx edi, cl                                               )
    AS2(    xor   edx, DWORD PTR [ebp + 3072 + edi*4]                   )

             

    AS2(    movd   esi, mm6                      )    

    AS2(    movd   eax, mm0                                             )
    AS2(    add    esi, 16                                              )
    AS2(    movd   ebx, mm1                                             )
    AS2(    movd   mm6, esi                      )    
    AS2(    movd   ecx, mm2                                             )

    AS2(    xor   eax, DWORD PTR [esi]                                  )
    AS2(    xor   ebx, DWORD PTR [esi +  4]                             )
    AS2(    movd  edi, mm5                                              )
    AS2(    xor   ecx, DWORD PTR [esi +  8]                             )
    AS2(    xor   edx, DWORD PTR [esi + 12]                             )

    AS1(    dec   edi                                                   )
    AS2(    movd  mm5, edi                                              )

#ifdef _MSC_VER
    AS1(    jnz   loop1)   
#else
    AS1(    jnz   1b )     
#endif

             
             
    AS2(    mov   esi, eax                                              )
    AS2(    shr   esi, 24                                               )
    AS2(    mov   esi, DWORD PTR [ebp + 4096 + esi*4]                   )
    AS2(    and   esi, 4278190080                                       )

    AS2(    mov   edi, ebx                                              )
    AS2(    shr   edi, 16                                               )
    AS2(    and   edi, 255                                              )
    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   edi, 16711680                                         )
    AS2(    xor   esi, edi                                              )

    AS2(    movzx edi, ch                                               )
    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   edi, 65280                                            )
    AS2(    xor   esi, edi                                              )

    AS2(    movzx edi, dl                                               )
    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   edi, 255                                              )
    AS2(    xor   esi, edi                                              )

    AS2(    movd  mm0, esi                                              )

             
    AS2(    mov   esi, ebx                                              )
    AS2(    shr   esi, 24                                               )
    AS2(    mov   esi, DWORD PTR [ebp + 4096 + esi*4]                   )
    AS2(    and   esi, 4278190080                                       )

    AS2(    mov   edi, ecx                                              )
    AS2(    shr   edi, 16                                               )
    AS2(    and   edi, 255                                              )
    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   edi, 16711680                                         )
    AS2(    xor   esi, edi                                              )

    AS2(    movzx edi, dh                                               )
    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   edi, 65280                                            )
    AS2(    xor   esi, edi                                              )

    AS2(    movzx edi, al                                               )
    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   edi, 255                                              )
    AS2(    xor   esi, edi                                              )

    AS2(    movd  mm1, esi                                              )

             
    AS2(    mov   esi, ecx                                              )
    AS2(    shr   esi, 24                                               )
    AS2(    mov   esi, DWORD PTR [ebp + 4096 + esi*4]                   )
    AS2(    and   esi, 4278190080                                       )

    AS2(    mov   edi, edx                                              )
    AS2(    shr   edi, 16                                               )
    AS2(    and   edi, 255                                              )
    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   edi, 16711680                                         )
    AS2(    xor   esi, edi                                              )

    AS2(    movzx edi, ah                                               )
    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   edi, 65280                                            )
    AS2(    xor   esi, edi                                              )

    AS2(    movzx edi, bl                                               )
    AS2(    mov   edi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   edi, 255                                              )
    AS2(    xor   esi, edi                                              )

    AS2(    movd  mm2, esi                                              )

             
    AS2(    mov   esi, edx                                              )
    AS2(    shr   esi, 24                                               )
    AS2(    mov   edx, DWORD PTR [ebp + 4096 + esi*4]                   )
    AS2(    and   edx, 4278190080                                       )

    AS2(    mov   edi, eax                                              )
    AS2(    shr   edi, 16                                               )
    AS2(    and   edi, 255                                              )
    AS2(    mov   esi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   esi, 16711680                                         )
    AS2(    xor   edx, esi                                              )

    AS2(    movzx esi, bh                                               )
    AS2(    mov   edi, DWORD PTR [ebp + 4096 + esi*4]                   )
    AS2(    and   edi, 65280                                            )
    AS2(    xor   edx, edi                                              )

    AS2(    movzx edi, cl                                               )
    AS2(    mov   esi, DWORD PTR [ebp + 4096 + edi*4]                   )
    AS2(    and   esi, 255                                              )
    AS2(    xor   edx, esi                                              )

    
             
    AS2(    movd   eax, mm0                                             )
    AS2(    movd   esi, mm6                      )    
    AS2(    movd   ebx, mm1                                             )
    AS2(    add    esi, 16                                               )
    AS2(    movd   ecx, mm2                                             )

    AS2(    xor   eax, DWORD PTR [esi]                                  )
    AS2(    xor   ebx, DWORD PTR [esi +  4]                             )
    AS2(    xor   ecx, DWORD PTR [esi +  8]                             )
    AS2(    xor   edx, DWORD PTR [esi + 12]                             )

     
    AS2(    movd  ebp, mm7                                              )

             
    AS1(    bswap eax                                                   )
    AS1(    bswap ebx                                                   )

             
    #ifdef __GNUC__
        AS2(    movd esi, mm4                       )    
    #else
        AS2(    mov  esi, DWORD PTR [ebp + 12]      )    
    #endif

    AS1(    bswap ecx                                                   )
    AS1(    bswap edx                                                   )

    AS2(    mov DWORD PTR [esi],      eax                               )
    AS2(    mov DWORD PTR [esi +  4], ebx                               )
    AS2(    mov DWORD PTR [esi +  8], ecx                               )
    AS2(    mov DWORD PTR [esi + 12], edx                               )


    EPILOG()
}