Сборка (TASM) прорисовки пикселя путем записи в память

Мой старый код напечатал строку в режиме 13h с int 10h, Я пытался изменить это с помощью int 10h в записи в память, но по какой-то причине это не работает. Я не знаком с записью в памяти, поэтому я не мог догадаться, в чем проблема.

Вот новый код:

proc PrintLine
;prints a line
;1.length 
;2.colour
;3.x
;4.y
push bp
mov bp,sp
push ax
push bx
push cx
push dx
push si
mov cx,[bp+10];leangth
mov dx,[bp+4];y
mov al,[bp+8];colour
mov si,[bp+6];x
xor bx,bx
pl:
    push si
    push dx
    push ax
    call PrintPixel
loop pl
pop si
pop dx
pop cx
pop bx
pop ax
pop bp
ret 8
endp PrintLine
proc PrintPixel
;print a pixel through writing into memory
;input:
;1.x
;2.y
;3.colour
;output:
;none
push bp
mov bp,sp
push ax
push bx
push cx
push dx
push di
mov ax,0A000h
mov es,ax
mov ax,[bp+6];y
mov bx,[bp+8];x
mov dl,[bp+4];colour
mov cx,320
mul cx;each line is 320 pixles ax is the number of lines
add ax,bx;bx is the place on the line
mov di,ax
mov [es:di],dl
mov ax, @data  
mov ds, ax
pop di
pop dx
pop cx
pop bx
pop ax
pop bp
ret 6
endp PrintPixel

Это старый код с int 10h:

proc PrintLine
;prints a line
;1.length 
;2.colour
;3.x
;4.y
push bp
mov bp,sp
push ax
push bx
push cx
push dx
push si
mov cx,[bp+10];leangth
mov dx,[bp+4];y
mov al,[bp+8];colour
mov si,[bp+6];x
mov ah,0ch
xor bx,bx
pl:
    push cx
    mov cx,si
    int 10h
    inc si
    pop cx  
loop pl
pop si
pop dx
pop cx
pop bx
pop ax
pop bp
ret 8
endp PrintLine

1 ответ

Решение

Ваша процедура PrintPixel имеет 2 важные проблемы.

  • Хотя вы сохраняете много регистров, вы также используете ES сегментный регистр, который вы вообще не сохраняете! Почему вы тогда повторно инициализируете DS Сегментный регистр является загадкой.

  • Потому что вы рассчитываете адрес смещения видео, используя mul cx вы получили продукт меч в DX:AX, но вы сохранили цвет пикселя в DL, Это может привести только к черным пикселям! Они там, но вы их не видите.

Поскольку этот вопрос был помечен x86, вы можете использовать универсальный imul инструкция:

push bp
mov  bp, sp
push ax
push bx
push ds
mov  ax, 0A000h
mov  ds, ax
mov  bx, 320      ; Bytes per line in mode 13h
imul bx, [bp+6]   ; y
add  bx, [bp+8]   ; x
mov  al, [bp+4]   ; colour
mov  [bx], al     <-- No need for any segment override prefix!
pop  ds
pop  bx
pop  ax
pop  bp
ret  6

Видите, насколько чище и короче это стало?


С переходом к использованию BIOS WritePixel больше не нужно очищать процедуру PrintLine. Больше не нужно, например, xor bx, bx,
Знаете ли вы, что вы можете нажать операнд памяти напрямую? Сделав это, вы сохраните много инструкций!

 push bp
 mov  bp, sp
 push cx
 mov  cx, [bp+10]       ; length
pl:
 push word ptr [bp+6]   ; x
 push word ptr [bp+4]   ; y
 push word ptr [bp+8]   ; colour
 call PrintPixel
 loop pl
 pop  cx
 pop  bp
 ret  8
Другие вопросы по тегам