Msvc Inline assembly inner function calls -


first i'd researched matter couldn't find relevant related it.

i writting c++ console program on msvc 2013 on release mode 32 bit. using inline assmebly in 1 of file , works great except when inline assembly function_1 calls function_2, when happens there intructions added function_2 , therefore stack gets damaged , program crashs. if stop using calls merely "lea ebx,[eip+5]", push ebx, jmp xxxxxx instead works fine.

so in case , little more concrete function 2 defined :

    void test() {  _asm{ f_01758630:  // ; <= procedure start      push ebp             mov ebp, esp             push esi             push edi             mov edi, [ebp + 0x0c]             xor esi, esi             shr edi, 0x2             test edi, edi             jle f_0175866b             push ebx             mov ebx, [ebp + 0x08]      f_01758645:          mov edx, dword ptr ds : [ebx + esi * 0x4]             rol edx, 0x10             mov ecx, edx             mov eax, edx             shr ecx, 0x8             shl eax, 0x8             xor ecx, eax             shl edx, 0x8             , ecx, 0xff00ff             xor ecx, edx             mov dword ptr ds : [ebx + esi * 0x4], ecx             inc esi             cmp esi, edi             jl tera_01758645             pop ebx          f_0175866b :          pop edi             pop esi             pop ebp             retn//; <= procedure end } } 

however when debug running program can see function implemented :

push ebx push esi push edi push ebp mov ebp,esp push esi push edi 

ie msvc implemented 3 pushs, maybe related _asm{} within function insight how can fix ?

the first

push    ebp mov     ebp, esp push    ebx push    esi push    edi 

is automatically generated prologue of function. @ end of function epilogue:

pop     ebx pop     edi pop     esi pop     ebx pop     ebp ret 

your _asm block has own prologue , epilogue, code done twice. worse, ret inside _asm block gets wrong return address , program crash. can avoid function prologue/epilogue declaring function naked:

__declspec (naked) void test() {     _asm     {         own prolog         ...         own epilog         ret     } } 

this dangerous, since can forget preserve registers returned unchanged, "callee saved registers": ebx, ebp, edi, esi. in msvc inline assembly, it's easy use function arguments , local variables, isn't necessary take control on epilog , prolog.

look @ example (as close possible code):

#include <stdio.h>  void function_2(unsigned* reg_ebx, unsigned reg_edi) {     _asm     {             mov edi, reg_edi      // take second argument             xor esi, esi             shr edi, 2             test edi, edi             jle f_0175866b             mov ebx, reg_ebx     // take first argument          f_01758645:              mov edx, dword ptr ds : [ebx + esi * 0x4]             rol edx, 16             mov ecx, edx             mov eax, edx             shr ecx, 8             shl eax, 8             xor ecx, eax             shl edx, 8             , ecx, 0xff00ff             xor ecx, edx             mov dword ptr ds : [ebx + esi * 0x4], ecx             inc esi             cmp esi, edi             jl f_01758645          f_0175866b :     } }  void function_1 () {     unsigned arr[8] = {1000,2000,3000,4000,5000,6000,7000,8000};     int i;     (i=0; < sizeof(arr)/sizeof(arr[0]); ++i) printf ("%08x ",arr[i]); puts ("");      _asm     {         push length arr         lea eax, arr         push eax         call function_2     }      (i=0; < sizeof(arr)/sizeof(arr[0]); ++i) printf ("%08x ",arr[i]); puts (""); }  int main ( void ) {     function_1();     return 0; } 

Comments

Popular posts from this blog

html - Outlook 2010 Anchor (url/address/link) -

javascript - Why does running this loop 9 times take 100x longer than running it 8 times? -

Getting gateway time-out Rails app with Nginx + Puma running on Digital Ocean -