сборка — Почему код ассемблера __fastcall больше, чем код __stdcall в MS C ++?

Я разобрал два разных варианта функции 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 быстрее в моем примере, но я не вижу этого, не так ли?

Спасибо!

1

Решение

Попробуйте включить оптимизацию, а затем сравнить результаты. Ваш 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
1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector