2015-05-23 3 views
1

привет Почему программа работает неправильно Первый запуск за короткий промежуток времени, дисплей меняет цвет Но тогда черный цвет возвращается Программа рисует флаг, но может не правильно экран цветной графический режим сделатьКак раскрасить монитор в графическом режиме в сборе

.model small 
.stack 256 
    org 100H 
.data 
.code 
main proc 
    mov ax, @data 
    mov ds, ax   
    call graphicsmode 
    call printflag    

    mov ah,00 
    mov al,03 
    int 10h  

    mov ax,4c00h 
    int 21h 
main endp 

graphicsmode proc 
    MOV AH,00H 
    MOV AL,13H 
    INT 10H 
    ret 
graphicsmode endp 

printflag proc  
    ;print color green 
    ;-------------------------- 
    mov cx,50 ;column 
    mov dx,50 ;row   
L1: mov ah,0CH 
    mov al,2H ;color pixel   
    mov bh,00H 
    int 10h  
    inc cx 
    cmp cx,400 
    jne L1 

    mov cx,50 
    inc dx 
    cmp dx,100 
    jne L1 

    ;print color white 
    ;-------------------------- 
    mov cx,50 ;column 
    mov dx,100 ;row   
L2: mov ah,0CH 
    mov al,7H ;color pixel   
    mov bh,00H 
    int 10h  
    inc cx 
    cmp cx,400 
    jne L2 

    mov cx,50 
    inc dx 
    cmp dx,150 
    jne L2 

    ;print color red  
    ;-------------------------- 
    mov cx,50 ;column 
    mov dx,150 ;row   
L3: mov ah,0CH 
    mov al,4H ;color pixel   
    mov bh,00H 
    int 10h  
    inc cx 
    cmp cx,400 
    jne L3 

    mov cx,50 
    inc dx 
    cmp dx,200 
    jne L3 
    ret 
printflag endp 

end main 
+2

Я уверен, вы понимаете, что «int 21h» и «int 10h» являются устаревшими вызовами DOS/BIOS. Никакая современная ОС не поддерживает их ... кроме как с помощью эмуляции приглашения DOS. ПРЕДЛОЖЕНИЯ: 1) Пройдите свой код под вашим любимым отладчиком сборки («gdb» - хороший выбор на многих платформах) и убедитесь, что ваш код верен. 2) В противном случае обвините в эмуляторе подсказок DOS – paulsm4

+2

Режим 13h всего 320x200, и вы пытаетесь рисовать линии вне этого диапазона. Также первое, что вы делаете после рисования флага, - это вернуться в текстовый режим, который будет стирать то, что вы нарисовали. Таким образом, вы можете видеть это только во время его рисования, как только его готовый рисунок будет немедленно стираться. –

+0

спасибо, хорошо – ahad

ответ

1

Для режима 0x13 вы можете заполнить экран с `респ stosw» инструкции, как это:

;al = colour to use 

    mov bx,0xA000 
    mov es,bx 
    mov cx,320*200/2 
    mov di,0 
    cld 
    mov ah,al 
    rep stosw 

Если вы один пиксель за один раз, то вы d» необходимо вычислить «адрес = y * 320 + x» 64000 раз, что невероятно медленно и бессмысленно. Это также означает, что вы пишете по одному байту за раз, и это добавляет до 64000 передач по шине PCI (где вы можете вдвое сократить количество передач, делая по 2 байта за один раз, или делайте 4 байта за раз).

Использование функции BIOS намного хуже. Он начинается с прерывания (которое происходит медленно), а затем имеет целую кучу ветвей, чтобы выяснить, какую функцию вы хотите, затем имеет еще одну группу ветвей, чтобы выяснить, какой режим видео вы используете, и в конце концов, у него есть все проблемы «одного пикселя за раз» (см. выше).

В принципе; ваш код имеет 2 проблемы - его нужно перепроектировать/переписать, и у него есть ошибки. Если вы найдете и исправите ошибки, их все равно придется перепроектировать/переписать; поэтому нет смысла находить и исправлять ошибки.

+1

Ваш ответ имеет 3 проблемы! Мы используем 'cld' для правильного выполнения этого примитива строки. Использование 'stosw' означает половину счетчика. ** ** 640000 ** расчет адресов немного преувеличен. –

+2

@ user3144770: D'oh - вы правы. Я исправил ошибки и избавился от ошибочного дополнительного нуля на 64000 :-) – Brendan

Смежные вопросы