Компилятор не разберётся, меняется возвращаемое ф-ей width() значение с каждой итерацией или нет. Или разберётся? В любом случае сделанному своими руками можно доверять. А компилятор может ошибаться.
Вместо Код (Text): table db '0', '1', '2', '3', '4' ,'5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' можно написать table db '0123456789ABCDEF'. Строка, выходящая за пределы экрана - это не очень хорошо. cupuyc Раньше всё было в точности наоборот. И память измерялась в килобайтах. Тысяча inc вместо add, и экономия видна невооружённым глазом.
Значит придется следить за моментом, после которого не уследишь Строки для вывода это не переменные, а константы. Я не про все .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() - константная функция-член класса, или видно определение функции, и оно достаточно простое, что бы компилятор понял, что побочных эффектов нет и состояние не хранится.
J0E А я утверждаю, что это переменные. Я прав? И всё же, где их хранить? О да. Возьмём на заметку. И всё же, интересует, как работать со строками наиболее удобным образом. Если так: invoke L, 'string', то больно уж неудобно в отладчике смотреть. Если писать их в сегменте кода, то на каждую строку свой идентификатор нужно. Если строчек мало, ещё куда ни шло, а если много, то названия замучаешься выписывать.
Поищи на форуме фасма [http://board.flatassembler.net/topic.php?p=75504#75504]макросы[/url], которые данные собирают в одном месте. Или свои напиши. Удобство сомнительное, хоть читаемость кода и повышается.
iZzz32 Да не, там тоже, если я правильно понял, для каждой строки нужно уникальное имя. Меня же интересует следующее: Нужно вызвать функцию, передав ей в качестве параметра строки. Если я делаю так: Код (Text): stdcall Procedure, 'string' , то в отладчике я увижу приблизительно следующее: Код (Text): call lablel1 ... здесь лабуда ... call Procedure , где лабуда - дизассемблированные байты строки, которые дизассемблер принимает за код. Очень неудобно для отладки. Есть другой способ - Код (Text): section code stdcall Procedure, string section data string db 'string' . Так гораздо удобней отлаживать, но заколебёшься различать строки. Интересует, как можно совместить достоинства одного и другого способа - лёгкость в сопровождении (если мне нужно сто строк по одному разу вывести, то легче будет написать их один раз прямо в тексте программы, нежели описать в коде данных и потом ссылаться по имени) и чистоту получившегося кода? С-компиляторы это делают автоматом, я так понимаю - если встречается новая строка, они выделяют ей место в памяти и потом используют этот адрес. Как провернуть то же самое на FASM-е? И вообще. Как вы делаете?
Конечно прав, но в таком случае появляются две проблемы: твоя программа нереентерабельна; возникает вопрос "где их хранить?". А константы можно хранить в соответствующей секции исполняемого образа. Макросы под твои требования допилить точно можно, я вряд ли чем помогу, попробуй начать с @@:
J0E О, гуд, спасибо, буду пробовать. Только вот не знаю, каким боком может помочь @@ как имя метки, к которой можно обратиться без имени, но с ограничениями.
Phuntik, да, я не совсем верно выразился. Я имел в виду доделать invoke, чтобы размещал строки с помощью block-mover-ов. Нечто вроде этого (набросал наскоро, пользоваться не стоит ): Код (Text): ;------------------------------------------------------------------------------; ; Compile with flat assembler v1.68+, <http://flatassembler.net/download.php>. ; ;------------------------------------------------------------------------------; format pe gui 4.1 entry start include 'win32a.inc' macro collect_strings { macro strings _,[sm] \{ sm purge sm restore strings \} match e , strings \{ e \} purge strings } macro yai name*,[p] { common if ~ p eq reverse local m strings equ strings,m macro m \{ if p eqtype '' ..str_#m: db p,0 end if \} if p eqtype '' push ..str_#m else push dword p end if common end if call name } start: yai [MessageBox],NULL,'Xyzzy is the fooest bar of baz!','Hello, world',MB_ICONINFORMATION yai [MessageBox],NULL,'Test','X',MB_ICONINFORMATION retn data import library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' include 'api/kernel32.inc' include 'api/user32.inc' end data collect_strings