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

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

  1. Morte

    Morte New Member

    Публикаций:
    0
    Регистрация:
    13 мар 2009
    Сообщения:
    14
    Под дос. Ваш первый вариант, как и мой прилично загружает процессор. (

    Второй вариант не понял. Что изначально должно лежать в BX?:
    Код (Text):
    1. mov ds, ax
    2. mov bx,    ; ???
    3. les dx, [bx]
    оффтоп: А что вообще есть "занятость" процессора? Мне кажется процессор всегда что-то выполняет.
     
  2. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    Под ДОС... задержки для графики обычно делаются произвольные, с синхронизацией с обновлением экрана. Специальный регистр видеокарты отражает факт возврата луча, и в промежуток между двумя кадрами идет запись в видеопамять. Естественно, речь идет о графике, а не о возможном запуске изначально текстового приложения в окне Windows.
    Код (Text):
    1. PROC vsync
    2.         mov dx, 03dah
    3. @1:
    4.         in al, dx
    5.         test al, 8
    6.         jnz short @1
    7. @2:
    8.         in al, dx
    9.         test al, 8
    10.         jz short @2
    11.         ret
    12. ENDP
    13.  
    14. И используется как-то так:
    15. ...
    16. (main loop:)
    17.   call vsync
    18.   (NewPoint)
    19.   (Check ESC)
    20. (end loop)
     
  3. Morte

    Morte New Member

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

    Представьте тетрис. Там обновление происходит сравнительно медленно. Мне именно это и надо.
     
  4. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    а встроить счетчик/делитель. допустим поставь 2/3/5/100 вызовов этой процедуры перед выполнением программы. а про bx извините. хотелось исправить mov bx, 0 на xor bx, bx но отвлекли и я забыл достереть и дописать
     
  5. Morte

    Morte New Member

    Публикаций:
    0
    Регистрация:
    13 мар 2009
    Сообщения:
    14
    У меня ситуация следующая: мне по-любому нужен бесконечный цикл, чтобы постоянно перемещать точку на экране.

    Код (Text):
    1. MOVE_POINT:
    2.     ; Тут задержка
    3.     ; Тут обновление кадра с точкой
    4. JMP MOVE_POINT
    Во время выполнения я постоянно наблюдаю высокую загруженность процессора. Я не понимаю как реализовывается нормальный sleep() на Assembler x86. Я подозреваю, что этим занимается сама ОС, но как сообщить Windows (я под эмулятором DOS-программ свою программу запускаю, конечно) о "сне" я не понимаю.

    Вариант выполнить какую-ту операцию большое количество раз помогает для задержки обновления кадра, но загруженность естественно не спадает.
     
  6. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    ты выполняешь программу на эмуляторе однозадачной среды в многозадачной среде. операционная система считает время своего бездействия и время распределенное между задачами. когда выполняется много операций, то многозадачная среда думает, что эмулятор однозадачной среды делает полезную работу. во втором же моем примере я использую прерывание от таймера, которое срабатывает постоянно с равными промежутками времени, а на время ожидания прерывания я выполняю команду ожидания прерывания, которая говорит эмулятору, что запущенная на нем задача желает бездействовать, до внешнего события, что приводит к тому, что эмулятор корректно осуществляет ожидание относительно многозадачной среды. а процедуре прерывания можно выполнять различные действия. к примеру загрузить в один из регистров переменную счетчик, поставить бесконечный цикл на ожидание нулегого значения в этой переменной, а в прерывании изменять значение в этой переменной. тогда ход выполнения программы будет приостановлен до обнуления счетчика, но количество операций будет много меньше, отчего и загрузка будет минимальной т.к. реально задача не будет ничего делать.
     
  7. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    Это не совсем моя процедура, это "общая" процедура, написанная впервые фиг знает кем, году эдак в 1986-87 (а может и раньше. И скорее всего - кем-то из производителей VGA-карточек). Если твой эмулятор в полноэкранном режиме, то частота монитора будет как раз та, какая нужна. Сначала попробуй, даже удивишься, насколько эта задержка подходит, просто тютелька. Для тетриса можно задержку через int 15h, это как раз досовский аналог sleep.
    А вообще, попробуй запустить в дос-боксе ЛЮБУЮ программу, которая что-то выводит на экран (не консольную) - хоть тетрис, хоть демку на 256 байт, диспетчер задач покажет 50% процессорного времени у виртуальной машины... И точно так же DOS-navigator в обычной ntvdm, из-за чего собственно он и умер под виндой, тормоза неадекватные результату.
     
  8. Morte

    Morte New Member

    Публикаций:
    0
    Регистрация:
    13 мар 2009
    Сообщения:
    14
    Да...На этом и остановился, спасибо.

    UPD Нет, я поспешил:
    Ладно, лучше чувствую всё равно особо не получится сделать.

    Но есть несколько вопросов по поводу кода:
    Код (Text):
    1. cli
    2. xor ax, ax
    3. mov ds, ax          ; Где используется DS?
    Код (Text):
    1. l1:
    2. ...                 ; Что тут должно быть?  
    3. o           dw       0
    4. s           dw       0
    Тут либо пропущен какой-то jump, либо l1: должно быть после двух последних строчек.

    Код (Text):
    1. timer_proc:
    2. pushf
    3. call dword [o]
    4. ;какие-либо действия выполняемые с периодичностью ~18,2 раза в секунду
    5. continue:
    6. xor ax, ax
    7. iret
    Правильно ли я понимаю, что перед iret'ами должны быть popf'ы?

    И я толком не смог понять что делает команда HLT...
     
  9. Memphis

    Memphis New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2008
    Сообщения:
    104
    Morte
    Во время выполнения я постоянно наблюдаю высокую загруженность процессора - попробуй после MOVE_POINT: сделать не ; Тут задержка, а банальный mov ah,1 ; int 16h ;
     
  10. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    ds - сегментный регистр по умолчанию. если не указано при обращении к памяти сегмента, то это в ds
    продолжение вашей программы
    нет. я симулирую вызов оригинального вектора прерывания через длинный вызов, но int от far call отличается только дополнительным сохранением флагов. они уйдут из стека после call
    да. я чуть-чуть напутал в позапрошлом посте. не посмотрел кода. в bx должно быть 24h
     
  11. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    Никуда вы не денетесь от загруженности процессора, хватит уже страдать. Любое приложение в виртуальной машине - будет использовать 50% процессора. Больше приоритет не даст. А меньше - не даст реализация виртуальной машины.
     
  12. RMIB

    RMIB New Member

    Публикаций:
    0
    Регистрация:
    9 апр 2009
    Сообщения:
    2
    Нужна помощь после выполнения кода
    Код (Text):
    1. mov ebx,3
    2.          mov eax,5
    3.          div ebx
    в edx получается 0 и в eax 1431655767, я не могу понять почему так?
     
  13. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    У тебя Edx = 1 перед операцией деления, дельтся ведь Edx:Eax, тоесть нужно обнулить xor edx,edx.
     
  14. RMIB

    RMIB New Member

    Публикаций:
    0
    Регистрация:
    9 апр 2009
    Сообщения:
    2
    спс терь всё работает)
     
  15. Morte

    Morte New Member

    Публикаций:
    0
    Регистрация:
    13 мар 2009
    Сообщения:
    14
    FatMoon, да, я уже смирился
     
  16. Morte

    Morte New Member

    Публикаций:
    0
    Регистрация:
    13 мар 2009
    Сообщения:
    14
    С помощью прерывания INT 16H пытаюсь получить с клавиатуры (точнее из какой-то "очереди", куда должен попасть код введённого символа). Первый раз нормально, второй раз и последующие - никакой реакции.
    Код (Text):
    1. format binary
    2. use16
    3. org 100h
    4.  
    5. ; Включение видеорежима 80x25
    6. mov ax, 3
    7. int 10h
    8.  
    9. mov  ax, 0b800h
    10. mov  es, ax
    11.  
    12. c:
    13.     ; Задержка ~ полсекунды      
    14.     mov cx, 5000
    15.     l0:
    16.     mov dx, -1
    17.     l1:
    18.     dec dx
    19.     jnz l1
    20.     loop l0
    21.  
    22.     mov ah, 01h
    23.     int 16h
    24.     jz c
    25.  
    26.     xor di, di
    27.     mov ah, 0Fh
    28.     mov [ES:DI], ax
    29.    
    30. jmp c
    31.  
    32. int 20h
    В итоге первый введённый символ я вижу в левом верхнем углу, а последующие "клацканья" по клаве не дают никакого эффекта.

    Где ошибка?

    ЗЫ В отладчике (td) я проверить не смог, я не разобрался как воспроизвести ситуацию ввода какого-то символа с клавиатуры.
     
  17. twgt

    twgt New Member

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    1.494
    Morte
    Так?
    Код (Text):
    1.         mov ah, 01h
    2.         int 16h
    3.         jz c
    4.  
    5.         mov ah,00h
    6.         int 16h
    7.  
    8.         xor di, di
    9.         mov ah, 0Fh
    10.         mov [ES:DI], ax
     
  18. Morte

    Morte New Member

    Публикаций:
    0
    Регистрация:
    13 мар 2009
    Сообщения:
    14
    Нет. Мне не нужно, чтобы было ожидание ввода символа, потому что в реальной программе движется какая-то точка. Если пользователь нажмёт "вниз", то точка должна начать движение вниз, если пользователь ничего нажимать не будет, то должно продолжаться движение.
     
  19. Morte

    Morte New Member

    Публикаций:
    0
    Регистрация:
    13 мар 2009
    Сообщения:
    14
    twgt, извиняюсь, это как раз именно то, что нужно.
     
  20. Morte

    Morte New Member

    Публикаций:
    0
    Регистрация:
    13 мар 2009
    Сообщения:
    14
    Объясните, пожалуйста, один момент.
    Тут:
    Код (Text):
    1.         mov ah, 01h
    2.         int 16h
    ... проверяется "очередь" (какой-то FIFO-стек?) на наличие символа, а далее
    Код (Text):
    1.         mov ah,00h
    2.         int 16h
    ... мы этот символ снимаем с этого стека.

    Меня интересует может ли быть так, что если между проверкой статуса и, собственно, снятием, будет какой-то объёмный код, который весь за один раз операционная система выполнить не даст одной программе, а "вклинит" что-то другое, от чего последний введённый символ может измениться, и мы снимем со стека вообще другой символ?