Мое почтение всем. Пишу сейчас заголовочный файл для своего дизассемблера (http://mediana.sf.net) по запросу (https://wasm.ru/forum/viewtopic.php?pid=392914#p392914). Несколько вопросов: 1. Mediana позволяет выводить мнемонику в ASCII и UNICODE. Соответственно, мнемоника может быть объявлена как db и как dw. Попробовал решить проблему так: struct INSTRUCTION ... if UNICODE >= 1 mnemonic dw MAX_MNEMONIC_LEN dup ? else mnemonic db MAX_MNEMONIC_LEN dup ? end if ends Получаю ошибку 'INSTRUCTION.mnemonic db MAX_MNEMONIC_LEN dup ?': Symbol already defined. Неужели из-за одной метки придется делать два файла: mediana32a.inc и mediana32w.inc? 2. Как правильнее было бы организровать массив структур в FASM? Чтобы удобнее было индексировать? l_inc предложил такой макрос: struc times [arg] { common match n def, arg \{ rept 1 %:1 \\{ . def \\} rept n-1 %:2 \\{ .\\#_\\#% def \\} \} } (С), вроде бы, baldr. Но он позволяет индексировать массивы структур лишь во время компиляции. Может у кого-то есть более элегантное решение? Или не морочить никому голову и сделать массив через dup? Заранее благодарен за ответы.
n0name Спасибо, работает. iZzz32 Заманчиво, но я хочу чтобы и в Linux работало. Поэтому поддержка UNICODE у меня своя.
KIV По сути дела я так и сделал, объявив в С свой тип unichar_t. А он в зависимости от макроса UNICODE либо char, либо wchar_t. Насчет FASM'а -- не уверен, что тип нужен.
n0name Ясно дело, что сами по себе типы идентичны. Но макросы фасм переопределяют именно du для преобразования обычных слов в unicode. Поэтому ради единообразия и возможной будущей совместимости лучше использовать таки du.
Поторопился я с ответом "все работает". Для структур все же не работает. Вот на таком примере выдается ошибка: Код (Text): include 'macro/struct.inc' T equ 1 struct TEST if T eq 1 tt db ? else tt dw ? end if ends Похоже, все же придется сделать два отдельных заголовочных.
Код (Text): struct TEST match =1,T { tt db ? } match =2,T { tt dw ? } ends А может всё же один-единственный условный TCHAR в начале инклуда, скопированный из win32[aw].inc)? Зачем эти велосипеды?
Естественно. Надо чётко представлять взаимодействие препроцессора и интерпретатора, входящих в состав FASM. STRUCT.INC из стандартного комплекта переопределяет db/dw/etc. как макросы в теле макро struct, соответственно директива интерпретатора if отрабатывает совсем не так (и не тогда). Вариант с макро TCHAR, предлагаемый iZzz32, выглядит вполне приемлемым. Удобнее — это как? Индексная арифметика (в общем случае) на совести программиста. Тот struc-макро был написан под конкретный случай, чтобы можно было статически адресовать элементы массива с конкретными индексами. Неверно. dw "Hello, world!" не компилируется (по известной причине).
baldr В общем, я сделал TCHAR (точнее, просто содрал его из заголовочного файла FASM, переименовав в unichar_t) и доволен. Насчет индексируемости (равно как и создания массивов), просто руками скопировал член структуры три раза, дав имена типа name0, name1, name2. Если кого-то не устроит -- переделаю, а пока пусть так.
Я бы порекомендовал использовать что-то вроде rept 3 i:0 { name#i TEST } чтобы подчеркнуть идентичность объявления всех трёх. Можно поизгаляться и нарисовать обёртку для макро ends, которая определит обёртку для структуры чтобы можно было использовать объявление вида name TEST[3]: Код (Text): include "Win32W.Inc" macro ends { match name=,fields, fields@struct \{; имя структуры пригодится для обёртки ends; пусть отработает родное из STRUCT.INC struc name [args] \\{; обёртка \\local ! ! equ ?; флаг наличия скобок match [n], args \\\{; они есть rept n i:0 \\\\{ .\\\\#i name; бэкслэши — зло ;-) \\\\} restore !; установим флаг \\\} match =?,! \\\{; не было скобок, отдадим как есть . name args restore ! \\\} \\} \} } ;;; для проверки struct TEST tt TCHAR cc db ? ends; тут сработает наш ends name TEST[3]; а тут — определённое им struc-макро nn TEST <'A', 'b'>; инициализированная структура rept 3 i:0 { dw `i, name#i }; чтобы убедиться: будет dw '0', name0, '1', name1,… dw nn Это макро должно быть определено после include "MACRO\STRUCT.INC" но до использования ends. Написано на коленке чтобы проиллюстрировать идею, за корректность не ручаюсь.