hoy experimentaremos a imprimir en el modo grafico en assembler en emu8086
un ejemplo basico para entender como funciona
Programa para imprimir la letra a en el modo grafico emu8086
; si queremos modificar la direccion de pantalla es B800 contiene 2 bytes
; B800; 2 bytes (Caracter,Color)
org 100h
mov ax,0b800h; direccionando a memoria de pantalla 0b800h
mov es,ax; ponemos al segmento extra para poder acceder
mov es:[0],65; imprimimos el caracter A su valor en codigo ascii es 65 en la memoria de pantalla
ret
ejecutamos en emu
(https://i.ibb.co/BjW0Ps1/etnedenr3.jpg)
Ahora practiquemos un poco mas
nuestra zona de memoria de la pantalla es lineal, va desde el 1 hasta el 2000 linealmente, cada direccion de memoria se expresa en hexadecimal
tendriamos algo parecido a esto
; zona de memoria es una especie de matriz o vector linea 0 ---------- 80
81--------- 160
161-------- 240
241-------- 320 (2000 caracteres en total)
ahora para practicar imprimiremos una cadena de caracteres A
Imprimir caracteres A --------------------->
<---------------------A
org 100h
mov bx,0
mov cx,3 ; repetiremos 3 veces a->
; <-a
mov ax,0b800h; memoria de pantalla
ciclo: ; este es el ciclo global que imprimira ambas lineas
push cx
mov bx,contadord
mov cx,80; son 80 caracteres por linea que debemos imprimir lo guardamos en cx para repetir 80 veces
imprimirder: ; ciclo que imprime a la derecha
mov es,ax; movemos al segmento extra
mov es:[bx],65; imprimimos a en el indice 0
;mov es:[bx+320],65
;mov es:[bx+640],65
add bx,2
loop imprimirder
add contadord,320
pop cx
push bx
push cx
mov bx,contadori
mov cx,80
imprimirizq: ; ciclo que imprime a la izquiera
mov es:[bx],65
sub bx,2
loop imprimirizq
add contadori,320
pop cx
pop bx
loop ciclo
ret
contadord dw 0h ;iniciamos la primera linea en la direccion 0h para que empiece a imprimir desde ahi
contadori dw 318 ;iniciamos en la segunda fila 320-2 si tomamos en cuenta que es una direccion lineal
resta dw 2h ; utilizaremos la variable para el decremento
viendo su ejecucion en emu8086
(https://i.ibb.co/vQzj774/etnedenr4.jpg)
el modo de pantalla es de 80*25
entendiendo el funcionamiento cada posicion seria
Para practicar un poco mas, haremos una impresion de caracteres primero hacia abajo y luego hacia arriba
org 100h
mov ax,0b800h
mov es,ax
;mov bx,0
mov cx,3
inccolumna:
push cx
push bx
mov bx,posicionx
mov cx,25; repetir 2 veces columna
abajo:
mov es:[bx],65
;mov es:[bx+1],24h
add bx,160
loop abajo
pop bx
pop cx
push cx
push bx
mov cx, 25
mov bx,posiciony
arriba:
mov es:[bx+2],65
sub bx,160
loop arriba
pop bx
pop cx
add posicionx,4
add posiciony,4
loop inccolumna
ret
x dw 0
posicionx dw 0h
posiciony dw 3840
como ven lo unico que cambia es el incremento, antes incrementabamos en 1 espacio, ahora añadimos +160 caracteres para imprimir en la siguiente linea, o decrementamos -160 para subir por la memoria de pantalla
movemos en CX el valor de 25 porque solo hay 25 lineas hacia abajo
ejecutemos en emu
ejecutemos
(https://i.ibb.co/j6zSMKg/etnedenr5.jpg)
por ultimo les dejo un codigo que imprime las dos filas en direcciones contrarias al mismo tiempo
org 100h
mov ax,0b800h
mov es,ax
;mov bx,0
mov cx,3
push ax
mov ax, posiciony ;inicializar resto
mov resto,ax
pop ax
inccolumnadoble:
push cx
mov bx,posicionx
mov cx,25; repetir 2 veces columna
abajo:
;mov ax,posiciony
; imprimir caracter hacia abajo
mov es:[bx],65
;mov es:[bx+1],24h
add bx,160
; imprimir caracter hacia arriba
push bx
mov bx,resto
mov es:[bx+2],65
sub resto,160
pop bx
loop abajo
pop cx
add posicionx,4 ; incrementar posicionx en 4 para siguiente columna
push ax ; copiar la direcion de posicionx y aumentar 3840 + 4
mov ax,posicionx
mov resto,ax
pop ax
add resto,3840
loop inccolumnadoble
ret
x dw 0
posicionx dw 0h
posiciony dw 3840
resto dw 0
a modo de curiosidad mario bros fue escrito en assembler
Excelente aporte. Muchas gracias por compartir ^-^)
~ DtxdF