Студентам с вопросами о лабораторных работах сюда

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

  1. Babajota

    Babajota New Member

    Публикаций:
    0
    Регистрация:
    19 фев 2012
    Сообщения:
    6
    Добрый день.
    Програма должна непрерывно выводить на екран ASCII символ с порта клавиатуры и завершатса при нажатии 'Esc'.

    FASM:
    Код (Text):
    1. org 100h
    2.  
    3. start:
    4.         in al,60h       ;получаем скан код с порта
    5.         mov dl,al       ;помещаем етот код на друк
    6.         mov ah,02h      ;функцыя вывода символа на екран
    7.         int 21h         ;вызываем ДОС прерывание
    8.         test dl,1Bh     ;проверяем не нажато ли 'Esc'
    9.         jnz continue
    10.  
    11. continue:
    12.         loop start      ;повторяем цыкл
    13. ret
    Но програма не работает как надо. Она выводит три строки с одним символом и завершаетса.
    Я точно чтото упустил. Прошу помогите мне.
     
  2. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Вы понимаете как работает команда loop? И зачем вы её засунули?
    jnz start
    loop убрать.
     
  3. Babajota

    Babajota New Member

    Публикаций:
    0
    Регистрация:
    19 фев 2012
    Сообщения:
    6
    Сделал так:
    Код (Text):
    1. org 100h
    2.  
    3. start:
    4.         in al,60h       ;получаем скан код с порта
    5.         mov dl,al       ;помещаем етот код на друк
    6.         mov ah,02h      ;функцыя вывода символа на екран
    7.         int 21h         ;вызываем ДОС прерывание
    8.         test dl,1Bh     ;проверяем не нажато ли 'Esc'
    9.         jnz start
    10. ret
    програма работает 1-й раз некоторое время и завершаетса без нажатия 'Esc' При етом нажатие клавиш изменяет выводимые символы на екране, но не те что надо...
    Все следующие запуски приводят к выводу одного символа и завершения програмы.

    Посоветуйте мне что сделать, дописать, изменить в коде...
     
  4. MMIX

    MMIX New Member

    Публикаций:
    0
    Регистрация:
    9 дек 2011
    Сообщения:
    385
    Тут надо 2 процедуры считывания символа делать.
     
  5. MMIX

    MMIX New Member

    Публикаций:
    0
    Регистрация:
    9 дек 2011
    Сообщения:
    385
    А не у вас конкретно про порты, думал прерывания можно заюзать.

    Ошибка видимо в том что после прерывания в dl не символ а чото другое, не? Посмотрите в дебуге.

    Код (Text):
    1. org 100h
    2.  
    3. start:
    4.         in al,60h       ;получаем скан код с порта
    5.         test  al,1Bh
    6.         je     end
    7.         mov dl,al       ;помещаем етот код на друк
    8.         mov ah,02h      ;функцыя вывода символа на екран
    9.         int 21h         ;вызываем ДОС прерывание
    10.         jmp start
     
  6. Babajota

    Babajota New Member

    Публикаций:
    0
    Регистрация:
    19 фев 2012
    Сообщения:
    6
    Спасибо!
    Вы мне помогли))

    Вот рабочий код:
    Код (Text):
    1. org 100h
    2.  
    3. start:
    4.         in al,60h       ;получаем скан код с порта
    5.         cmp  al,01h     ;сравниваем его с 1-ой клавишей на клавиатуре (Esc)
    6.         je endp         ;если да - на выход
    7.         or al,80h       ;скан-код отпускания клавиши равен скан-коду нажатия плюс 80h
    8.         out 61h,al      ;Если в старший бит этого порта записать значение 1, клавиатура будет заблокирована
    9.         int 29h         ;INT 29h: Быстрый вывод символа на экран (недокументированное прерывание 29h)
    10.         jmp start       ;повтор цыкла
    11.  
    12. endp:
    13.         ret             ;Выход
    Выводимые символы не совпадают с нажатыми клавишами, так как скан код что возвращает порт не совпадает с ASCII кодом символа.
     
  7. MMIX

    MMIX New Member

    Публикаций:
    0
    Регистрация:
    9 дек 2011
    Сообщения:
    385
    Babajota

    Ну вот видите когда в отладчике посмотришь сразу все ясно хехе :)
     
  8. Babajota

    Babajota New Member

    Публикаций:
    0
    Регистрация:
    19 фев 2012
    Сообщения:
    6
    Добрый вечер.
    Еще одна проблема нашлась...

    эсть строка дивного формата:
    Код (Text):
    1. ; строка " 00h 00:00 " с атрибутом 1Fh после каждого слова
    2. output_line        db    ' ',1Fh,'0',1Fh,'0',1Fh,'h',1Fh
    3.                    db    ' ',1Fh,'0',1Fh,'0',1Fh,':',1Fh
    4.                    db    '0',1Fh,'0',1Fh,' ',1Fh
    и код на TASM:
    Код (Text):
    1. ; AL = час в BCD-формате
    2.         call       bcd2asc                     ; преобразовать в ASCII,
    3.         mov        byte ptr output_line[2],ah  ; поместить их в
    4.         mov        byte ptr output_line[4],al  ; строку output_line
    5.  
    6.         mov        al,cl                       ; CL = минута в BCD-формате
    7.         call       bcd2asc
    8.         mov        byte ptr output_line[10],ah
    9.         mov        byte ptr output_line[12],al
    10.  
    11.         mov        al,dh                       ; DH = секунда в BCD-формате
    12.         call       bcd2asc
    13.         mov        byte ptr output_line[16],ah
    14.         mov        byte ptr output_line[18],al
    Помогите мне перевести его в FASM. Пожалуйста!
     
  9. MMIX

    MMIX New Member

    Публикаций:
    0
    Регистрация:
    9 дек 2011
    Сообщения:
    385
    Babajota

    Там разница основная только в том что если в масме/тасме (не идеальном) скобок нет когда юзаем значение ячейки, то в фасме нужна скобка [...] -- это будет значение переменной и т.д. А адрес элемента наоборот без скобок. Вообще сие вы сами знать должны есле юзаете фасм :)

    mov byte ptr output_line[2],ah
    в фасме будет примерно как
    mov byte [output_line+2],ah
     
  10. Babajota

    Babajota New Member

    Публикаций:
    0
    Регистрация:
    19 фев 2012
    Сообщения:
    6
    Спасибо))
    Но всплыла ещо одна ощыбка:
    Код (Text):
    1.         mov        cx,output_l  
    2.         push       0B800h
    3.         pop        es              
    4.         mov        di,word [start_position]
    5.         mov        si,output_line  
    6.         cld
    7.         rep        movsb  
    8. ...
    9. output_l equ $ - output_line
    Error: undefined symbol 'output_l'

    Что здесь не так, ведь он объявлен?
     
  11. MMIX

    MMIX New Member

    Публикаций:
    0
    Регистрация:
    9 дек 2011
    Сообщения:
    385
    Babajota
    Попробуйте ее вначале объявить.
     
  12. MMIX

    MMIX New Member

    Публикаций:
    0
    Регистрация:
    9 дек 2011
    Сообщения:
    385
    Babajota
    Ну и разумеется она должна идтить сразу после output_line

    А вообще ошибка наверное в том что

    mov cx,output_l

    будет заносить адрес этой переменнай, а вам надобно значение, так што в квадратныя скобки.

    mov cx,[output_l]
     
  13. SUNNY

    SUNNY Member

    Публикаций:
    0
    Регистрация:
    1 окт 2009
    Сообщения:
    32
    Хорошая тема. Тут в отличае от других тем хоть что-то реальное подсказывают, а не дураком обзывают. Вернусь же к вопросам самого начального уровня, вопросам выбора рабочего инструмента.

    Я учусь программировать на MASM, и прежде чем приступить к созданию WIN32-программ хочу научиться програмировать для DOS.
    1. Можно ли создавать DOS-программы при помощи пакета MASM32 или для этого лучше достать из сундука MASM v.6.15? Или может ещё более старый пакет?
    2. Нужен редактор, умеющий редактировать в кодировке CP-866, раз уж под DOS пишу. Ну и чтоб подсветка ASM-синтаксиса была, автодобавление пробелов и всё прочее.
    3. Низкоуровневое програмирование это конечно хорошо, но макросы удобнее. Где взять inc-файлы с макросами: функций DOS (int21, int10, int09), математических функций и прочего?
     
  14. Babajota

    Babajota New Member

    Публикаций:
    0
    Регистрация:
    19 фев 2012
    Сообщения:
    6
    Да но теперь:

    Error: operand sizes do not match.
    mov cx,[$-output_line]


    может ету строку можно как то по другому записать:
    Код (Text):
    1. output_l equ $ - output_line
    И вот код всей программы:

    Код (Text):
    1. ; timer.asm
    2. ; демонстрация перехвата прерывания системного таймера: вывод текущего времени
    3. ; в левом углу экрана
    4. org    100h
    5. ; строка " 00h 00:00 " с атрибутом 1Fh (белый на синем) после каждого символа
    6. output_line    db    ' ',1Fh,'0',1Fh,'0',1Fh,'h',1Fh
    7.            db    ' ',1Fh,'0',1Fh,'0',1Fh,':',1Fh
    8.            db    '0',1Fh,'0',1Fh,' ',1Fh
    9.  
    10. output_l equ $ - output_line
    11.  
    12. old_int1Ch   dd    ?   ; здесь хранится адрес предыдущего обработчика
    13. start_position   dw    0   ; позиция на экране, в которую выводится текущее время
    14. start:
    15. ; сохранить адрес предыдущего обработчика прерывания 1Ch
    16.     mov    ax,351Ch     ; АН = 35h, AL = номер прерывания
    17.     int    21h          ; функция DOS: определить адрес обработчика
    18.     mov    word [old_int1Ch],bx   ; прерывания
    19.     mov    word [old_int1Ch+2],es ; (возвращается в ES:BX)
    20. ; установить наш обработчик
    21.     mov    ax,251Ch     ; АН = 25h, AL = номер прерывания
    22.     mov    dx,int1Ch_handler ; DS:DX - адрес обработчика
    23.     int    21h          ; установить обработчик прерывания 1Ch
    24.  
    25. ; здесь размещается собственно программа, например вызов command.com
    26.     mov    ah,1
    27.     int    21h          ; ожидание нажатия на любую клавишу
    28. ; конец программы
    29.  
    30. ; восстановить предыдущий обработчик прерывания 1Ch
    31.     mov    ax,251Ch     ; АН = 25h, AL = номер прерывания
    32.     mov    dx,word [old_int1Ch+2]
    33.     mov    ds,dx
    34.     mov    dx,word old_int1Ch ; DS:DX - адрес обработчика
    35.     int    21h
    36.     ;ret
    37.  
    38. ; обработчик для прерывания 1Ch
    39. ; выводит текущее время в позицию start_position на экране
    40. ; (только в текстовом режиме)
    41. int1Ch_handler:
    42.     pusha               ; обработчик аппаратного прерывания
    43.     push       es           ; должен сохранять ВСЕ регистры
    44.     push       ds
    45.     push       cs           ; на входе в обработчик известно только
    46.     pop    ds           ; значение регистра CS
    47.     mov    ah,02h       ; Функция 02h прерывания 1Ah:
    48.     int    1Ah          ; чтение времени из RTC,
    49.     jc     exit_handler     ; если часы заняты - в другой раз
    50. ; AL = час в BCD-формате
    51.     call       bcd2asc             ; преобразовать в ASCII,
    52.     mov    byte [output_line+2],ah  ; поместить их в
    53.     mov    byte [output_line+4],al  ; строку output_line
    54.  
    55.     mov    al,cl               ; CL = минута в BCD-формате
    56.     call       bcd2asc
    57.     mov    byte [output_line+10],ah
    58.     mov    byte [output_line+12],al
    59.  
    60.     mov    al,dh               ; DH = секунда в BCD-формате
    61.     call       bcd2asc
    62.     mov    byte [output_line+16],ah
    63.     mov    byte [output_line+18],al
    64.  
    65.     mov    cx,[output_l]         ; число байт в строке - в СХ
    66.     push       0B800h
    67.     pop    es                  ; адрес в видеопамяти
    68.     mov    di,word [start_position]  ; в ES:DI
    69.     mov    si,output_line   ; адрес строки в DS:SI
    70.     cld
    71.     rep    movsb               ; скопировать строку
    72.  
    73. exit_handler:
    74.     pop    ds                  ; восстановить все регистры
    75.     pop    es
    76.     popa
    77.     jmp    old_int1Ch          ; передать управление предыдущему обработчику
    78.  
    79. ; процедура bcd2asc
    80. ; преобразует старшую цифру упакованного BCD-числа из AL в ASCII-символ,
    81. ; который будет помещен в АН, а младшую цифру - в ASCII-символ в AL
    82. bcd2asc:
    83.     mov    ah,al
    84.     and    al,0Fh       ; оставить младшие 4 бита в AL
    85.     shr    ah,4         ; сдвинуть старшие 4 бита в АН
    86.     or     ax,3030h     ; преобразовать в ASCII-символы
    87.     ret
    Воопще ета програма может работать?
     
  15. Valid01

    Valid01 New Member

    Публикаций:
    0
    Регистрация:
    22 фев 2012
    Сообщения:
    46
    SUNNY
    Можно .
     
  16. Valid01

    Valid01 New Member

    Публикаций:
    0
    Регистрация:
    22 фев 2012
    Сообщения:
    46
    Babajota

    А указывать размер переменной кто будет ?
     
  17. SUNNY

    SUNNY Member

    Публикаций:
    0
    Регистрация:
    1 окт 2009
    Сообщения:
    32
    Valid01
    Ещё бы на два оставшихся вопроса ответ найти - и совсем красота будет.
     
  18. Valid01

    Valid01 New Member

    Публикаций:
    0
    Регистрация:
    22 фев 2012
    Сообщения:
    46
    SUNNY
    Ну редактор пофигу , я вот недавно поставил винасм , вроде пойдет .
    Макросы под дос - не знаю , вряд ле найдете .
     
  19. marchibo220

    marchibo220 Алексей

    Публикаций:
    0
    Регистрация:
    5 мар 2012
    Сообщения:
    1
    Адрес:
    Москва
    Посмотри в инете, сейчас масса готовых редакторов.
     
  20. DecMiay

    DecMiay New Member

    Публикаций:
    0
    Регистрация:
    27 фев 2011
    Сообщения:
    3
    Объясните наконец, уже 3 часа бьюсь и не могу понять.
    Вот статья http://wasm.ru/article.php?article=1001017, про динамические библиатеки.

    Так вот там есть процедура
    Код (Text):
    1. TestHello proc
    2.     invoke MessageBox,NULL,addr HelloMsg,addr AppName,MB_OK
    3.     ret
    4. TestHello endp
    Так вот как мне туда передать целочисленный массив и выполнить над ним какие-небудь действия и вернуть обратно. И ещё я использую invoke LoadLibrary в основном приложении. Очень нуждаюсь в вашей помощи.
    Кстати вот ссылка на пример http://wasm.ru/pub/1/files/tut17.zip.