|
ru.algorithms- RU.ALGORITHMS ---------------------------------------------------------------- From : Sashka Yackubtchick 2:5054/29.54 21 Dec 2001 03:28:50 To : Sergey Kabikov Subject : Гоpодская олимпиада по инфоpматике -------------------------------------------------------------------------------- 20 Dec 01 18:59, Sergey Kabikov писАл(а) к Arthur Vartanov: SK>>> ВСЕ. Более ничего позитивного в CDECL'е не имеется. AV>> Еще как имееется. cdecl, в отличие от stdcall, позволяет использовать AV>> функции с переменным числом аргументов. SK> =:-О SK> push Что_угодно SK> push Что_то_другое SK> push 2 // извещаем процедуру, что ей дали ДВА аргумента SK> call StdCallProc SK> push Что_угодно SK> push 1 // а теперь - только ОДИH SK> call StdCallProc SK> Мы ведь говорим о _соглашении_о_вызове, а не о его реализации в конкретном SK> компиляторе ? 8-) SK> Иначе это был бы оффтопик 8-))) Вышеуказанный код ничем не обнаруживает что вызвали по соглашению STDCALL Суть не в том как передаются аргументы, а 1. Является ли колличество аргументов определено (константно) 2. Кто отвечает за "очистку" стека - вызывающий код или вызываемый. В stdcall колличество аргументов определено и очистку стека выполняет вызываемая процедура. Hапример так ret 16 где 16 аргумент = колличеству байтов всех переданных процедуре аргументов В Си соглашениях колличество аргументов переменно и за очистку отвечает вызывающий код Hапример следующий после вызова код add esp,16 где 16 - то же самое что и в первом случае. В самой же процедуре ret без агрумента. При этом становится понятно почему код будет короче при stdcall дело в том что ret арг это мнемоника. И пишется она в процессе создания библиотеки и соответсвенно находится в секции кода. (По философии M$ эта секция не должна меняться поэтому динамическое изменение кода в runtime мы даже разбирать не будем, к тому же такой подход помимо массы других неудобств рождает еще и тормоза действительно). Значит, если колличество агрументов заранее не определено то очитка стека уже не может быть выполнена одной командой с возвратом. Поэтому на прийдётся добавить перед возвратом (если за очистку будет отвечать вызванная процедура) одну еще команду add esp,размер агрументов Помимо этого если ты передаёшь первым аргументом вообще не их размер а их колличество то команд дополнительных будет уже 2е как минимум. Так как тебе потребуется перевести из одной меры в другую кол. арг. -> байты Если все аргументы были :DWORD то например shl [ebp+4],2 ;умножим на 4е первый аргумент. add esp,[ebp+4] ;сместим указатель стека Hа самом деле это доволько тормозно поэтому наверно прийдётся сначала загрузить это в региста mov ecx,[ebp+4] shl ecx,2 add esp,ecx Итого у нас уже три дополнительных команды. Это на тот случай если ты всё еще настаиваешь что при переменном колличестве аргументов очистку стека должна выполнять вызываемая процедура. Потому как если это будет делать вызывающая нам нужно будет сделать только одну команду. Поскольку при компиляции вызывающего кода уже известно сколько аргументов передали функции это колличество будет переведено в константу компилятором и он добавит (по сишному вызову) всего лишь одну команду add esp,константа колличества байт переданных функции по сишноому Сейчас задумаемся над такой простой вещью - существует масса случаев когда можно написать полезную функцию где спокойно можно обойтись закреплённым колличеством аргументов. Вот именно это и представляют в своей основе функции Win32 API (за редким исключением вроде wsprinf). В них нет необходимости высчитывать колличество переданных аргументов - оно известно уже на стадии компиляции этой библиотеки поэтому нет никаких потребностей в командах очистки стека - она производится по аргументу команды ret. Соответственно чем больше функций в stdcall тем больше сокращается и места и времени на этих командах очистки, но одновременно с этим и действительно не могут быть переданы аргументы в произвольном колличестве, будь это не так то понадобился бы доп код для очистки стека. Вообщем я уже по второму кругу начал :) Пока! Sashka, The Svin. --- GoldED/W32 3.00.Beta1+ * Origin: Svin, Perm, Russia (2:5054/29.54) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.algorithms/33843c22a3d5.html, оценка из 5, голосов 10
|