Ensamblador

  0   1   2   3   4   5   6   7   8   9   10

2
  1. Escribir un programa que escriba el mismo carácter en las 2000 posiciones de la pantalla:
    pantalla EQU 0B800h ;Direccion física de comienzo de la pantalla ;------------------------------------------------------------------------------ ;Definición del segmento de codigo ;------------------------------------------------------------------------------ CODE SEGMENT assume cs:code START PROC mov ax,pantalla ;Cargar la dirección de la coordenada 0,0 de la mov ds,ax ;pantalla xor bx,bx ;Ponemos bx a 0 pinta_caracter: mov ds:[bx],byte ptr "V" ;Escribir el carácter en su coordenada inc bx ;En lugar de sumar 2, se incrementa 2 veces porque ;consume menos ciclos de reloj del procesador inc bx ;Cada posicion de la pantalla son 2 bytes, cmp bx,2000*2 ;por eso bx va a llegar hasta 4000 jl pinta_caracter ;Si bx<4000 volvemos a pintar otro carácter mov ax,4C00h ; int 21h ;Terminar el programa START ENDP CODE ENDS END START
  2. Hacer un programa que coja el carácter que se encuentre en la coordenada 0,0 de la pantalla en ese momento y lo copie por toda la pantalla. En los últimos 4 caracteres mostrar la palabra ETSI:
    pantalla EQU 0B800h ;------------------------------------------------------------------------------ ;Definición del segmento de codigo ;------------------------------------------------------------------------------ CODE SEGMENT assume cs:code START PROC mov ax,pantalla ;Cargar la dirección de la coordenada 0,0 de la mov ds,ax ;pantalla xor bx,bx mov dx,ds:[bx] ;Obtener el carácter de la coordenada 0,0 pinta_caracter: inc bx inc bx mov ds:[bx],dx ;Copiar el carácter obtenido por toda la pantalla cmp bx,1995*2 ;Dejamos los ultimos 4 caracteres sin rellenar jl pinta_caracter mov ds:[1996*2],byte ptr "E" ;En los ultimos 4 caracteres escribimos mov ds:[1997*2],byte ptr "T" ;nuestro mensaje mov ds:[1998*2],byte ptr "S" ; mov ds:[1999*2],byte ptr "I" ; mov ax,4C00h ; int 21h ;Terminar el programa START ENDP CODE ENDS END START
  3. Nos vemos en la necesidad ya de empezar a manejar el Turbo Debugger. No todos los programas que hagamos tienen por qué mostrar algo por la pantalla. Veremos ahora un programa que realiza la suma de los números 1+2+3+4+5+6+7+8+9+10=55=37h. La salida de esta suma se irá guardando en el acumulador (AX). Con el TD podremos ir viendo como el registro AX va aumentando hasta llegar a 37 en hexadecimal, que va a ser el equivalente a 55 en decimal. Todo lo que veremos en el TD va a estar en hexadecimal. Al principio puede parecernos un poco raro y no saber muy bien a que equivale, pero poco a poco iremos aprendiendo a pensar en hexadecimal y binario :D. Antes de nada les voy a mostrar los archivos .bat que he venido utilizando durante mi aprendizaje del ensamblador: - Para debuggear un programa puede utilizarse únicamente el programa deb.bat:
    :----------------------------------------------------------------------- : : Fichero: deb.bat : : Descripcion: : Ensamblar modulo fuente principal de un programa, crear modulo : objeto y debuggearlo. : :----------------------------------------------------------------------- : echo off if z%1 == z goto error goto check :error echo *** error: falta nombre del modulo fuente *** goto fin :check if exist %1.asm goto ensam echo *** error: fichero %1.asm no existe *** goto fin :ensam tasm /zi %1; if exist %1.obj goto mensa echo *** error en programa fuente *** goto fin :mensa tlink /v %1 echo ... creado fichero %1.obj td %1 :fin
    Este archivo de procesamiento por lotes lo que hace es ensamblar el archivo, linkarlo y por ultimo lanzar el Turbo Debugger para nuestro archivo. Claro está que todo esto puede hacerse paso por paso, pero bueno, cada uno verá lo que prefiere. Mi fichero t.bat no se diferencia en casi nada de deb.bat, la única diferencia es que en lugar de td %1 debemos poner un %1 para que lo ejecute. De esta manera t.bat lo que hace es ensamblar, linkar y ejecutar el programa. Con estos programas ya estamos preparados para hacer frente al siguiente ejemplo, para el cual veremos su resultado en el TD.
    ;------------------------------------------------------------------------------ ;Definición del segmento de codigo ;------------------------------------------------------------------------------ CODE SEGMENT assume CS:code START: xor ax,ax ; mov cx,1 ;Inicializar suma: add ax,cx ; inc cx ; cmp cx,11 ; jne suma ;Sumar 1+...+10=37h mov ax,4C00h ; int 21h ;Terminar el programa CODE ENDS END START
    El siguiente programa es algo más sofisticado y potente. La teoría la explicaremos después de ver el ejemplo.
  4. Realizar un programa que limpie la pantalla dejando el fondo azul y los caracteres rojos:
    pantalla EQU 0B800h ;------------------------------------------------------------------------------ ;Definición del segmento de pila ;------------------------------------------------------------------------------ PILA SEGMENT STACK "STACK" db 40h dup(0) PILA ENDS ;------------------------------------------------------------------------------ ;Definición del segmento extra ;------------------------------------------------------------------------------ EXTRA SEGMENT result dw 0,0 EXTRA ENDS ;------------------------------------------------------------------------------ ;Definición del segmento de codigo ;------------------------------------------------------------------------------ CODE SEGMENT assume cs:code,es:extra,ss:pila START PROC cld ;DF=0 (incrementar DI) mov ax,pantalla mov es,ax xor di,di mov ax,1C00h ;Fondo azul, caracteres rojos con intensidad ;Equivalente a: mov ax,0001110000000000b mov cx,2000 rep stosw ;Repetirlo las 2000 veces mov ax,4C00h ; int 21h ;Terminar el programa START ENDP CODE ENDS END START

    Si quisiesemos poner los atributos de otra forma sólo hay que cambiar una línea. Podríamos ponerla de la siguiente manera, por ejemplo:
    mov ax,1100001000000000b ó mov ax,0C200h

    si quisiesemos poner el fondo rojo con letras verdes.

    Teoría para entender el ejercicio:

    STOSW: Se transfiere el registro AX a la palabra ES:[DI]. DI se actualiza en dos unidades.
    Si la bandera de dirección es cero (DF=0), DI se incrementa, si DF=1, se decrementa.
    Esto lo logramos con las instrucciones CLD o STD.
    En CX hemos especificado el número de elementos de la cadena. En este caso las 2000 posiciones, son las 80x25 posiciones de la pantalla.

    Para indicar en la memoria de pantalla como queremos el fondo y los caracteres podemos hacerlo en sus 8 bits. Para indicar el carácter tenemos otros 8 bits. Cada número o letra hexadecimal equivale a un nibble (4 bits):

    código atributo (1 byte). Los bits son los siguientes:
    7 - Utilizado para indicar si el carácter parpadea o no.
    6 - Componente rojo del fondo
    5 - Componente verde del fondo
    4 - Componente azul del fondo
    3 - Intensidad en los caracteres
    2 - Componente rojo del carácter
    1 - Componente verde del carácter
    0 - Componente azul del carácter

    Como vemos en nuestro ejemplo (0001 1100 0000 0000), hemos activado el componente azul del fondo, la intensidad y el componente rojo de los caracteres.

    código carácter (1 byte): Podemos elegir de la tabla ASCII aquel carácter que prefiramos. Como carácter elegimos el 00h, que en la tabla ASCII va a equivaler a dejar el fondo sin ningún carácter. Si quiesiesemos que apareciese el carácter 'V' en el fondo pues cogeríamos el 56h. Cuando ejecutemos el programa, si queremos volver a tener nuestra pantalla como antes, basta con un un simple:
    C:\>cls

    Volveremos a tener la pantalla con letras blancas sobre fondo negro.

www.victorsanchez2.com
victorsanchez2 en gmail.com
victorsanchez2 en jabberes.org
http://www.linkedin.com/in/victorsanchez2
victorsanchez2.asc (Huella digital: 4D05 8831 CB70 5F22 D836 73FF BA0A 5C66 BBB9 AC5A)
Tf: 659 35 74 53

Valid XHTML 1.0 Transitional