Оцените код

Тема в разделе "WASM.BEGINNERS", создана пользователем Phuntik, 26 дек 2009.

  1. spa

    spa Active Member

    Публикаций:
    0
    Регистрация:
    9 мар 2005
    Сообщения:
    2.240
    лично я юзаю инлайн, а дальше компилятор сам разберется.
     
  2. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    Компилятор не разберётся, меняется возвращаемое ф-ей width() значение с каждой итерацией или нет. Или разберётся? В любом случае сделанному своими руками можно доверять. А компилятор может ошибаться.
     
  3. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    Отклонились от темы. Может, ещё кто конструктивное чего скажет?
     
  4. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    Вместо
    Код (Text):
    1. table db '0', '1', '2', '3', '4' ,'5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
    можно написать table db '0123456789ABCDEF'. Строка, выходящая за пределы экрана - это не очень хорошо.

    cupuyc
    Раньше всё было в точности наоборот. И память измерялась в килобайтах. Тысяча inc вместо add, и экономия видна невооружённым глазом.
     
  5. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Значит придется следить за моментом, после которого не уследишь :)
    Строки для вывода это не переменные, а константы.
    Я не про все .if спрашивал. Сравним:
    .if eax = 0
    jmp lExit
    .endif
    и
    or eax, eax
    je lExit
    3 строки против 2х.
    Optimization Manual, 3.6.8 Mixing Code and Data. Извини, про ud2 (специальный невалидный опкод) я тупанул, ее рекомендуют располагать после косвенных переходов, что бы проц не пытался декодировать данные, как инструкции. ret хоть и косвенный переход, но должен быть в trace cache.

    Он иногда разберется, если в
    for(int i = 0; i < widht(); i++)
    widht() - константная функция-член класса, или видно определение функции, и оно достаточно простое, что бы компилятор понял, что побочных эффектов нет и состояние не хранится.
     
  6. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    J0E
    А я утверждаю, что это переменные. Я прав? ;) И всё же, где их хранить?

    О да. Возьмём на заметку.

    И всё же, интересует, как работать со строками наиболее удобным образом.
    Если так:
    invoke L, 'string',
    то больно уж неудобно в отладчике смотреть. Если писать их в сегменте кода, то на каждую строку свой идентификатор нужно. Если строчек мало, ещё куда ни шло, а если много, то названия замучаешься выписывать.
     
  7. iZzz32

    iZzz32 Sergey Sfeli

    Публикаций:
    0
    Регистрация:
    3 сен 2006
    Сообщения:
    355
    Поищи на форуме фасма [http://board.flatassembler.net/topic.php?p=75504#75504]макросы[/url], которые данные собирают в одном месте. Или свои напиши. Удобство сомнительное, хоть читаемость кода и повышается.
     
  8. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    iZzz32
    Да не, там тоже, если я правильно понял, для каждой строки нужно уникальное имя. Меня же интересует следующее:
    Нужно вызвать функцию, передав ей в качестве параметра строки.
    Если я делаю так:
    Код (Text):
    1. stdcall Procedure, 'string'
    , то в отладчике я увижу приблизительно следующее:
    Код (Text):
    1. call lablel1
    2. ...
    3. здесь лабуда
    4. ...
    5. call Procedure
    , где лабуда - дизассемблированные байты строки, которые дизассемблер принимает за код.
    Очень неудобно для отладки.
    Есть другой способ -
    Код (Text):
    1. section code
    2. stdcall Procedure, string
    3. section data
    4. string db 'string'
    . Так гораздо удобней отлаживать, но заколебёшься различать строки.
    Интересует, как можно совместить достоинства одного и другого способа - лёгкость в сопровождении (если мне нужно сто строк по одному разу вывести, то легче будет написать их один раз прямо в тексте программы, нежели описать в коде данных и потом ссылаться по имени) и чистоту получившегося кода?
    С-компиляторы это делают автоматом, я так понимаю - если встречается новая строка, они выделяют ей место в памяти и потом используют этот адрес.
    Как провернуть то же самое на FASM-е?
    И вообще. Как вы делаете?
     
  9. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Конечно прав, но в таком случае появляются две проблемы: твоя программа нереентерабельна; возникает вопрос "где их хранить?". ;) А константы можно хранить в соответствующей секции исполняемого образа. ;) Макросы под твои требования допилить точно можно, я вряд ли чем помогу, попробуй начать с @@:
     
  10. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    J0E
    О, гуд, спасибо, буду пробовать. Только вот не знаю, каким боком может помочь @@ как имя метки, к которой можно обратиться без имени, но с ограничениями.
     
  11. iZzz32

    iZzz32 Sergey Sfeli

    Публикаций:
    0
    Регистрация:
    3 сен 2006
    Сообщения:
    355
    Phuntik, да, я не совсем верно выразился. Я имел в виду доделать invoke, чтобы размещал строки с помощью block-mover-ов. Нечто вроде этого (набросал наскоро, пользоваться не стоит :derisive:):
    Код (Text):
    1. ;------------------------------------------------------------------------------;
    2. ; Compile with flat assembler v1.68+, <http://flatassembler.net/download.php>. ;
    3. ;------------------------------------------------------------------------------;
    4.         format  pe gui 4.1
    5.         entry   start
    6.         include 'win32a.inc'
    7.  
    8. macro collect_strings
    9. {
    10.   macro strings _,[sm]
    11.   \{
    12.     sm
    13.     purge sm
    14.     restore strings
    15.   \}
    16.   match e , strings \{ e \}
    17.   purge strings
    18. }
    19.  
    20. macro yai name*,[p]
    21. {
    22.   common
    23.     if ~ p eq
    24.   reverse
    25.     local m
    26.     strings equ strings,m
    27.     macro m \{
    28.       if p eqtype ''
    29.         ..str_#m: db p,0
    30.       end if
    31.     \}
    32.     if p eqtype ''
    33.       push ..str_#m
    34.     else
    35.       push dword p
    36.     end if
    37.   common
    38.     end if
    39.     call name
    40. }
    41.  
    42. start:
    43.         yai     [MessageBox],NULL,'Xyzzy is the fooest bar of baz!','Hello, world',MB_ICONINFORMATION
    44.         yai     [MessageBox],NULL,'Test','X',MB_ICONINFORMATION
    45.         retn
    46.  
    47.         data    import
    48.         library kernel32,'KERNEL32.DLL',\
    49.                 user32,'USER32.DLL'
    50.         include 'api/kernel32.inc'
    51.         include 'api/user32.inc'
    52.         end     data
    53.  
    54. collect_strings
     
  12. Phuntik

    Phuntik New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2008
    Сообщения:
    318
    iZzz32
    Окей, спасибо, буду вникать.