FASM, условная компиляция и не только

Тема в разделе "WASM.ASSEMBLER", создана пользователем Mika0x65, 17 авг 2010.

  1. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Мое почтение всем.

    Пишу сейчас заголовочный файл для своего дизассемблера (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?

    Заранее благодарен за ответы.
     
  2. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    if UNICODE eq 1
     
  3. iZzz32

    iZzz32 Sergey Sfeli

    Публикаций:
    0
    Регистрация:
    3 сен 2006
    Сообщения:
    355
    1. TCHAR, может быть, будет нагляднее?
     
  4. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    n0name
    Спасибо, работает.

    iZzz32
    Заманчиво, но я хочу чтобы и в Linux работало. Поэтому поддержка UNICODE у меня своя.
     
  5. KIV

    KIV Member

    Публикаций:
    0
    Регистрация:
    16 июл 2009
    Сообщения:
    231
    А ещё лучше не dw, а du (уж это не макрос и есть везде).
    И кто мешает свой TCHAR объявить?
     
  6. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    du == dw
     
  7. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    KIV
    По сути дела я так и сделал, объявив в С свой тип unichar_t. А он в зависимости от макроса UNICODE либо char, либо wchar_t. Насчет FASM'а -- не уверен, что тип нужен.
     
  8. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    n0name
    Ясно дело, что сами по себе типы идентичны. Но макросы фасм переопределяют именно du для преобразования обычных слов в unicode. Поэтому ради единообразия и возможной будущей совместимости лучше использовать таки du.
     
  9. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Поторопился я с ответом "все работает". Для структур все же не работает. Вот на таком примере выдается ошибка:

    Код (Text):
    1. include 'macro/struct.inc'
    2.  
    3. T equ 1
    4.  
    5. struct TEST
    6.   if T eq 1
    7.     tt db ?
    8.   else
    9.     tt dw ?
    10.   end if
    11. ends
    Похоже, все же придется сделать два отдельных заголовочных.
     
  10. iZzz32

    iZzz32 Sergey Sfeli

    Публикаций:
    0
    Регистрация:
    3 сен 2006
    Сообщения:
    355
    Код (Text):
    1. struct TEST
    2.   match =1,T {
    3.     tt db ?
    4.   }
    5.   match =2,T {
    6.     tt dw ?
    7.   }
    8. ends
    А может всё же один-единственный условный TCHAR в начале инклуда, скопированный из win32[aw].inc)? Зачем эти велосипеды?
     
  11. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    Естественно. Надо чётко представлять взаимодействие препроцессора и интерпретатора, входящих в состав FASM.
    STRUCT.INC из стандартного комплекта переопределяет db/dw/etc. как макросы в теле макро struct, соответственно директива интерпретатора if отрабатывает совсем не так (и не тогда). Вариант с макро TCHAR, предлагаемый iZzz32, выглядит вполне приемлемым.

    Удобнее — это как? Индексная арифметика (в общем случае) на совести программиста. Тот struc-макро был написан под конкретный случай, чтобы можно было статически адресовать элементы массива с конкретными индексами.

    Неверно. dw "Hello, world!" не компилируется (по известной причине).
     
  12. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    baldr
    В общем, я сделал TCHAR (точнее, просто содрал его из заголовочного файла FASM, переименовав в unichar_t) и доволен. Насчет индексируемости (равно как и создания массивов), просто руками скопировал член структуры три раза, дав имена типа name0, name1, name2. Если кого-то не устроит -- переделаю, а пока пусть так.
     
  13. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    Я бы порекомендовал использовать что-то вроде rept 3 i:0 { name#i TEST } чтобы подчеркнуть идентичность объявления всех трёх. Можно поизгаляться и нарисовать обёртку для макро ends, которая определит обёртку для структуры чтобы можно было использовать объявление вида name TEST[3]:
    Код (Text):
    1. include "Win32W.Inc"
    2.  
    3. macro ends {
    4.   match name=,fields, fields@struct \{; имя структуры пригодится для обёртки
    5.     ends; пусть отработает родное из STRUCT.INC
    6.     struc name [args] \\{; обёртка
    7.       \\local !
    8.       ! equ ?; флаг наличия скобок
    9.       match [n], args \\\{; они есть
    10.         rept n i:0 \\\\{
    11.           .\\\\#i name; бэкслэши — зло ;-)
    12.         \\\\}
    13.         restore !; установим флаг
    14.       \\\}
    15.       match =?,! \\\{; не было скобок, отдадим как есть
    16.         . name args
    17.         restore !
    18.       \\\}
    19.     \\}
    20.   \}
    21. }
    22.  
    23. ;;; для проверки
    24. struct TEST
    25.   tt TCHAR
    26.   cc db ?
    27. ends; тут сработает наш ends
    28.  
    29. name TEST[3]; а тут — определённое им struc-макро
    30. nn TEST <'A', 'b'>; инициализированная структура
    31. rept 3 i:0 { dw `i, name#i }; чтобы убедиться: будет dw '0', name0, '1', name1,…
    32. dw nn
    Это макро должно быть определено после include "MACRO\STRUCT.INC" но до использования ends. Написано на коленке чтобы проиллюстрировать идею, за корректность не ручаюсь. :derisive: