Здравствуйте. Сто лет не писал на fasm и забыл как входить в процедуру. Помогите пожалуйста. Я помню что если сразу входить в процедуру в начале программы то ненужно выравнивать стек "sub rsp,8" Спасибо, разобрался с Божей помощью Код (Text): format PE64 GUI 5.0 entry start include 'win64a.inc' section '.code' code readable executable proc start ret endp invoke ExitProcess,rax section '.idata' import data readable writeable library kernel,'KERNEL32.DLL' import kernel,\ ExitProcess,'ExitProcess'
Вообще, ничего не понял, что Вам надо, но наверное это: Код (ASM): include 'win64W.inc' format PE64 GUI 5.0 entry start section '.text' code readable executable start: sub rsp,8 ; Выравнивание стека на dqword call start2 invoke ExitProcess, 0 proc start2 ret endp ;section '.data' data readable writeable section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' include 'api\kernel32.inc' include 'api\user32.inc'
У меня такой вопрос: почему программа ексемпл запускается в безопастном режиме в COMODO FIREWALL, я понимаю что программа редкая но всё же хостинг фото
Мне интересно почему фаерволл запускает ее в безопастном режиме, ну ладно... Вот еще вопрос почему антивирусы, каторый я и в глаза не видел, определяют ее как заразу фотохостинг бесплатно
Мб, потому что в импорте нет "опасных" функций? Ложные срабатывания, это норма. Лечиться подписью сертификатом
Это не выравнивание, это просто "rsp-8". Выравнивание вот: Код (ASM): and rsp, -8 А вообще правильный вход в процедуру зависит от ОС, ее разрядности и соглашения, принятого в процедуре. Посмотрите исходник макроса "invoke".
Категорически не согласен! Если сделать and rsp, -8 то программа упадёт на x64. Т.к применяя and вы убиваете указатель на стек в rsp. ТС приложил исходник в первом сообщение, смотрим его и путём не сложных умственных заключений приходим к выводу, что его интересует только ОС Windows, архитектура x64 =)
Вообще, 8 надо отнять из RSP только потому что макросы Fasm (вроде как invoke) не резервируют достаточное количество байт перед вызовом функции. Win64 ABI требует, чтобы стековый кадр был выравнен на 16 байт. Таким образом если не сделать sub rsp,8, то стек не будет иметь 16 байтовую кратность с учётом адреса возврата вызываемой функции.
Atari, Код (ASM): ; Example of 64-bit PE program format PE64 GUI include 'win64ax.inc' .code start: ; Make stack dqword aligned frame invoke MessageBoxA,0,_message,_caption,MB_OK invoke ExitProcess,0 endf section '.data' data readable writeable _caption db 'Win64 assembly program',0 _message db 'Hello World!',0 .end start макрос .code/.end value подставит в текст sub rsp,8
wat? А сделав sub - не убиваете, да? И кто вам мешает rsp сначала сохранить, а когда надо - восстановить? Invoke fasm для win64 отлично резервирует место, ибо это входит в Win64 calling convention. Тогда надо делать and rsp, -16; причем в самом начале вашей функции, ибо никто не гарантирует, что стек у вас будет при вызове выровнен. Иначе придется скурпулезно считать каждый push и pop, особенно с учетом любых переходов - чтобы не дай бог не сбиться с границы - что все равно рано или поздно произойдет. Я когда-то писал функцию универсального вызова внешних процедур для С, и выглядела она как то так: Код (C): asm("call:", "pushq %rbp", "movq %rsp, %rbp", "andl $-16, %esp", // alignment "andq $1, %rdx", // arguments count "leaq -16(%rsp,%rdx,8), %rsp", "pushq (%r10)", ..., "pushq (%r10)", // all arguments ....... "subq $32, %rsp", // extra space "call *%rax", "leave", "ret", Прошу заметить, что перед вызовом винда требует еще и 32 байтика в резерв.
Пардон, мой косяк. Действительно and rsp, -8, делает выравнивание стека без потери адреса. Вы были таки правы, я поспешил с выводами, когда увидел опкод and, а дальнейшие мои мысли были построены на ложном умозаключение... Эм, шутки шутками, но... Опытным путём было выяснено, что перед вызовом функции стек должен быть выравнен на 8 байтовую границу, а после на 16-байтовую. Не надо выравнивать стек перед каждым вызовом функции, достаточно на точке входа сделать sub rsp, 8. Выравнивание на 8 байтовую границу останется, а после вызова call xxxx, будет размещён в стеке адрес возврата и выравнивание стека будет кратно 16, что нам и надо. Открываем PROC64.INC и видим: Код (ASM): macro invoke proc,[arg] { common fastcall [proc],arg } macro fastcall proc,[arg] { common local stackspace,argscount,counter ; Вот тут самое интересное if argscount < 4 stackspace = 4*8 else if argscount and 1 stackspace = (argscount+1)*8 else stackspace = argscount*8 end if На сколько я понимаю, если аргументов функции меньше чем 4, то резервируем на стеке 32 байта, если хотя бы 4 и аргументов чётное количество, то резервируем КоличествоАргументов * 8, при не чётном количестве аргументов, считаем, как (КоличествоАргументов + 1) * 8. Т.е. всё замечательно, аргументы в стеке лежат с выравниванием кратным 16, пока инструкция call не положит в стек адрес возврата... Итого в самом простом случае, получается, что макрос fastcall (invoke) резервирует 32 байта + 8 байт на адрес возврата = 40 байт и чтобы их выровнять, нам надо добавить 8 (отнять от rsp 8). Я уже не знаю как проще объяснить =(
там еще чуднее, для функций с аргументами <= 4 макрос invoke будет обрамлять каждую функцию sub rsp,20h add rsp,20h то есть Код (Text): sub rsp,20h invoke MessageBoxA,0,_message,_caption,MB_OK add rsp,20h sub rsp,20h invoke ExitProcess,0 add rsp,20h если использовать frame/endf как у меня выше, тогда получим Код (Text): sub rsp,20h invoke MessageBoxA,0,_message,_caption,MB_OK invoke ExitProcess,0 add rsp,20h при обрамлении функций с разным числом параметров frame/endf вычислит функцию с наибольшим количеством параметров Код (Text): sub rsp,MAX*8 invoke f1 invoke f2 .... invoke fN add rsp,MAX*8
Теоретически да, но, например, для MessageBox или RegisterClass резервирование не требуется, достаточно при входе в процедуру поставить push reg64 или enter 0,0 вместо sub rsp,8 Глава вторая. Как Братец Кролик уменьшал размер программы
конечно разные, я пишу через invoke и макрос сам всё раскладывает по регистрам, а вы через call и mov и lea пишете самостоятельно. это "так себе" аргумент, а вот без sub rsp,32 MessageBox работает нормально...
Да, правда ваша - я невнимательно вас прочитал. Уже удалил. Ну я на эти грабли уже наступал. Ничего не имею против, чтобы и вы потоптались )