PDA

Просмотр полной версии : Зачем нужно __cdecl?


Fdsiyhu
19.10.2021, 05:08
Я прочитал и понял, что это соглашение о вызовах делает так, что аргументы функции приходят в стек в обратном порядке, а целостность стека сохраняет вызывающий код. Но для чего это нужно? Кому и зачем это может понадобиться?

#Northn
19.10.2021, 09:13
Кому и зачем это может понадобиться?


Компьютеру, чтобы стек не переполнился и приложение не вылетело.

Компьютеру, чтобы понимать, откуда что брать: из ecx, edx, или из локального стека

Например, методы классов используют thiscall, в таком режиме в первый невидимый аргумент (регистр ecx) пихается указатель на наш класс.

memir
19.10.2021, 09:20
варарги

.deserve
19.10.2021, 11:55
Вот зачем - старая добрая вики (https://www.blast.hk/redirect/aHR0cHM6Ly9ydS53aWtpcGVkaWEub3JnL3dpa2kvJUQwJUExJU QwJUJFJUQwJUIzJUQwJUJCJUQwJUIwJUQxJTg4JUQwJUI1JUQw JUJEJUQwJUI4JUQwJUI1XyVEMCVCRV8lRDAlQjIlRDElOEIlRD AlQjclRDAlQkUlRDAlQjIlRDAlQjU)

Плюс, как выше написали, cdecl функция, по причине того, что стек чистит самостоятельно caller, может использовать вариадики - цппреф (https://www.blast.hk/redirect/aHR0cHM6Ly9lbi5jcHByZWZlcmVuY2UuY29tL3cvY3BwL2xhbm d1YWdlL3ZhcmlhZGljX2FyZ3VtZW50cw)



Компьютеру, чтобы стек не переполнился и приложение не вылетело.
Компьютеру, чтобы понимать, откуда что брать: из ecx, edx, или из локального стека
Например, методы классов используют thiscall, в таком режиме в первый невидимый аргумент (регистр ecx) пихается указатель на наш класс.


При чем здесь переполнение стека? Соглашение о вызовах к этому вообще ни малейшего отношения не имеет

И нету никакого локального стека, а есть область для локальных переменных в стеке (которую часто называют локал стеком, да), которая расположена в стековом фрейме функции, но аргументы, переданные функции, оттуда не берутся

"Например, методы классов используют thiscall" - а в POSIX? Правильно, __cdecl.

И аргумент вполне себе видимый

#Northn
19.10.2021, 13:53
При чем здесь переполнение стека?



C++:






void
__cdecl
a
(
int
b
,
int
c
,
int
d
,
int
e
)
{
}
int
main
(
)
{
while
(
1
)
reinterpret_cast
(
void
(
__thiscall
*
)
(
int
,
int
,
int
,
int
)
(
a
)
(
1
,
2
,
3
,
4
)
;
}




Давай.

.deserve
19.10.2021, 15:10
C++:






void
__cdecl
a
(
int
b
,
int
c
,
int
d
,
int
e
)
{
}
int
main
(
)
{
while
(
1
)
reinterpret_cast
(
void
(
__thiscall
*
)
(
int
,
int
,
int
,
int
)
(
a
)
(
1
,
2
,
3
,
4
)
;
}




Давай.


Ты делаешь вложенные вызовы функции, вызывающие переполнение стека. А происходит это из-за "бесконечного" добавления фрейма активации. Зачем ты сюда соглашения о вызовах приплёл одному тебе известно. (читай upd) К тому же на цланге ты варнинг получишь по вызову cdecl функции через thiscall с игнором параметров.

upd. Да, при вызове аргументы остаются не очищенным как раз благодаря вызову функции через thiscall, которая сама должна их чистить. Не видел до этого, чтобы так стек переполняли. Интересно.