Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [Assembler]Графика


Автор: Vladao 1.2.2008, 14:05
Ребят, привет!smile 
На вашем форуме в первый раз, т.к. своими силами не могу одолеть эту прогу.  Данная программа по ассемблеру выводит польский флаг и по стрелкам "Вверх"/"Вниз" передвигает его по экрану в соответствующих направлениях. Проблема состоит в том, что когда я нажимаю другие клавиши, программа виснет и далее не воспринимает др.клавиши, т.е. стрелки "Вверх"/"Вниз". Я не знаю как исправить сей факт, а зачот висит всё блин...:(  Прошу вашей помощи, спасибо!
Код

;Рисование флага+движение (быстрая графика) 
                     
                     ;директивы сегментов
        .model small ;модель памяти
        .stack 100h ;определение стека,его размер
        .data ;определение сегмента данных
        x    dw    230
    y0    dw    150
    hi    dw    50
    w    dw    25
    yc    dw    ?
    color    db    0
     increm    dw    0
;12-red
;15-white

;Макрос настройки цветового регистра reg на цветовой оттенок rgb

nastr        macro    reg,rgb
        mov    ax,1000h
        mov    bh,rgb 
        mov    bl,reg
        int    10h
endm

;Процедура записи значений во внутренние регистры адаптера через порты (адресный и данных)
;prt - номер адресного порта,nreg - номер регистра, val - значение

ports        macro    prt,nreg,val
        mov    dx,prt
        mov    al,nreg
        out    dx,al
        inc    dx
        mov    al,val
        out    dx,al
endm

;Макрос рисования горизонтальной линии непосредственно в видеопамяти
;xl,yl,len,col - то же самое, что и ранее для BIOS

adgline        macro    xl,yl,len,col
        local    beg
        mov    cx,len        ;Line length To CX
        xor    si,si        ;SI=0
        mov    al,80        ;AL=80
        mul    yl        ;AL=80*Y0 (bytes)
        mov    dx,ax        ;AX->DX
        mov    ax,xl        ;X0->AX
        mov    bl,8        ;8->BL
        div    bl        ;X0=X0 / 8 (bytes)
        xor    ah,ah        ;AH=0
        add    dx,ax        ;DX=Y0*80+X0 (bytes) = startbyte
        mov    bx,dx        ;DX->BX
beg:        ports    3c4h,2,0fh ;регистр Адреса Указателя Последовательности доступен через порт, а 2-это индекс регистра Маскирования Растра
        ports    3ceh,8,0ffh ; регистр Графического Контроллера доступен через порт, а 8 - это индекс регистра Битовая Маска
        mov    byte ptr es:[bx][si],00000000b ; si-смещение области данных,где находится пиксельная ячейка
        ports    3c4h,2,col 
        mov    byte ptr es:[bx][si],0ffh
        inc    si    
        loop    beg
    endm    


;макрос консольной приостановки до нажатия клавиши
;после нажатия клавиши два байта поступают в регистр АХ;
;макрос может использоваться для очистки консольного буфера
stop    macro
    mov    ah,0
    int    16h
    endm


        .code ;определение сегмента кода
        mov     ax,@data; Инициализация сегментных регистров
        mov     ds,ax 
    mov    ax,0a000h ;адрес видеобуфера
    mov    es,ax
    mov    ah,0 ;функция 0 (ah=0)устанавливает видео-режим
    mov    al,12h ;номер режима
    int    10h ;обращение к видео-BIOS через прерывание int 10h
    nastr    8,4
    nastr    0,9;   ->     001 001
    stop;               RGB rgb
    call    draw
    
    
again:    mov    ah,1; функция прерывания int 16h для чтения символа с клавиатуры
    int    16h            
    jz    again
    cmp    ah,1    
    jne    m3
    jmp    endprog        
m3:    cmp    ah,50h        ;down arrow Code
    mov    increm,10
    je    m2
    cmp    ah,72        ;up arrow Code
    mov    increm,-10
    jne    again
m2:     mov     color,0
     call     draw
     add     y0,50
     call     draw
     add     y0,-50
     mov     ax,increm
     add     y0,ax
     mov     color,15    
     call     draw
     mov     color,12
     add     y0,50
     call     draw
     add     y0,-50
     stop
     jmp     again

proc        draw        
        mov    ax,y0
        mov    yc,ax
        mov    cx,hi    
loopy:        push    cx
        adgline    x,yc,w,color
        inc    yc
        pop    cx
        loop    loopy
        ret
         endp
        
endprog:
    nastr    4,8
    mov    ax,3
    int    10h
    stop
    mov    ax,4c00h ;Вызов функции завершения программы
    int    21h
end


Автор: JAPH 1.2.2008, 15:58
Функция 1 прерывания 16h позволяет проверить наличие символа в буфере: ZF=1, если символа нет.
Функция 0 получает символ из буфера.

У вас идёт проверка на наличие символа. Пусть в буфере хранится символ 't', тогда прога непрерывно проверяет, есть ли символ в буфере, не забирая его оттуда. Бесконечный цикл.

По-моему, вызов stop должен находиться не в строке 112, а между 89 и 90ой, если не вместо цикла в строках 87-89.

Автор: Vladao 1.2.2008, 22:26
JAPH, спасибо вам большое, ваш совет действительно помог и всё заработало! Благодарен от души!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)