Решил ткнуться в FASM (сим пытаюсь ненавязчиво намекнуть: не пинайте, пожалуйста, за глупость) и тут же коленки пооббивал. Начал с того, что написал маленькую dll-ку (предварительно почитав, разумеется, прилагающийся manual и примеры), но не суть. Среди прочего импорт оформил вот так: Код (Text): section '.idata' import data readable writeable library kernel,'KERNEL32.DLL' library user,'USER32.DLL' .............................. , а не так: Код (Text): section '.idata' import data readable writeable library kernel,'KERNEL32.DLL',\ user,'USER32.DLL' .............................. Не прошло и четырех часов тупого пяленья в три строчки кода, как я обнаружил ошибку. :-( Причем все успешно компилируется. Зато потом при попытке вызвать какую-нибудь функцию из этой dll-ки появляется огромный выбор на любой вкус из трех вариантов: отладка, отправить отчет, не отправлять отчет (ну... можно еще посмотреть этот самый отчет, что не избавляет от необходимости выбора из вышеуказанных трех вариантов). IDA, в свою очередь, показывает, что fasm накомпилировал какую-то белибердистику. Так вот, I если так делать можно, то 1) почему это нигде не описано (в manual'е все очень сжато и... и вообще мало написано)? 2) с какой целью это можно делать? II если так делать нельзя, то 1) опять таки, почему это нигде не описано? и 2) самый главный вопрос: Почему компилятор пропускает это без ошибок?
Так делать нельзя, потому что ты создаешь вторую директорию импорта, фактически, которая, есесно, не обрабатывается. Дойдя до нулевого элемента первой директории, лоадер винды решает, что это конец и пора бы запускать файл. Пропускает без ошибок, потому что это макрос, а не инструкция, и никаких проверок в нем нету. Рассчитывали, что писать будут правильно В доказательство сказанного - если аккуратно посмотреть, то вместо адреса функции в импорте будет спокойно лежать RVA имени функции, то есть вторую директорию импорта лоадер и не трогал вовсе. Кстати, скомпилировал он все правильно
Nata Дык пару часов просидел, сравнивая, чего же у меня не так как там. Но когда различий чуть больше, чем одно, то нужное различие не сразу бросается в глаза (особенно если уверен, что как раз здесь у тебя все правильно) Ну... там же, где и EntryPoint (да и вообще вся секция кода) и директива format PE GUI 4.0 DLL и т.п. : за пределами поста #1. Great Большое спасибо. Бум знать. А то я уже собрался разочаровываться в fasm'е, еще не начав с ним работать.
И еще вопрос dazu, чтобы тему новую не создавать. Точнее скорее еще одна попытка пожаловаться на документацию к fasm'у. В manual'е написано При этом совсем не написано, что если, например, переменная char db 224 объявлена локальной внутри процедуры, то компилятор на mov bx,char говорит "invalid value". И теперь надо извращаться с помощью lea bx, [char], т.е. грубо говоря: сначала разыменовываем указатель, а потом опять получаем адрес. Почему бы для локальных переменных не сделать mov bx,char тоже валидной инструкцией? To recapitulate: Например есть такой код: Код (Text): proc Msg ;locals char dw 0C089h ;endl invoke MessageBox,0,char,0,MB_ICONERROR+MB_OK ret endp Стоит мне раскомментировать locals и endl, как перед вызовом MessageBox становится необходимым добавлять лишнюю строку lea eax, [char], а вызов делать уже с параметром eax, а не char. Зачем?
потому что локальная переменная на самом деле представляет собой выражение вида EBP-CONST, т.к. располагается в кадре стека. поэтому и MOV EAX, EBP-CONST не катит (невалидная инструкция), но LEA EAX, [EBP-CONST] катит, как косвенная адресация.
Great Но раз это в документации не описано, то можно подумать, что компилятор переформирует mov eax,ebp-const в какой-нибудь Код (Text): mov eax, ebp sub eax, const ну или мало ли во что еще... главное чтобы документация соответствовала действительности.
l_inc если бы он так преобразовывал, это был бы просто ужас. пишешь одну инструкцию, а генерится совсем другая. а вдруг я рассчитывал на mov? уж лучше ничего не делать, чем делать так ) как, собственно, разработчики фасма и поступили. в любом случае в одну инструкцию запихнуть в стек разность EBP и смещения не выйдет )
l_inc Разочаровываться можно в макросах (library в данном случае), но не в бедном препроцессоре, который не виноват, что на него повесили кривой (ну, это тоже спорно...) макрос. Вообще, если бы фасм не обладал таким навороченным (по сравнению с масмом) препроцессором, проблем с макросами было бы меньше.
Asterix Ты имеешь ввиду препроцессор или ассемблер вообще? Если препроцессор, то ссылки под рукой нет? Что-то я там на форуме ничего такого не вижу. А до 2го фасма ещё дожить надо
Quantum В препроцессоре fasm нет: - макрофункций - посимвольного разбора строк (в масме он тоже не ахти реализован, но всё таки есть из-за этих "мелочей" никак не могу назвать фасмовский препроцессор более удобным чем масмовский
Этого и не будет AFAIK т.к. противоречит концепции фасма. Честно, даже и не знаю где это могло бы использоваться, match вполне хватает.
Quantum например вот такую штуку в фасме не сделаешь Код (Text): $invoke MACRO vars:VARARG invoke vars EXITM <eax> ENDM обещано вроде в 2.0, хотя может планы уже и изменились
asmfan лично мне макрофункций и возможности выдёргивать из параметра ту подстроку которую мне нужно, а не ту которую match навязывает очень сильно не хватает . Сначала думал вот с объединением данных (чтобы они с кодом не смешивались) разберусь и начну вовсю fasmом пользоваться, ан не тут то было - всё равно жутко не удобно - короче не нашёл я в нём хвалёной свободы самовыражения - масм рулёз (хотя и слегка тормоз)
Раз пошло обсуждение фасма. Там можна хоть както втолдычить ему, чтоб он выдавал сразу все ошибки а не только первую? Он может собирать дебаг версии програм?
Что-то вроде, *первую не хочу исправлять, исправлю-ка вторую*)))? Неа, помойму. А вообще катайте-ка Томазу прошения, мож в обозримом будущем появится что-то подобное...