|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Май 14, 2004 10:58:46 Elohim Meth macro TByte Name, Value
{
if used Name
Name db Value
end if
}
TByte s1, 'Строка номер один'
TByte s2, 'Строка номер два'
mov eax, s1
Как ты можешь догодаться, вторая строка не будет включена в выполнимый файл, так как она не используется. Мы получили новую возможность, которая изначально в FASM'е не имелась. Это просто пример, причем как ты просил не очень сложный. Есть более интересные вещи. |
|
|
Дата: Май 14, 2004 11:50:22 JaDS Хммм... Это спорный вопрос новая ли это возможность. Она же обеспечивается не програмистом на FASM, а наличием директивы used которую написал автор FASM. Если на то пошло, то при её отсутсвии возможно ли было бы реализовать макрос,который выполнял бы действие аналогичное действию used? Вот тогда это можно было бы считать новой возможностью. Но это,повторюсь,спорный вопрос. Я не встречал насколько я помню аналогичной директивы в HLA, но по его идеологии парсера такую директиву как used Хайду будет реализовать элементарно |
|
|
Дата: Май 14, 2004 12:20:18 [ Elohim Meth : Ну простой макрос сгенерировать просто а сложный сложно :-)) Если суметь сгенерировать строку с текстом макроса то дальше никаких проблем нет. ] Т.е. сложный макрос будет состоять из одной строки? А как насчет генерации макросов с переменным количеством строк и/или параметров? Про @basereg & ?@parmoffset я почитал в доке.. По 2 строчки написано :-/ Справится ли HLA с подобным: proc fun .foo ;; local begin invoke fun2, [.foo],0 ;; в зависимости от адресации: ESP нужно корректировать, а EBP - нет ....... В том же MASM можно задать свои пролог/эпилог для подпрограмм, таким образом не ограничиваться рамками stdcall etc. В FASM само понятие "процедура" отсутствует. Все сделано наиболее естесственно для ассемблера: CALL LABEL & RET :) Коннечно, для удобства задаются макросы PROC etc, но тут ограничение только одно - способности программиста. > какие возможности определяет пользователь? Например, такие . Экзешник получен при использовании только FASM.EXE :). Посмотрите секцию импорта.. Такое вообще реально на HLA? И это только вершина айсберга. Зачам мне технологии 20ти летней давности - LIB файлы, если в FASM можно делать либы на основе только исходников, а скорость компилирования и объём ОЗУ сейчас не проблема ;) |
|
|
Дата: Май 14, 2004 13:39:33 S_T_A_S_ Вы забываете что команды в HLA можно писать через ";" #macro gen_simple @text("#macro _xor_; xor(eax,eax); xor(ebx,ebx); #endmacro") #endmacro вот первое что пришло мне в голову. Если потом вызвать макрос gen_simple, то он сгенерирует macros _xor_, который можно вызывать в любом месте программы. Устественно это простейший пример иллюстрирующий возможность. Строку можно формировать и на основе параметров макроса. Немного не понял с примером. Что есть .foo? Если локальная переменная в стеке то какого размера? в зависимости от адресации: ESP нужно корректировать, а EBP - нет Понятно, что нужно. Но нужно и спопсоб адресации указать наверно? В HLA это делается через @basereg. А вообще ответ да - справится. HLA совершенно не ограничивается stdcall для вызова процедур и тем более не ограничивается стандартным прологом и эпилогом. Для этого существуют переменные @noframe, @stackalign, @display итд. итп. И никто не мешает если хочется писать push(param) call(label) ret() Из экзешника мне вообще говоря мало что понятно. При его запуске появляются 2 окна и все. То что в FASM таблица импорта формируется руками я знаю. Хотя задач в которых это бы действительно понадобилось пока не встречал. На основе чего еще кроме исходников делаются либы в MASM или HLA? По поводу этого напишите подробнее, как это делается в FASM. |
|
|
Дата: Май 14, 2004 15:43:58 · Поправил: S_T_A_S_ [ Elohim Meth : команды в HLA можно писать через ";" ] Понятно. А можно переопроделить, например, XOR ? > Что есть .foo? Если локальная переменная в стеке то какого размера? Да, это локальная переменная. Размер (DWORD) разве важен? Важно то, что надо делать что-то вроде PUSH [ESP+XX+NN], где NN зависит от того, какой это параметр по счету у INVOKE. Это в случае с EBP, NN=0 - тут все просто. > Но нужно и спопсоб адресации указать наверно? Разве тут может быть другой способ адресации кроме косвенной через регистр.. @basereg как я понял указывает через какой регистр. существуют переменные @noframe, @stackalign, @display итд. итп Вот!! А к чему такая избыточность? Если у меня нет локадьных переменных, то очевидно, что мне не нужен "display". Код, который HLA генерирует для "display" я даже комментировать не хочу :/ ; Code begins here: L58_m1__hla_ : push ebp ;/*Dynamic link*/ push dword ptr [ebp-4] ;/*Display for lex level 0*/ lea ebp,[esp+4] ;/*Get frame ptr*/ push ebp ;/*Ptr to this proc's A.R.*/ and esp, 0fffffffch push L74_str__hla_ call STDOUT_PUTS ; puts xL58_m1__hla___hla_: mov esp, ebp pop ebp ret > Из экзешника мне вообще говоря мало что понятно. Это пример какие возможности определяет пользователь. Предположим, есть обычная программа, которая компилируется в обычный экзешник. Я делаю простое include 'myfile' - и получаю экзешник, в котором в секции импорта всего одна ф-ция. И вообще секция всего одна, а там и есть иконка с version info. И он прекрасно работает, хотя и весит немного меньше :) Запускать его не обязательно, можно просто посмотреть в PE вьювере и/или под отладчиком. Если вы не встречали, где это может понадобится - это не факт, что это не нужно, например, мне. И это - простой пример, на что неспособена HLA, хотя в ней очень много других, не нужных для меня, функций. И еще, мне больше нравится размер экзешника Icz tute2 скомпилированного FASM, чем HLA =) > На основе чего еще кроме исходников делаются либы в MASM или HLA? Возможно, меня не правильно поняли. Те либы уже сделаны, и если я хочу их подключить - без проблем, юзаю линкер. А если я хочу их изменить? Без проблем, юзаем IDA ? =) В FASM можно написать 2000+ *.asm файлов и все их подключить к проекту. А в экзешник пойдет, скажем, только 20 % кода из них. Вот у меня вопрос возник, весьма скользкий.. Существуют ли большие приложения написанные на HLA? Меня как-то смущают файлы из hlasrc.zip :( |
|
|
Дата: Май 14, 2004 16:47:27 S_T_A_S_ А можно переопроделить, например, XOR ? А зачем? xor - всем известная и понятная мнемоника процессора зачем её переопределять? Но вообще наверно нет - нельзя. В данном случае, по моему мнению, лучше написать какой-нить макрос типа _xor_ - тогда хоть путаницы не возникнет. А что в FASM можно переопределять мнемоники? В таком случае с адресацией через esp тогда да HLA пожалуй не справится. А FASM справится? А если перед вызовом функции были push, pop, изменение esp, jmp на другие куски кода итд. FASM это все учтет? если да - тогда это очень здорово,а если нет, то лично мне такая фича не нужна. я лучше сразу буду адресовать через ebp. @display не нужен даже если есть локальные переменные :-) Он нужен только если есть вложенные процедуры которым нужен доступ к локальным переменным внешней процедуры. Поэтому я просто в начале программы в одном месте пишу ?@stackalign = false; ?@display = false; и все. Если вы не встречали, где это может понадобится - это не факт, что это не нужно, например, мне. Бесспорно. хотя в ней очень много других, не нужных для меня, функций Если вы не встречали, где это может понадобится - это не факт, что это не нужно, например, мне. :-)) Извиняюсь за двойное цитирование. А чем не нравится размер в 3072 байта если в FASM немного меньше, то разве это показатель? В HLA идет встроенная поддержка исключений она скорее всего и увеличивает размер немного. Зачем юзать IDA если есть сырцы? Можно же их поправить и одним кликом пересобрать lib файл. Если не нравятся lib, то кто же мешает подключить все файлы в проект также как и в FASM? Я так и делаю когда тестирую процедуры, а потом просто включаю их в lib. Tо что все пойдет в экзешник если действовать не через lib, то это конечно плохо, но это фича не HLA а MASM насколько я понимаю и HLA винить в этом нельзя. Посмотрим что будет в HLA2. В конце концов можно же использовать HLA как парсер и FASM как компилятор :-)) Больших проектов на HLA не встречал, кроме как HLA2 который целиком пишется на HLA1, но это наверно не значит, что их нет. А чем смущают файлы hlasrc.zip? |
|
|
Дата: Май 14, 2004 18:49:43 · Поправил: S_T_A_S_ [ Elohim Meth : xor - всем известная и понятная мнемоника процессора зачем её переопределять? ] Для "перегрузки операторов" :-) Вот примитивный пример: macro push arg
{ if arg eqtype '' ;; если аргумент строка - помещаем её в тело программы, а в рунтайме ложим в стек указатель на неё
local ..continue
call ..continue
db arg,0
..continue:
else ;; иначе выполняем обычные действия.
push arg
end if }
> в FASM можно переопределять мнемоники? Совершенно верно. Также как и некоторые директивы. Причем сами макросы можно многократно переопределять, и позже восстанавливать предыдущие значения. > @display не нужен даже если есть локальные переменные :-) Разумно, но по умолчанию он зачем-то создается в примере, который я смотрел. imho логично писать в нечале не отключение ненужных фич, а включение нужных. > А чем не нравится размер в 3072 байта если в FASM немного меньше, то разве это показатель? В FASM - 1Кб, как и положено для такой программы. HLA добавляет лишний код, и еще по 8 байт к каждой строке. В данном случае - это явное излишество. Показатель? Да. Ассђмблер дает полный контроль над генерируемым кодом, компилятор - нет. > Зачем юзать IDA если есть сырцы? Можно же их поправить и одним кликом пересобрать lib файл. Ну.. это если есть сорцы.. А если есть еще и либы, то "зачэм нам 2 гэнэралных сэкрэтаря" ? > Tо что все пойдет в экзешник если действовать не через lib, то это конечно плохо, но это фича не HLA а MASM насколько я понимаю и HLA винить в этом нельзя. Ну, если это элементарно делается макросами в FASM, то в чем сложность сделать это в парсере? Просто менталитет такой - куча ключей в командной строке и т.п. > В конце концов можно же использовать HLA как парсер и FASM как компилятор :-)) Можно, но не это увеличит скорость компиляции. imho лучше написать макросы для FASM. > А чем смущают файлы hlasrc.zip? HLA написан на С :). Касательно самой модели ООП, imho она реализована лучше, чем у NaN. Хотя гибкости не хватает - резервируется ESI, другой регистр похоже нельзя использовать. |
|
|
Дата: Май 14, 2004 20:09:42 S_T_A_S_ Подобный макрос пишется элементарно только называться должен не push, а например _push_. Это может показаться недостатком конечно. Но давайте расширим этот простой пример и скажем, что если параметр является строкой и строка есть набор регистров разделенных к примеру запятой, то эти регистры положить в стек. Или еще пример: переопределить mov param1,param2 так, чтобы он генерировал push/pop если оба параметра переменные в памяти и обычный mov в противном случае. Возможно ли это реализовать в FASM? Я согласен с тем, что нужно бы сделать в HLA такой ключик, который отключал бы даже этот минимальный код обработки exception который входит в пустую программу. Впрочем он занимает всего пару сотен байт и для программы чуть более сложной чем Hello World это практически не имеет значения. По поводу строк. Никто не запрещает написать макрос который будет генерировать строки без этих 8 байт. HLA написан на С :). Да это так, потому что HLA1 это прототип и Рэндалл Хайд никогда этого не скрывал. HLA2 пишется исключительно на HLA1 и ктому же он обещает в HLA2 сделать возможность использовать для классов любой регистр, а не только esi. |
|
|
Дата: Май 14, 2004 21:01:38 · Поправил: S_T_A_S_ [ Elohim Meth : Подобный макрос пишется элементарно только называться должен не push, а например _push_ ] Дык понятно, что элементарно. Но в том-то и дело, что это уже будет новый, а не переопределенный существующий. Не вижу большого смысла руздувать существующий набор мнемоник. > если параметр является строкой и строка есть набор регистров разделенных к примеру запятой, то эти регистры положить в стек. Тут макрос совсем не нужен. Стандартно для FASM: PUSH EAX EDX ECX Если нужен именно макрос, то в прошлом примере нужно просто поставить квадратные скобочки в заголовке: macro push [arg] ;; обрабатывается список параметров разделенных запятыми. А вот интересный макрос MOV из macroses library by Ivan Poddubny: (можно и перемещение из памяти в памяти добавить, хотя imho такой подход указывает на слабость реализации)
macro mov arg1,arg2
{
if arg1 in <eax,ebx,ecx,edx,esi,edi,ebp,esp>
if arg2 eqtype 0
if arg2 = 0
xor arg1,arg1
else if arg2 = 1
xor arg1,arg1
inc arg1
else if arg2 = -1
or arg1,-1
else if arg2 > -128 & arg2 < 128 ;; надо бы писать >= для левой границы
push arg2
pop arg1
else
mov arg1,arg2
end if
else
mov arg1,arg2
end if
else
mov arg1,arg2
end if
}
А можно написать макрос, чтобы работал и такой код: mov [.WC.hCursor], invoke LoadCursor,ebx,IDC_ARROW Можно еще посмотреть статью о возможностях макросов FASM. И это далеко не предел. По поводу строк: "Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away." - Antoine de Saint Exupery |
|
|
Дата: Май 14, 2004 21:16:58 Тут макрос совсем не нужен. Стандартно для FASM: PUSH EAX EDX ECX Вы меня не правильно поняли. Я имел ввиду случай когда макросу передается именно строка "eax,ecx,edx" - один параметр, а не набор параметров. И на этапе компиляции нужно её разобрать и выдать какой то код в зависимости от содержания этой строки. Строка например формируется другим макросом который вызывает данный. Т.е. заранее не известно какие регистры будут находиться в строке. |
|
|
Дата: Май 14, 2004 21:26:10 [ Elohim Meth : А если перед вызовом функции были push, pop, изменение esp, jmp на другие куски кода итд. FASM это все учтет? ] FASM учтет ровно столько, сколько напишет программист в макросах. Для PUSH/POP - это подразумевается, иначе не будет работать тот пример с INVOKE ^^. Другие изменения ESP.. Восстановление стека вызываемой подпрограммой - обязательно. А вот ADD / SUB - я пока не делал.. Но сложного в этом ничего нет. Надо будет - добавить можно. По поводу JMP - я не знаю, как это может изменить стек. Если есить переходы на участки кода, которые меняют баланс стека - то это явный изъян в программе - она при таком подходе рухнет рано или поздно. Вообще, мне кажется странным мнение, что замена EBP на ESP может накладывать ограничения на написание прогаммы. Эти ораничения imho могут быть связаны только с некорректной работой со стеком самой программы. По крайней мере, до появления х86 никто не испытывал никаких проблем без регистра базы стекового кадра. Он был введен для упрощения работы тогдашних компиляторов, как и команда enter. Теперь мы имеем flat модель памяти и тратить целый регистр для дублирования другого - imho слишком расточительно. Это может быть оправданно только при частом вызове win api (т.к. код меньше на байт) Но, с другой стороны - появляются команды инициализации. Я проводил некоторое сравнение - реально размер кода практически одинаков (а часто даже меньше с ESP !). К тому же, многие производители С компиляторов тоже так думают. И еще. Это просто быстрее работает. |
|
|
Дата: Май 14, 2004 21:29:27 > А можно написать макрос, чтобы работал и такой код: mov[.WC.hCursor],invokeLoadCursor,ebx,IDC_ARROW А вот для masm'а это уже написано ;-) $invoke MACRO vars:VARARG
invoke vars
EXITM <eax>
ENDM
использовать так: mov hInstance, $invoke(GetModuleHandle, NULL) |
|
|
Дата: Май 14, 2004 21:37:56 [ Elohim Meth : Я имел ввиду случай когда макросу передается именно строка "eax,ecx,edx" - один параметр.. Строка например формируется другим макросом который вызывает данный ] Дык, это все пустяки :) Только будет не строка (строки в FASM - это ascii символы) а список параметров. Задается он вроде того: params fix eax, ebx... ..... params fix params, esi, edi Вызываем: push params А вот мой макрос, аргументами которого могут быть: команды INVOKE, строки (при этом дубли не помещаются в память), модификатор ADDR (т.е. как у INVOKE в MASM) ADDR equ
macro push [arg]
{ common if _#arg eq _invoke arg | _#arg eq _stdcall arg
arg
push @rv
else if _#arg in <_addr arg,_ADDR arg>
local ..opcode, ..address
virtual at 0
label ..address at arg
mov eax, dword [..address]
load ..opcode from 0
end virtual
if ..opcode = 0A1h
push arg
else
..EAX_changed = TRUE
lea EAX, [..address]
push EAX
end if
else if arg eqtype ''
local ..text
.sz ..text, <arg>
push ..text
else
if arg eq EAX & ..EAX_changed
'EAX overwritten by ADDR/LEA'
else
push arg
end if
end if } |
|
|
Дата: Май 14, 2004 21:38:48 Asterix Для FASM тоже написано ;-) И у тебя даже есть. |
|
|
Дата: Май 17, 2004 15:34:28 S_T_A_S_ Вот пример из жизни. На MASM мне такие вещи сделать не удалось, а на HLA все таки получилось. Задача: имеется три свободно изменяемых регистра eax,edx,ecx. Регистр esi указывает на структуру,а если точнее на данные объекта. В структуре объекта со смещением например 8 [esi + 8] лежит указатель на облать памяти. Нужно написать следующий макрос. macro fast_get_item (_index_(индекс),_param_(необязательный параметр в котором может лежать значение [esi + 8]) параметрами соответственно могут являться константы,переменные,регистры, ссылки на память через регистры ([eax],[eax +edx*8], и.т.д.) В итоге макрос должен сгенерировать что то вроде: mov <свободный регистр>,_index_ (Это если _index_ уже не явл. регистром) mov <след.свободный регистр>, [esi + 8] (Это если не задан второй параметр макроса) mov eax,[<след.свободный регистр> + <свободный регистр> * 4] Причем нужно случайно не перезаписать значения параметров, когда они передаются в каких нибудь (eax,edx,ecx). Возможно ли это на FASM? |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.175 |