1. Лень. 2. Да мало-ли когда он этот момент. 3. Первое что представляется. Код (Text): mov var1,rsp test rsp,0Fh jz @F sub rsp,8 @@: ;;;;;;;Вызов АПИ mov rsp,var1 Код получается хуже, чем на C. Легче постоянно его выровненным держать. Как ранее сказано не используя push/pop.
например, макросы в FASM генерируют прологи и эпилоги функций таким образом что стек получается выровненным, таким образом в функциях нет необходимости выравнивать стек. стек надо выровнять только один раз в точке входа и ещё в некоторых экзотических ситуациях
Сейчас на fasm`е пытаюсь написать одну не большую вещицу. Макросы в нем ужасные. Вот сравнил с MASM под который я свой пролог/эпилог сделал. MASM, wcreate proc <12> hwndParent:HWND LOCAL hwndNew:HWND mov hwndParent,rcx invoke CreateFile,1,2,3,4,5,6,7 invoke CreateWindowEx,1,2,3,4,5,6,7,8,9,10,11,12 mov hwndNew,rax ret wcreate endp 9Eh или 158 байт Код (Text): 0000000100401000:C8700000 enter 70h,0h 0000000100401004:48894D10 mov [rbp+10h],rcx 0000000100401008:B901000000 mov ecx,1h 000000010040100D:BA02000000 mov edx,2h 0000000100401012:41B803000000 mov r8d,3h 0000000100401018:41B904000000 mov r9d,4h 000000010040101E:48C745C007000000 mov qword ptr [rbp-40h],7h 0000000100401026:48C745B806000000 mov qword ptr [rbp-48h],6h 000000010040102E:48C745B005000000 mov qword ptr [rbp-50h],5h 0000000100401036:FF1544100000 call CreateFileA 000000010040103C:B901000000 mov ecx,1h 0000000100401041:BA02000000 mov edx,2h 0000000100401046:41B803000000 mov r8d,3h 000000010040104C:41B904000000 mov r9d,4h 0000000100401052:48C745E80C000000 mov qword ptr [rbp-18h],0Ch 000000010040105A:48C745E00B000000 mov qword ptr [rbp-20h],0Bh 0000000100401062:48C745D80A000000 mov qword ptr [rbp-28h],0Ah 000000010040106A:48C745D009000000 mov qword ptr [rbp-30h],9h 0000000100401072:48C745C808000000 mov qword ptr [rbp-38h],8h 000000010040107A:48C745C007000000 mov qword ptr [rbp-40h],7h 0000000100401082:48C745B806000000 mov qword ptr [rbp-48h],6h 000000010040108A:48C745B005000000 mov qword ptr [rbp-50h],5h 0000000100401092:FF1588100000 call CreateWindowExA 0000000100401098:488945F8 mov [rbp-8h],rax 000000010040109C:C9 leave 000000010040109D:C3 retn FASM, proc wcreate hwndParent local hwndNew:QWORD mov [hwndParent],rcx invoke CreateFile,1,2,3,4,5,6,7 invoke CreateWindowEx,1,2,3,4,5,6,7,8,9,10,11,12 mov [hwndNew],rax ret endp 0C9h или 201 байт Код (Text): 00402000:55 push rbp 00402001:4889E5 altm(1) mov rbp,rsp 00402004:4883EC10 sub rsp,10h 00402008:48894D10 mov [rbp+10h],rcx 0040200C:4883EC40 sub rsp,40h 00402010:48C7C101000000 mov rcx,1h 00402017:48C7C202000000 mov rdx,2h 0040201E:49C7C003000000 mov r8,3h 00402025:49C7C104000000 mov r9,4h 0040202C:48C744242005000000 mov qword ptr [rsp+20h],5h 00402035:48C744242806000000 mov qword ptr [rsp+28h],6h 0040203E:48C744243007000000 mov qword ptr [rsp+30h],7h 00402047:FF1593100000 call CreateFileA 0040204D:4883C440 add rsp,40h 00402051:4883EC60 sub rsp,60h 00402055:48C7C101000000 mov rcx,1h 0040205C:48C7C202000000 mov rdx,2h 00402063:49C7C003000000 mov r8,3h 0040206A:49C7C104000000 mov r9,4h 00402071:48C744242005000000 mov qword ptr [rsp+20h],5h 0040207A:48C744242806000000 mov qword ptr [rsp+28h],6h 00402083:48C744243007000000 mov qword ptr [rsp+30h],7h 0040208C:48C744243808000000 mov qword ptr [rsp+38h],8h 00402095:48C744244009000000 mov qword ptr [rsp+40h],9h 0040209E:48C74424480A000000 mov qword ptr [rsp+48h],0Ah 004020A7:48C74424500B000000 mov qword ptr [rsp+50h],0Bh 004020B0:48C74424580C000000 mov qword ptr [rsp+58h],0Ch 004020B9:FF1511110000 call CreateWindowExA 004020BF:4883C460 add rsp,60h 004020C3:488945F0 mov [rbp-10h],rax 004020C7:C9 leave 004020C8:C3 retn Только на вызове 2 функций получается 201-158=43 байта дутого кода, а свои делать будет долго.
там каждый invoke делает sub rsp и add rsp при вызове каждой функции, это действительно как-то некошерно. можно например запилить свои версии этого макроса без sub/add rsp
s_d_f Во-первых, ужаснуться можно одному только условному переходу. А во-вторых, в упор не вижу, что я невнимательно прочитал.
Пост #22 - первое что мне представляется может оказаться далеко не самым лучшим. Пост #24 - вот это настоящий ужас.
s_d_f Ага. Т.е. представляете "далеко не самое лучшее", а потом сами же из этого делаете вывод, что "код получаестя хуже, чем на C". Ну я себе сейчас такого напредставляю, что любой код окажется хуже, чем на php. Тут трудно поспорить. Ну что ж. Значит исправлять стандартные макросы придётся. Все недостатки достаточно легко исправимы. Мне недавно перед тем, как начать проект, пришлось CodeBlocks самому два дня допиливать, пока он начал нормально с cygwin gdb работать. А подправить пару макросов — это цветочки.
Предложенное мной всеравно может оказаться лучше чем подсчет количества push/pop`ов, особенно когда их очень много. И я уже признал, что это не очень удачный вариант. Удачи
s_d_f Автор fasm на сходный вопрос сегодня ответил. Оказывается, есть макрос frame. Конечно, не тотальная оптимизация, но от лишних выделений стека1 избавляет. 1 биологам читать это предложение не рекомендуется
Регистр rbp не требует SIB-байта, а rsp требует, но если в стэке резервируется более 160 байт для локальных переменных, то лучше уже использовать rsp. Кошмарный макрос получился.