У меня есть программа с функцией, выполненной только с встроенной сборкой.Ошибка встроенной сборки только в версии
Эта функция используется для вызова других функций, которые мы переменные аргументы (число и тип).
Вся моя программа работает очень хорошо в режиме отладки, но когда я проверить его в версии, у меня есть эта ошибка:
SomeThing.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x0A4B2FFC).
Вот моя сборка функция:
__declspec(naked) void Player_dummyFunction(dvrFunction* iFunc)
{
__asm push ebp
__asm mov ebp,esp
__asm sub esp,0C0h
__asm push ebx
__asm push esi
__asm push edi
__asm lea edi,[ebp-0C0h]
__asm mov ecx,30h
__asm mov eax,0CCCCCCCCh
__asm rep stos dword ptr es:[edi]
/* Need the number of params. */
__asm mov ecx, dword ptr [iFunc] /* Use the calling convention of VC */
__asm call dvrFunction::GetParamsNumber /* this->m_ParamsData.size() */
__asm mov edx, eax /* Save the return value */
__asm cmp edx, 0 /* Condition to know if the GL function has params (edx == 0) */
__asm jz body /* Jump to the body label if the previous condition is true */
push_loop:
/* Push the parameters in the reverse order on the stack */
__asm mov ecx, dword ptr [iFunc] /* Another use of the calling convention */
__asm push edx
__asm call dvrFunction::GetParamsAddress /* this->m_ParamsData[i]->GetAddress() */
__asm push [eax] /* Push the dereferenced address (the value) on the stack */
/* edx is automatically decremented by GetParamsAddress */
__asm cmp edx, 0 /* Is edx == 0 ? */
__asm jnz push_loop /* If no, go back push_loop label */
body:
__asm mov ecx, dword ptr [iFunc] /* Use the thiscall convention */
__asm call dvrFunction::GetCName /* Call GetCName to have a const char* */
__asm push eax /* Push the name into the stack */
__asm lea ecx, g_PlatBuiltin /* Use another convention for the structs */
__asm call [ecx]g_PlatBuiltin.wglGetProcAddress /* Call the real wglGetProcAddress to have the pointer to the GL function */
__asm mov ecx, eax /* Save the result -> TODO Is this operation needed ? */
__asm call ecx /* Call the original open GL function */
__asm pop edi
__asm pop esi
__asm pop ebx
__asm add esp,0C0h
__asm cmp ebp,esp
//__asm call __RTC_CheckEsp (0125114Fh)
__asm mov esp,ebp
__asm pop ebp
__asm ret /* Call the ret asm command */
}
Из-за оптимизации программа может не иметь указателя кадра. Могут также произойти и другие изменения в макете стека. Я предлагаю вам позволить компилятору обрабатывать стек (с аргументами и локальными переменными) и делать только самые необходимые необходимые вещи в ассемблере (если нужно вообще!).Вы действительно измерили производительность вашей функции ассемблера по сравнению с тем, что было сделано на C++? С оптимизацией и без нее? –
Я не читал код, но какой компилятор вы используете и каковы параметры оптимизации (на выходе и в режиме отладки)? – fstamour
@JoachimPileborg Спасибо, может быть, я могу позволить компилятору сделать пролог и эпилог, но другие вещи должны быть сделаны в сборке ... –