Я разобрал два разных варианта функции Swap (простой обмен значениями между двумя указателями).
1). __fastcall http://pastebin.com/ux5LMktz
2). __stdcall (функция без явного модификатора соглашения о вызовах будет иметь __stdcall по умолчанию из-за компилятора MS C ++ для Windows) http://pastebin.com/eGR6VUjX
Как я знаю, __fastcall реализован по-разному, в зависимости от компилятора, но в основном он помещает первые два аргумента (слева направо) в регистр ECX и EDX. И может быть использование стека, но если аргументы слишком длинные.
Но что касается ссылки на 1-й вариант, вы можете видеть, что это значение помещается в реестр ECX, и между двумя вариантами функции подкачки нет реальной разницы.
И вариант __fastcall использует:
00AA261F pop ecx
00AA2620 mov dword ptr [ebp-14h],edx
00AA2623 mov dword ptr [ebp-8],ecx
Которые не используются в версии __stdcall.
Так что это не выглядит более оптимизированным (как, по определению, __fasctcall).
Я новичок в языке ASM и соглашении о вызовах, поэтому прошу у вас совета. Может быть, __fastcall быстрее в моем примере, но я не вижу этого, не так ли?
Спасибо!
Попробуйте включить оптимизацию, а затем сравнить результаты. Ваш fastcall
версия имеет много избыточных операций, потому что она не оптимизирована.
Вот выход VS 2010 с /Ox
,
fastcall
:
; _firstValue$ = ecx
; _secondValue$ = edx
?CallMe1@@YIXPAH0@Z PROC ; CallMe1
mov eax, DWORD PTR [ecx]
push esi
mov esi, DWORD PTR [edx]
cmp eax, esi
je SHORT $LN1@CallMe1
mov DWORD PTR [ecx], esi
mov DWORD PTR [edx], eax
$LN1@CallMe1:
pop esi
ret 0
?CallMe1@@YIXPAH0@Z ENDP ; CallMe1
stdcall
:
_firstValue$ = 8 ; size = 4
_secondValue$ = 12 ; size = 4
?CallMe2@@YGXPAH0@Z PROC ; CallMe2
mov edx, DWORD PTR _firstValue$[esp-4]
mov eax, DWORD PTR [edx]
push esi
mov esi, DWORD PTR _secondValue$[esp]
mov ecx, DWORD PTR [esi]
cmp eax, ecx
je SHORT $LN1@CallMe2
mov DWORD PTR [edx], ecx
mov DWORD PTR [esi], eax
$LN1@CallMe2:
pop esi
ret 8
?CallMe2@@YGXPAH0@Z ENDP ; CallMe2
cdecl
(что вы по ошибке называете stdcall
в вашем примере):
_firstValue$ = 8 ; size = 4
_secondValue$ = 12 ; size = 4
?CallMe3@@YAXPAH0@Z PROC ; CallMe3
mov edx, DWORD PTR _firstValue$[esp-4]
mov eax, DWORD PTR [edx]
push esi
mov esi, DWORD PTR _secondValue$[esp]
mov ecx, DWORD PTR [esi]
cmp eax, ecx
je SHORT $LN1@CallMe3
mov DWORD PTR [edx], ecx
mov DWORD PTR [esi], eax
$LN1@CallMe3:
pop esi
ret 0
?CallMe3@@YAXPAH0@Z ENDP ; CallMe3
Других решений пока нет …