Ensamblador
8
- El siguiente programa le pide al usuario la confirmación de si
desea continuar y dependiendo de la respuesta se hará una cosa u otra:
;------------------------------------------------------------------------------
;Programa que le pregunta al usuario si desea continuar o no hasta que se pulse
;la tecla 'N' o 'n'
;------------------------------------------------------------------------------
cr equ 13 ;retorno de carro
lf equ 10 ;alimentacion de linea
;------------------------------------------------------------------------------
;Definicion del segmento de datos
;------------------------------------------------------------------------------
DATOS SEGMENT
DeseaContinuar db cr,lf,'Desea continuar? S/N: '
db'$'
continuando db ' Continuando...',cr,lf
db'$'
LetraErronea db ' La tecla pulsada es incorrecta.',cr,lf
db'$'
DATOS ENDS
;------------------------------------------------------------------------------
;Definicion del segmento de pila
;------------------------------------------------------------------------------
PILA SEGMENT STACK "STACK"
db 40h dup(?)
PILA ENDS
;------------------------------------------------------------------------------
;Definicion del segmento de codigo
;------------------------------------------------------------------------------
CODE SEGMENT
assume CS:code, DS:datos, SS:pila
START:
mov ax,datos
mov ds,ax
jmp continuar ;Saltamos a la etiqueta CONTINUAR
INICIO:
lea dx,continuando ;
mov ah,9 ;
int 21h ;Mensaje de que seguimos en el programa
jmp continuar ;Salto para preguntar si se desea continuar
ERROR:
lea dx,LetraErronea ;
mov ah,9 ;Mensaje de que la letra introducida
int 21h ;no es correcta
CONTINUAR:
lea dx,DeseaContinuar ;
mov ah,9 ;
int 21h ;Mostrar pregunta para ver si desea continuar
mov ah,1 ;Esperar a que se pulse una tecla
int 21h ;y mostrarla por pantalla
cmp al, 'S' ;
je inicio ;
cmp al, 's' ;
je inicio ;Desea continuar
cmp al, 'N' ;
je salir ;
cmp al, 'n' ;
je salir ;No desea continuar, terminamos
jmp error ;La tecla pulsada no es 'S', 's', 'N' ni 'n'
;Se va a mostrar un mensaje de error. Saltamos
;a la etiqueta ERROR
salir:
mov ax, 4C00h
int 21h
CODE ENDS
END START
- Este programa cambia el color de fondo de una posición determinada de pantalla.
Si se ejecuta varias veces seguidas veremos como cambia de blanco a negro y viceversa:
PANTALLA equ 0B800h
;------------------------------------------------------------------------------
;Definicion del segmento de pila
;------------------------------------------------------------------------------
PILA SEGMENT STACK "STACK"
db 40h dup(0)
PILA ENDS
;------------------------------------------------------------------------------
;Definicion del segmento de codigo
;------------------------------------------------------------------------------
CODE SEGMENT
assume CS:code, SS:pila
START:
mov ax,PANTALLA
mov ds,ax
mov bx,(80*24+5)*2+1 ;Ultima linea, caracter 5
;Utilizamos el '+1' para acceder
;directamente al fondo
cmp byte ptr [bx],07h ;Vemos si el fondo es negro
jz CambiaFondo
mov byte ptr [bx],07h ;Si no es negro lo ponemos
jmp fin
CambiaFondo:
mov byte ptr [bx],70h ;Ponemos el fondo blanco
fin:
mov ax,4C00h
int 21h
CODE ENDS
END START
- Otro programa .COM (no os olvideis de compilar con las banderas antes mencionadas). En
este caso se trata de mostrar las letras V y S con un intervalo de medio segundo, siendo una
letra roja y la otra azul:
PANTALLA equ 0b800h
ROJO equ 4
LETRA_ROJA equ 'V'
LETRA_AZUL equ 'S'
AZUL equ 1
;------------------------------------------------------------------------------
;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
;
; in:
; out:
; machaca:
; make: Hace que se intercambien las letras V y S cada medio segundo en
; colores diferentes.
;
;------------------------------------------------------------------------------
letras proc far
push ax ;
push es ;
push di ;Guardamos los registros en la pila
cli ;Inhabilitar las interrupciones
mov al,0Ch ;
out 70h,al ;
in al,71h ;Leer el RTC
mov ax,pantalla
mov es,ax
mov di,79*2 ;Esquina superior derecha
mov ax,es:[di] ;Guardamos en AX lo que hay en la esquina
cmp ah,AZUL ;Si era azul ahora debemos mostrar
je muestra_v_rojo ;la 'V' de color rojo
mov ah,AZUL
mov al,LETRA_AZUL
mov es:[di],ax ;Guardar en ES:[DI] que hemos puesto la letra
;de color azul
jmp fin ;Terminar el procedimiento
muestra_v_rojo:
mov ah,ROJO
mov al,LETRA_ROJA
mov es:[di],ax ;Guardar en ES:[DI] que hemos puesto la letra
;de color rojo
fin:
mov al,20h ;
out 20h,al ;
out 0A0h,al ;EOI al maestro y al esclavo
sti ;Habilitar las interrupciones
pop di ;
pop es ;
pop ax ;Recuperar los registros
iret
letras endp
;------------------------------------------------------------------------------
; instalar
;
; in:
; out:
; machaca: ax, dx, es
; make: Instala el programa dejandolo residente
;
;------------------------------------------------------------------------------
instalar proc
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 ;Dejar residente
instalar endp
CODE ENDS
END START
- El siguiente ejercicio de examen nos pide conocer la instrucción scasb.
Hallar cuál es el valor de AX tras la instrucción NOP:
;------------------------------------------------------------------------------
;Definicion del segmento de datos
;------------------------------------------------------------------------------
DATOS SEGMENT
Cadena1 db 50 dup(0)
Cadena2 db 50 dup(?)
DATOS ENDS
;------------------------------------------------------------------------------
;Definicion del segmento de pila
;------------------------------------------------------------------------------
PILA SEGMENT STACK "STACK"
db 40h DUP(0)
PILA ENDS
;------------------------------------------------------------------------------
;Definicion del segmento de codigo
;------------------------------------------------------------------------------
CODE SEGMENT
assume cs:code,ds:datos,ss:pila
START PROC
;Inicializamos los registros de segmento
mov ax,datos
mov ds,ax
mov ax,pila
mov ss,ax
xor ax,ax
mov cx,10h
lea si,Cadena1
lea di,Cadena2
otro:
push ds
inc ax
pop es
scasb
loop otro
nop ;AX=10h, SI=0, DI=42h
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
- Otro ejercicio como el anterior, pero usando la instrucción repne.
Recordar que la instrucción LOOP primero decrementa y despues compara CX con 0,
así que cuidado con este ejercicio:
;------------------------------------------------------------------------------
;Definicion del segmento de datos
;------------------------------------------------------------------------------
DATOS SEGMENT
Cadena1 db 50 dup(0)
Cadena2 db 50 dup(?)
DATOS ENDS
;------------------------------------------------------------------------------
;Definicion del segmento de pila
;------------------------------------------------------------------------------
PILA SEGMENT STACK "STACK"
db 40h DUP(0)
PILA ENDS
;------------------------------------------------------------------------------
;Definicion del segmento de codigo
;------------------------------------------------------------------------------
CODE SEGMENT
assume cs:code,ds:datos,ss:pila
START PROC
;Inicializamos los registros de segmento
mov ax,datos
mov ds,ax
mov ax,pila
mov ss,ax
xor ax,ax
mov cx,10h
lea si,Cadena1
lea di,Cadena2
otro:
push ds
inc ax
pop es
repne scasb
loop otro
nop
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
- Hallar cual es el contenido de las posiciones de memoria: 1000, 1001, 1002 y
1003 tras la ejecucion del bucle:
;------------------------------------------------------------------------------
; Ejercicio 1: examen ETCII - 12/02/96
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;Definicion del segmento de codigo
;------------------------------------------------------------------------------
CODE SEGMENT
assume CS:code
START:
;Inicializar
mov byte ptr ds:[1000h],0
mov byte ptr ds:[1001h],0
mov byte ptr ds:[1002h],0
mov byte ptr ds:[1003h],0
mov si,1000h
mov cx,4
l1:
add [si],si
inc si
loop l1
mov ax,4C00h
int 21h
CODE ENDS
END START
- Hallar el contenido de SI tras la ejecución de los bucles:
;------------------------------------------------------------------------------
; Ejercicio: examen ETCII - 12/02/96
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;Definicion del segmento de codigo
;------------------------------------------------------------------------------
CODE SEGMENT
assume CS:code
START:
mov si,0
mov cx,4
L2: push cx
mov cx,100h
L1: dec cx
inc si
loop l1
pop cx
loop l2
mov ax,4C00h
int 21h
CODE ENDS
END START
|
|