Как этот asm для функции stdcall очищает аргументы из стека?

У меня простой код. StdCall - это __stdcall, а CdeclCall - это __cdecl.

#include <stdio.h>

int __stdcall StdCall(int a,int b)
{
    return a + b;
}
 
int __cdecl CdeclCall(int a,int b)
{
    return a + b;
}

int main(int argc, char **argv) {

    StdCall(10,20);
    CdeclCall(10,20);
    printf("Done");
    return 0;

}

Часть разборки main () для StdCall (Main не очищает стек для StdCall)

push    20                  ; 00000014H
push    10                  ; 0000000aH
call    ?StdCall@@YGHHH@Z           ; StdCall

Часть разборки main () для CdeclCall (Main очищает стек для CdeclCall)

push    20                  ; 00000014H
push    10                  ; 0000000aH
call    ?CdeclCall@@YAHHH@Z         ; CdeclCall
add esp, 8   ; Stack cleared here

Теперь StdCall несет ответственность за удаление своих аргументов из стека, но дизассемблирование не показывает никакого кода, который выдвигает флажки для очистки / очистки стека.

Разборка для StdCall

    push    ebp
    mov ebp, esp
    sub esp, 192                ; 000000c0H
    push    ebx
    push    esi
    push    edi
    lea edi, DWORD PTR [ebp-192]
    mov ecx, 48                 ; 00000030H
    mov eax, -858993460             ; ccccccccH
    rep stosd

    mov eax, DWORD PTR _a$[ebp]
    add eax, DWORD PTR _b$[ebp]

    pop edi
    pop esi
    pop ebx
    mov esp, ebp
    pop ebp
    ret 8

Генерация кода стека очистки для __stdcall во время выполнения или я неправильно понял концепцию?


person Pranit Kothari    schedule 05.04.2014    source источник
comment
Старым термином для вызываемого, восстанавливающего указатель стека, было соглашение о вызове pacscal, но в вашем случае теперь это __stdcall.   -  person rcgldr    schedule 05.04.2014


Ответы (1)


Это часть инструкции ret 8 - 8 - это количество байтов, которое нужно добавить к указателю стека после извлечения адреса возврата.

https://www.felixcloutier.com/x86/ret

См. Также В чем смысл и использование __stdcall? для получения дополнительной информации о @ украшениях имен функций C в Windows.

person Mark Ransom    schedule 05.04.2014
comment
Хотел уточнить для меня, возвращаемое значение сохраняется в регистре. ret инструкция просто передаст управление. Это правильно? - person Pranit Kothari; 05.04.2014
comment
@pranitkothari да, верно. Возвращаемое значение уже находится в eax. - person Mark Ransom; 05.04.2014
comment
(отредактировал вопрос и ответ, чтобы лучше дублировать программу MessageBox в сборке x86). PS, Марк, ты можешь @ ответить кому-то, кто редактировал пост, даже если он не прокомментировал. Согласен, было бы неплохо, если бы существовал механизм PM, кроме выяснения того, как пригласить кого-то в чат, что, я думаю, могло бы быть возможно без публикации комментариев где-либо, но вам нужно будет создать чат-комнату, чтобы я не беспокоился . - person Peter Cordes; 23.02.2021
comment
@PeterCordes еще раз спасибо. Думаю, я был сбит с толку, поскольку @ не предлагал опцию автозаполнения, как обычно. - person Mark Ransom; 23.02.2021
comment
О да, это так странно. По какой-то причине автозаполнение не работает для людей, которые только редактировали, а не комментировали. Думаю, это просто фактор работы на стороне клиента. - person Peter Cordes; 23.02.2021