Код (Text): ; Hi! ; По идее прога должна вывести строку msg столько раз, сколько ; ввел юзер. Но почему-то не получается :/ ; P.S. [x] это аналог "offset x" или там "addr x" ??? ; thx format PE console include 'c:\fasm\include\win32a.inc' entry start ;_____________________________________________________________________ _________ ;_____________________________________________________________________ _________ section '.code' code readable writeable executable start: push STD_INPUT_HANDLE call [GetStdHandle] push 0 push [nread] ; сколько на самом деле считали символов (?) push 1 ; сколько хотим считать (?) push [read] ; куда читаем (?) push eax call [ReadConsole] push STD_OUTPUT_HANDLE call [GetStdHandle] mov ebx, eax pushad mov esi, [read] lbl1: push 0 push 0 push 8 push msg ; и почему тут при [msg] error возникает ? push ebx call [WriteConsole] dec esi jnz lbl1 popad push 0 call [ExitProcess] ;____________________________________________________________________ ;____________________________________________________________________ msg db 'Hello!',13,10,0 read dd ? nread dd ? ;_____________________________________________________________________ _________ ;_____________________________________________________________________ _________ data import library kernel32, 'kernel32.dll' include 'c:\fasm\include\apia\kernel32.inc' end data
Убрать квадратные скобки, т.к. эти параметры должны быть адресами (указателями), а не данными, которые содержатся по указанному адресу.
LOL Там ещё ошибки есть. Вместо msg желательно использовать другое имя (szHello, например), чтоб не путать со стандартной структурой msg. pushad / popad тут ни к чему.
Понял! Ты прав. Копание с Olly дало результат =) Только вот что - если ввести, например, число 4, то оно нормально считается и запишется куда надо (в read). Только туда запишется ASCII код символа - 34h, затем при считавании его в esi (кол-во итераций цикла) там и окажется это значение, т.е. цикл выполниться 34h = 52d раза :/ Что, впрочем, вполне логично и теперь понятно Сейчас буду думать, как получить в read не 24h, а 4d =) Где-то я это видел... Если кто знает - напишите plz! [add] pushad/popad, что они лишние - знаю. Я в общем не полностью исходник постил, а его "проблемную" часть. А эти забыл удалить. На счет имен - учту, спасибо. [/add]
А что тут думать? Вычесть ASCII код нуля решит проблему: Код (Text): movzx esi, BYTE [read] sub esi,'0' Теперь в esi будет число. Но будет очень плохо, если пользователь в консоль введёт ноль. Подумайте почему и как исправить...
Ну... Юров говорит: "movzx - преобразование элементов без знака меньшей размерности в эквивалентные им элементы без знака большей размерности". Я так ничего не скажу - команду эту вижу впервые :/ Но на ЯВУ я бы сделал так: взял бы ASCII код символа (напр. 34h), взял бы код '0' - 30h и вычел бы их: 34h-30h=4h что мне и нужно. А если посмотреть в отладчике... так после movzx в будеь 30h, затем вычитаем тоже 30h и получаем 0, а затем, очевидно, бесконечный цикл! Ну а исправить элементарно - jz nah
Ну... Юров говорит: "movzx - преобразование элементов без знака меньшей размерности в эквивалентные им элементы без знака большей размерности". Я так ничего не скажу - команду эту вижу впервые :/ Но на ЯВУ я бы сделал так: взял бы ASCII код символа (напр. 34h), взял бы код '0' - 30h и вычел бы их: 34h-30h=4h что мне и нужно. А если посмотреть в отладчике... так... после movzx в будеь 30h, затем вычитаем тоже 30h и получаем 0, а затем, очевидно, бесконечный цикл! Ну а исправить элементарно - jz nah. Мда... мог бы и без отладчика догадаться [add] Sorry за дублирование :/[/add]
И еще - к сожалению я не понял, почему нужно: Код (Text): movzx esi, BYTE [read] sub esi,'0' а не так: Код (Text): sub BYTE [read],'0' mov esi, [read] Вроде бы работает...
LOL Ошибка в этой строчке: Мы подгружаем из буфера в esi сразу 4 байта!!! К счастью, т.к. буфер инициализируется нулями, во 2м, 3м и 4м байте будут нули, но в общем случае, если нужно прочитать байт и нет уверенности что в старших байтах нули, лучше использовать movzx. А вычитать '0' быстрее из регистра, чем из ячейки в памяти. Первый вариант обращается к памяти 1 раз (в первой инструкции), а второй - 2 раза (в обоих инструкциях).
Да, про обращения к памяти я понял =). Но не понял формулировки Юрова о movzx. Я так понимаю: mov eax, [что-то_там] movzx eax, BYTE [что-то_еще] Во этом случае происходит копирование 1 байта (а может и 2 если там WORD), а в первом всех 4. Так?
Вот! А то Юров уж как-то заумно написал Спасибо огромное! Я много чего узнал/понял =) Хотя... хочется больше и быстрее [ADD] вроде разобрался я с массивами =)[/ADD]