Ensamblador

  0   1   2   3   4   5   6   7   8   9   10

5
  1. Realizar un programa que guarde el estado de la pantalla con todos sus caracteres, después rellene toda la pantalla con '*' y por último vuelva a dejar la pantalla como estaba:
    ;------------------------------------------------------------------------------ ;Programa que guarda el estado de la pantalla con todos sus caracteres, despues ;rellena toda la pantalla con '*' y por ultimo vuelve a dejar la pantalla como ;estaba ;------------------------------------------------------------------------------ PANTALLA equ 0B800h ;------------------------------------------------------------------------------ ;Definicion del segmento de datos ;------------------------------------------------------------------------------ DATOS SEGMENT pantalla_bak db 80*25*2 DUP(?) ;Reservar una variable para guardar toda la ;informacion de la pantalla DATOS ENDS ;------------------------------------------------------------------------------ ;Definicion del segmento de pila ;------------------------------------------------------------------------------ PILA SEGMENT STACK "STACK" db 40h dup(0) PILA ENDS ;------------------------------------------------------------------------------ ;Definicion del segmento extra ;------------------------------------------------------------------------------ EXTRA SEGMENT RESULT DW 0,0 EXTRA ENDS ;------------------------------------------------------------------------------ ;Definicion del segmento de codigo ;------------------------------------------------------------------------------ CODE SEGMENT assume DS:datos, CS:code, SS:pila START: mov ax,PANTALLA mov ds,ax xor si,si mov ax,datos mov es,ax lea di,pantalla_bak ;Apuntar a la variable mov cx,80*25*2 ;Numero de bytes que tenemos que copiar cld ;Direccion para incrementar DI y SI backup: movsb ;Mover el contenido de la direccion de memoria apuntada ;por SI a la apuntada por DI, en este caso la variable ;pantalla_bak loop backup mov cx,80*25 ; xor bx,bx ; mov al,'*' ; mov ah,70h ;Llenar la pantalla de '*' llena: mov [bx],ax inc bx inc bx loop llena push ds ; push es ; pop ds ; pop es ;Intercambiar DS y ES xor di,di lea si,pantalla_bak xor ah,ah ; int 16h ;Esperar a que se pulse una tecla mov cx,4000 ;Los 4000 bytes de la pantalla restaura: ; movsb ; loop restaura ;Volver a dejar la pantalla como al principio mov ax,4C00h int 21h CODE ENDS END START
  2. Realizar un programa que devuelva la primera posición en que se ha encontrado un carácter dado:
    ;------------------------------------------------------------------------------ ;Devuelve la primera posicion en que se ha encontrado el caracter a buscar ;------------------------------------------------------------------------------ CARACTER equ 'v' ;------------------------------------------------------------------------------ ;Definicion del segmento de datos ;------------------------------------------------------------------------------ DATOS SEGMENT mensaje db "www.victorsanchez2.net" msg_caracter db "El caracter: " msg_posicion db "Se encuentra en la posicion: " DATOS ENDS ;------------------------------------------------------------------------------ ;Definicion del segmento de pila ;------------------------------------------------------------------------------ PILA SEGMENT STACK "STACK" db 40h DUP(0) PILA ENDS ;------------------------------------------------------------------------------ ;Definicion del segmento extra ;------------------------------------------------------------------------------ EXTRA SEGMENT RESULT DW 0,0 EXTRA ENDS ;------------------------------------------------------------------------------ ;Definicion del segmento de codigo ;------------------------------------------------------------------------------ CODE SEGMENT assume cs:code,ds:datos,es:extra,ss:pila START PROC ;Inicializamos los registros de segmento mov ax,datos mov ds,ax mov ax,pila mov ss,ax mov ax,extra mov es,ax ;Limpiamos la pantalla mov ax,0B800h ;En esta direccion comienza la memoria de video mov es,ax ;Lo cargamos en el segmento extra xor di,di ;Ponemos DI=0 mov cx,80*25 ;80 lineas x 25 columnas xor al,al ;0=" " Rellenar la pantalla con blancos mov ah,0Fh ;Fondo negro, letras blancas rep stosw lea si,mensaje ;Cargar el mensaje donde buscaremos mov al,CARACTER ;Cargar el caracter a buscar mov cx,22 ;Longitud maxima para buscar (longitud de 'mensaje') call busca_fin ;Buscar la posicion en que se encuentra el CARACTER mov ax,0B800h ; mov es,ax ;Colocarnos al inicio de la memoria de video add cl,30h ;Preparar CL para mostrar el caracter por pantalla push cx ;Guardarlo para recuperarlo despues mov di,(80*2)*2 ;Colocarnos en la segunda fila lea si,mensaje ;Colocar el offset de mensaje en si mov cx,22 ;Total de caracteres de mensaje call pinta ;Mostrarlo por pantalla mov di,(80*4)*2 ;Nos colocamos en la cuarta fila lea si,msg_caracter ;Cargar el offset mov cx,13 ;Total de caracteres de mensaje call pinta ;Mostrarlo por pantalla mov di,(80*4+13)*2 ;Colocarnos al final del msg_caracter mov byte ptr es:[di],CARACTER ;Mostrar el CARACTER por pantalla mov di,(80*5)*2 ;Ponernos en la quinta fila lea si,msg_posicion ;Cargar el offset mov cx,29 ;Total de caracteres de mensaje call pinta ;Mostrarlo por pantalla mov di,(80*5+29)*2 ;Colocarnos al final del msg_posicion pop cx ;Recuperar la posicion en que se encontraba CARACTER mov es:[di],cl mov ax,4C00h ; int 21h ;Terminar el programa START ENDP ;------------------------------------------------------------------------------ ; busca_fin ; ; in: AL contiene el caracter que debemos buscar ; SI contiene la cadena que debemos buscar ; out: En CX se guarda la posicion donde se ha encontrado el caracter ; machaca: CX ; make: Devuelve en CX la primera posicion donde se ha encontrado el caracter ; dado en AL ;------------------------------------------------------------------------------ busca_fin proc near push di push dx push es push si push ax mov ax,ds ; mov es,ax ; mov di,si ;Copiar DS:SI en ES:DI mov dx,cx ;Copiar el limite en otro registro cld ;Direccion incremental pop ax ;Recuperar el caracter que nos han pedido push ax ;Guardarlo en la pila para no perderlo repnz scasb ;Buscar el caracter pedido sub dx,cx ;Calcular la longitud mov cx,dx ;Guardar la longitud en CX pop ax pop si pop es pop dx pop di ret busca_fin endp ;------------------------------------------------------------------------------ ; pinta ; ; in: SI contiene el offset del mensaje a mostrar ; DI contiene la direccion donde se ira mostrando el mensaje ; CX contiene el numero de iteraciones a realizar ; out: ; machaca: CX ; make: Muestra por pantalla el mensaje dado ;------------------------------------------------------------------------------ pinta proc near push ax push si push di mov ah,0Fh ;Fondo negro y letras blancas pintar: ; mov al,[si] ; mov es:[di],ax ; inc si ; inc di ; inc di ; loop pintar ;Mostrarlo por pantalla pop di pop si pop ax ret pinta endp CODE ENDS END START
  3. Hacer un programa que muestre la sucesión de códigos ASCII en la esquina superior derecha de la pantalla, intercambiando los caracteres cada medio segundo. Este programa ya es algo más complejo que los anteriores ya que empezamos a trabajar con programas residentes y el RTC. Os recomiendo que aprendais bien las características de los programas residentes y programación del RTC antes de intentar comprender este ejercicio por completo. Este tipo de ejercicios van un nivel más allá, y si de verdad no comprendeis bien este tipo de ejercicios es mejor que os cojais libros, apuntes o lo que sea y lo domineis con soltura.
    Un comando que os puede servir de ayuda es:
    MEM /C
    Con este podemos saber los programas que hay residentes en nuestra memoria. Al escribir esto veremos como aparece el programa de nombre ASCII, que ocupa 0,4K.
    Para ensamblar y ejecutar este programa, al ser .COM, hay que hacerlo con unas banderas distintas:
    C:\>tasm archivo
    C:\>tlink /t archivo
    C:\>archivo
    ;------------------------------------------------------------------------------ ;Programa que muestra la sucesion de codigos ASCII en la esquina superior ;derecha de la pantalla, intercambiando los caracteres cada medio segundo ;------------------------------------------------------------------------------ PANTALLA equ 0b800h ;------------------------------------------------------------------------------ ;Definicion del segmento de codigo ;------------------------------------------------------------------------------ CODE SEGMENT assume CS:code org 100h ;Dejar las 100h primeras posiciones para el PSP START: jmp instalar ;Bifurcar a la rutina de instalacion letras proc far push ax ; push es ; push di ;Guardamos los registros en la pila mov al,0Ch ; out 70h,al ; in al,71h ;Leer el RTC mov ax,PANTALLA mov es,ax mov di,79*2 mov ax,es:[di] ;Guardamos en AX lo que hay en la esquina inc al ;Pasamos al siguiente caracter mov es:[di],ax ;Lo mostramos por pantalla cli ;Inhabilitar las interrupciones mov al,20h out 20h,al out 0A0h,al sti ;Habilitar las interrupciones pop di ; pop es ; pop ax ;Recuperar los registros iret letras endp instalar proc far cli ;Inhabilitar las interrupciones xor ax,ax ; mov es,ax ;Poner a 0 ES mov es:[70h*4],offset letras ;Guardar el offset mov es:[70h*4+2],cs ;y el segmento de la rutina in al,0A1h ;Leer el PIC esclavo and al,11111110b ; out 0A1h,al ;Activamos IR0 in al,21h ;Leer el PIC maestro and al,11111011b ; out 21h,al ;Activado mov al,0Ah ;Vamos a escribir en el registro A del RTC out 70h,al ; mov al,2Fh ;Los simbolos se intercambian cada medio segundo out 71h,al ;Lo indicamos en el registro A del RTC mov al,0Bh ;Vamos a escribir en el registro B del RTC out 70h,al in al,71h or al,01000000b ; out 71h,al ;Activamos las interrupciones periodicas sti ;Habilitar las interrupciones lea dx,instalar int 27h instalar endp CODE ENDS END START
  4. Algo muy importante es el programa que sirve para desinstalar y restaurar todo lo que hizo el programa anterior. Si no lo hacemos seguirá mostrándose la sucesión de los caracteres ASCII mientras mantengamos encendido el ordenador. Después de ensamblar y ejecutar el programa con:
    C:\>tasm /zi archivo
    C:\>tlink /v archivo
    C:\>archivo
    Este programa no es .COM, por lo tanto usamos las banderas habituales. Después de ejecutarlo, si volvemos a escribir "MEM /C" veremos que nuestro programa ha desaparecido, ya no se encuentra residente en memoria.
    ;------------------------------------------------------------------------------ ;Desactiva las interrupciones periodicas del RTC y elimina el programa anterior ;de la memoria. ;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------ ;Definicion del segmento de pila ;------------------------------------------------------------------------------ PILA SEGMENT STACK "STACK" DB 40h dup(0) PILA ENDS ;------------------------------------------------------------------------------ ;Definicion del segmento extra ;------------------------------------------------------------------------------ EXTRA SEGMENT RESULT DW 0,0 EXTRA ENDS ;------------------------------------------------------------------------------ ;Definicion del segmento de codigo ;------------------------------------------------------------------------------ CODE SEGMENT ASSUME CS:CODE,SS:pila START PROC FAR call desinstalar mov ax,4C00h ; int 21h ;Terminar el programa START ENDP ;------------------------------------------------------------------------------ ; desinstalar ; ; in: ; out: ; machaca: ; make: Desinstala las interrupciones periodicas (PIE), desconecta la ; interrupcion del RTC al PIC esclavo, restaura los vectores de ; interrupcion y desinstala el programa residente ; ;------------------------------------------------------------------------------ desinstalar PROC push ax push es push ds cli ;Inhabilitar las interrupciones ;Antes de proceder a desinstalarlo comprobamos si existe cmp word ptr es:[70h*4],0 je FIN mov al,0Bh ;Registro B del PIC out 70h,al ; and al,10111111b ; out 71h,al ;Deshabilitamos las interrupciones periodicas (PIE) in al,0A1h ;Leer el PIC esclavo OR al,00000001B ; out 0A1h,al ;desconectamos la interrupcion del RTC al PIC esclavo ;Restaurar los vectores de interrupcion xor ax,ax mov es,ax mov ax,es:[70h*4+2] ;Copia en DS el segmento de codigo del mov ds,ax ;programa a desinstalar xor ax,ax mov es:[70h*4],ax ;Poner el offset a 0 mov es:[70h*4+2],ax ;Poner CS a 0 ;Desinstalar el programa residente mov ax,ds:[2Ch] ; mov es,ax ; mov ah,49h ; int 21h ;Desinstalar el PSP mov ax,ds ; mov es,ax ; mov ah,49h ; int 21h ;Desinstalar CS sti ;Habilitar las interrupciones FIN: pop ds pop es pop ax ret desinstalar ENDP CODE ENDS END START

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