ReadConsole

Тема в разделе "WASM.BEGINNERS", создана пользователем LOL, 29 апр 2006.

  1. LOL

    LOL New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2006
    Сообщения:
    175
    Адрес:
    Russia
    Код (Text):
    1.  
    2. ; Hi!
    3. ; По идее прога должна вывести строку msg столько раз, сколько
    4. ; ввел юзер. Но почему-то не получается :/
    5. ; P.S. [x] это аналог "offset x" или там "addr x" ???
    6. ; thx
    7. format PE console
    8. include 'c:\fasm\include\win32a.inc'
    9. entry start
    10.  
    11. ;_____________________________________________________________________ _________
    12. ;_____________________________________________________________________ _________
    13. section '.code' code readable writeable executable
    14. start:
    15.  
    16.                 push    STD_INPUT_HANDLE
    17.                 call    [GetStdHandle]
    18.  
    19.                 push    0
    20.                 push    [nread]         ; сколько на самом деле считали символов (?)
    21.                 push    1               ; сколько хотим считать (?)
    22.                 push    [read]          ; куда читаем (?)
    23.                 push    eax
    24.                 call    [ReadConsole]
    25.  
    26.                 push    STD_OUTPUT_HANDLE
    27.                 call    [GetStdHandle]
    28.                 mov     ebx, eax
    29.  
    30.                 pushad
    31.  
    32.                 mov     esi, [read]
    33.         lbl1:
    34.  
    35.                 push    0
    36.                 push    0
    37.                 push    8
    38.                 push    msg             ; и почему тут при [msg] error возникает ?
    39.                 push    ebx
    40.                 call    [WriteConsole]
    41.  
    42.                 dec     esi
    43.                 jnz     lbl1
    44.  
    45.                 popad
    46.  
    47.                 push    0
    48.                 call    [ExitProcess]
    49.  
    50. ;____________________________________________________________________
    51.  
    52. ;____________________________________________________________________
    53.  
    54.                 msg     db 'Hello!',13,10,0
    55.                 read    dd ?
    56.                 nread   dd ?
    57. ;_____________________________________________________________________ _________
    58. ;_____________________________________________________________________ _________
    59. data import
    60.                 library         kernel32, 'kernel32.dll'
    61.                 include         'c:\fasm\include\apia\kernel32.inc'
    62. end data
    63.  
     
  2. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine


    Убрать квадратные скобки, т.к. эти параметры должны быть адресами (указателями), а не данными, которые содержатся по указанному адресу.
     
  3. LOL

    LOL New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2006
    Сообщения:
    175
    Адрес:
    Russia
    Хм... я изначально так и делал... сейчас еще раз попробую...
     
  4. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    LOL

    Там ещё ошибки есть. Вместо msg желательно использовать другое имя (szHello, например), чтоб не путать со стандартной структурой msg. pushad / popad тут ни к чему.
     
  5. LOL

    LOL New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2006
    Сообщения:
    175
    Адрес:
    Russia
    Понял! Ты прав. Копание с Olly дало результат =)

    Только вот что - если ввести, например, число 4, то оно нормально считается и запишется куда надо (в read). Только туда запишется ASCII код символа - 34h, затем при считавании его в esi (кол-во итераций цикла) там и окажется это значение, т.е. цикл выполниться 34h = 52d раза :/ Что, впрочем, вполне логично и теперь понятно :) Сейчас буду думать, как получить в read не 24h, а 4d =) Где-то я это видел... Если кто знает - напишите plz!

    [add] pushad/popad, что они лишние - знаю. Я в общем не полностью исходник постил, а его "проблемную" часть. А эти забыл удалить. На счет имен - учту, спасибо. [/add]
     
  6. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine


    А что тут думать? Вычесть ASCII код нуля решит проблему:
    Код (Text):
    1. movzx esi, BYTE [read]
    2. sub esi,'0'


    Теперь в esi будет число. Но будет очень плохо, если пользователь в консоль введёт ноль. Подумайте почему и как исправить...
     
  7. LOL

    LOL New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2006
    Сообщения:
    175
    Адрес:
    Russia
    Ну... Юров говорит: "movzx - преобразование элементов без знака меньшей размерности в эквивалентные им элементы без знака большей размерности". Я так ничего не скажу - команду эту вижу впервые :/ Но на ЯВУ я бы сделал так: взял бы ASCII код символа (напр. 34h), взял бы код '0' - 30h и вычел бы их: 34h-30h=4h что мне и нужно. А если посмотреть в отладчике... так после movzx в будеь 30h, затем вычитаем тоже 30h и получаем 0, а затем, очевидно, бесконечный цикл! Ну а исправить элементарно - jz nah
     
  8. LOL

    LOL New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2006
    Сообщения:
    175
    Адрес:
    Russia
    Ну... Юров говорит: "movzx - преобразование элементов без знака меньшей размерности в эквивалентные им элементы без знака большей размерности". Я так ничего не скажу - команду эту вижу впервые :/ Но на ЯВУ я бы сделал так: взял бы ASCII код символа (напр. 34h), взял бы код '0' - 30h и вычел бы их: 34h-30h=4h что мне и нужно. А если посмотреть в отладчике... так... после movzx в будеь 30h, затем вычитаем тоже 30h и получаем 0, а затем, очевидно, бесконечный цикл! Ну а исправить элементарно - jz nah. Мда... мог бы и без отладчика догадаться :)

    [add] Sorry за дублирование :/[/add]
     
  9. LOL

    LOL New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2006
    Сообщения:
    175
    Адрес:
    Russia
    И еще - к сожалению я не понял, почему нужно:
    Код (Text):
    1.  
    2. movzx esi, BYTE [read]
    3. sub esi,'0'
    4.  


    а не так:
    Код (Text):
    1.  
    2. sub     BYTE [read],'0'
    3. mov     esi, [read]
    4.  


    Вроде бы работает...
     
  10. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    LOL

    Ошибка в этой строчке:



    Мы подгружаем из буфера в esi сразу 4 байта!!! К счастью, т.к. буфер инициализируется нулями, во 2м, 3м и 4м байте будут нули, но в общем случае, если нужно прочитать байт и нет уверенности что в старших байтах нули, лучше использовать movzx.



    А вычитать '0' быстрее из регистра, чем из ячейки в памяти. Первый вариант обращается к памяти 1 раз (в первой инструкции), а второй - 2 раза (в обоих инструкциях).
     
  11. LOL

    LOL New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2006
    Сообщения:
    175
    Адрес:
    Russia
    Да, про обращения к памяти я понял =). Но не понял формулировки Юрова о movzx. Я так понимаю:

    mov eax, [что-то_там]

    movzx eax, BYTE [что-то_еще]

    Во этом случае происходит копирование 1 байта (а может и 2 если там WORD), а в первом всех 4. Так?
     
  12. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    LOL Да. Суффикс zx означает, что старшие 3/2 байта заполняются нулями. zero extend.
     
  13. LOL

    LOL New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2006
    Сообщения:
    175
    Адрес:
    Russia
    Вот! А то Юров уж как-то заумно написал :) Спасибо огромное! Я много чего узнал/понял =) Хотя... хочется больше и быстрее ;)

    [ADD] вроде разобрался я с массивами =)[/ADD]