Documentos de Académico
Documentos de Profesional
Documentos de Cultura
php
1
Escribir un programa en ensamblador que muestre un mensaje por pantalla mediante
interrupciones:
;------------------------------------------------------------------------------
;Definicion del segmento de datos
;------------------------------------------------------------------------------
DATOS SEGMENT
DATOS ENDS
;------------------------------------------------------------------------------
;Definicion del segmento de codigo
;------------------------------------------------------------------------------
CODE SEGMENT
assume cs:code,ds:datos
START PROC
mov ax,datos ;
mov ds,ax ;Inicializar
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
;------------------------------------------------------------------------------
;Definicion del segmento de datos
;------------------------------------------------------------------------------
DATOS SEGMENT
saludo db "Hola mundo!!!"
DATOS ENDS
;------------------------------------------------------------------------------
;Definicion del segmento de pila
;------------------------------------------------------------------------------
PILA SEGMENT STACK "STACK"
DB 40 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
;Fin de las inicializaciones
;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. Esto equivale a mov di,0, pero
;xor di,di consume 3 ciclos de reloj y con mov 4
mov cx,80*25 ;El tama�o total es 2000 (80 lineas x 25 columnas)
mov ax,0B800h
mov es,ax
mov si,offset saludo
mov di,(80*7+17)*2 ;Linea 7, caracter 18
mov cx,13
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
;------------------------------------------------------------------------------
;Definicion del segmento de datos
;------------------------------------------------------------------------------
DATOS SEGMENT
mensaje db "Ejercicios disponibles en: www.victorsanchez2.net"
pregunta_nombre db "Cual es tu nombre?: "
nombre db 64 DUP(0)
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
;Fin de las inicializaciones
;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. Esto equivale a mov di,0, pero
;xor di,di consume 3 ciclos de reloj y con mov 4
mov cx,80*25 ;El tama�o total es 2000 (80 lineas x 25 columnas)
;Almacenamos el nombre
mov ah,0Ah
mov dx,offset nombre
mov nombre[0],64 ;Maximo numero de caracteres
int 21h
mov bx,0
muestra_nombre:
mov dl,nombre[bx+2]
mov ah,2
int 21h ;Escribir un caracter del nombre
inc bx
cmp bl,nombre[1] ;Compara con el numero de caracteres
jne muestra_nombre
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
;------------------------------------------------------------------------------
;Definicion del segmento de datos
;------------------------------------------------------------------------------
DATOS SEGMENT
mensaje db "Ejercicios disponibles en: www.victorsanchez2.net"
pregunta_nombre db "Cual es tu nombre?: "
nombre db 256 DUP(0)
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
;------------------------------------------------------------------------------
; Procedimiento inicial
;------------------------------------------------------------------------------
START PROC
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
;------------------------------------------------------------------------------
; inicializa_seg
;
; in:
; out: Los registros de segmento quedan inicializados
; machaca: AX, DS, SS, ES
; make: Inicializa los registros de segmento
;
;------------------------------------------------------------------------------
inicializa_seg proc near
mov ax,datos
mov ds,ax
mov ax,pila
mov ss,ax
mov ax,extra
mov es,ax
ret
inicializa_seg endp
;------------------------------------------------------------------------------
; limpia_pantalla
;
; in:
; out:
; machaca: DI, ES
; make: Limpia la pantalla escribiendo espacios en las 80x25 posiciones de
; la pantalla, accediendo a la memoria de video
;
;------------------------------------------------------------------------------
limpia_pantalla proc near
ret
limpia_pantalla endp
;------------------------------------------------------------------------------
; muestra_mensaje
;
; in:
; out:
; machaca: DI, SI
; make: Muestra un mensaje por pantalla indicando en que pagina se pueden
; encontrar los ejercicios
;
;------------------------------------------------------------------------------
muestra_mensaje proc near
push ax
push cx
push es
mov si,offset mensaje
mov di,(80*10+10)*2 ;Linea 10, columna 10
mov cx,49 ;Tama�o del mensaje
pop es
pop cx
pop ax
ret
muestra_mensaje endp
;------------------------------------------------------------------------------
; pide_nombre
;
; in:
; out:
; machaca: DI, SI, DX
; make: Pide el nombre al usuario para que lo introduzca por pantalla
;
;------------------------------------------------------------------------------
pide_nombre proc near
push ax
push cx
push es
;Almacenamos el nombre
mov ah,0Ah
mov dx,offset nombre
mov nombre[0],64 ;Maximo numero de caracteres
int 21h
pop es
pop cx
pop ax
ret
pide_nombre endp
;------------------------------------------------------------------------------
; muestra_nombre
;
; in: nombre contiene el nombre de usuario que se ha introducido
; out:
; machaca: DI, SI
; make: Muestra el nombre al usuario por pantalla
;
;------------------------------------------------------------------------------
muestra_nombre proc near
push ax
push cx
push es
mov ax,0B800h
mov es,ax
xor dx,dx
mov si,offset nombre+2
mov di,(80*12+31)*2 ;Linea 12, columna 31
mostrar_nombre:
mov al,[si]
mov ah,1bh ;Fondo azul, letras blancas
mov es:[di],ax
inc dx ;Cuenta el numero de caracteres
inc si
inc di
inc di
cmp dl,nombre[1] ;Comparar con el numero de caracteres
jne mostrar_nombre
pop es
pop cx
pop ax
ret
muestra_nombre endp
CODE ENDS
END START
;------------------------------------------------------------------------------
;Definicion del segmento de datos
;------------------------------------------------------------------------------
DATOS SEGMENT
dato db 3 ;Numero del que calcularemos su factorial
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 ;2 palabras (4 bytes)
EXTRA ENDS
;------------------------------------------------------------------------------
;Definicion del segmento de codigo
;------------------------------------------------------------------------------
CODE SEGMENT
assume CS:code,DS:datos,ES:extra,SS:pila
START PROC
mov cl,dato
call calcula_factorial ;Calcula el faltorial de dato
mov factorial,al ;Almacenar el resultado en factorial
call muestra_factorial ;Muestra el valor del factorial
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
;------------------------------------------------------------------------------
; inicializar
;
; in:
; out: Los registros de segmento quedan inicializados
; machaca: AX, DS, SS, ES
; make: Inicializa los registros de segmento
;
;------------------------------------------------------------------------------
inicializar proc near
mov ax,datos
mov ds,ax
mov ax,pila
mov ss,ax
mov ax,extra
mov es,ax
ret
inicializar endp
;------------------------------------------------------------------------------
; calcula_factorial
;
; in: CL contiene el dato
; out: Devuelve en AX el resultado de calcular el factorial
; machaca: AX, CX
; make: Inicializa los registros de segmento y el puntero de pila
;
;------------------------------------------------------------------------------
calcula_factorial proc near
mov ax,1
xor ch,ch
cmp cx,0 ;Si el numero es 0
je fin ;terminamos
factor:
mul cx
dec cx
jne factor
fin:
ret
calcula_factorial endp
;------------------------------------------------------------------------------
; muestra_nombre
;
; in: nombre contiene el nombre de usuario que se ha introducido
; out:
; machaca: DI, SI
; make: Muestra el valor del factorial por pantalla
;
;------------------------------------------------------------------------------
muestra_factorial proc near
push ax
push cx
push es
mov ax,0B800h
mov es,ax ;Apuntar a la memoria de video
mov dl,factorial
mov di,(80*12+31)*2 ;Linea 12, columna 31
add dl,30h ;Obtener el valor en ASCII ('0'=30h)
mov dh,1bh
mov es:[di],dx
pop es
pop cx
pop ax
ret
muestra_factorial endp
CODE ENDS
END START
2
Escribir un programa que escriba el mismo car�cter en las 2000 posiciones 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
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:
;------------------------------------------------------------------------------
;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 ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
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.
Realizar un programa que limpie la pantalla dejando el fondo azul y los caracteres
rojos:
;------------------------------------------------------------------------------
;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
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
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
3
Realizar un programa que muestre la tabla de caracteres ASCII por pantalla:
;------------------------------------------------------------------------------
; Programa que muestra la tabla de caracteres ASCII por pantalla
;------------------------------------------------------------------------------
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
xor bx,bx
xor al,al
mov cx,256 ;Numero de caracteres que contiene la tabla ASCII
mostrar_ascii:
mov [bx],al ;Escribirlo en la coordenada de la pantalla
inc bx ;
inc bx ;Pasar a la siguiente coordenada
inc al ;Pasar al siguiente caracter
loop mostrar_ascii
mov ax,4C00h ;
int 21h ;Terminar el programa
CODE ENDS
END START
Este programa se encarga de dibujar un cuadrado en la pantalla, ponerlo con fondo
blanco y rellenarlo con caracteres 'V':
;------------------------------------------------------------------------------
;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
BucleLineas:
push cx
BucleColumnas:
mov al,80*2 ;Bytes por linea
mul dl ;Por el numero de linea
mov bx,ax
mov al,2 ;2 bytes por columna
mul dh ;Por el numero de columna
add bx,ax
mov word ptr [bx],7056h ;Fondo blanco y letra 'V'
inc dh ;Siguiente columna
loop BucleColumnas
mov ax,4C00h
int 21h
CODE ENDS
END START
Este programa le pregunta al usuario si desea continuar o no hasta que se pulse la
tecla 'N' o 'n':
;------------------------------------------------------------------------------
;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
salir:
mov ax, 4C00h
int 21h
CODE ENDS
END START
Realizar un programa que cambie todas las letras de la pantalla a minusculas:
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 ;DS apunta a la direccion de la pantalla
xor bx,bx
mov cx,2000 ;80 filas x 25 columnas
cambia_minus:
mov al,ds:[bx] ;Obtenemos el caracter que hay en la pantalla
;en la coordenada indicada
cmp al,byte ptr 'A' ;Comprobar que este entre la letra 'A'
jb siguiente ;
cmp al,byte ptr 'Z' ;y la letra 'Z'
ja siguiente ;Si no es asi pasamos al siguiente caracter
add al,32 ;Para pasar de mayusculas a minusculas
;hay que sumar 32 para movernos en la
;tabla ASCII de las mayusculas a las minusculas
mov ds:[bx],al ;Escribimos en la pantalla el caracter cambiado
;a minusculas
siguiente:
inc bx ;
inc bx ;Pasamos a la siguiente coordenada
loop cambia_minus
mov ax,4C00h ;
int 21h ;Terminamos el programa
CODE ENDS
END START
;------------------------------------------------------------------------------
;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 ah,3 ;No sirve para nada, solo para ver que al convertir
;en palabra o doble palabra se machacan los registros
mov al,5
cbw ;Convertir un byte en palabra
cwd ;Convertir una palabra en doble palabra
mov ax,4C00h
int 21h
CODE ENDS
END START
Ejemplo de la instruccion: AAM (ajuste ASCII en multiplicaci�n)
;------------------------------------------------------------------------------
; Programa que prueba la instruccion: AAM
;
; ah <- cociente (al/10)
; al <- resto (al/10)
;
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;Definicion del segmento de codigo
;------------------------------------------------------------------------------
CODE SEGMENT
assume CS:code
START:
mov al,9
mov cl,5
mul cl ;Resultado: ax=002D
aam ;En el cociente hay un 4 y en el resto un 5
;Resultado es ax=0405
mov ax,4c00h
int 21h
CODE ENDS
END START
Ejemplo de la instruccion: AAA (ajuste ASCII en suma)
;------------------------------------------------------------------------------
; Programa que muestra el uso de la instruccion AAA. Esta instruccion convierte
; el contenido de AL en un numero decimal ASCII (desempaquetado) tras una
; instruccion de suma. Se utiliza para ajustar el resultado despues de una suma
; de dos numeros decimales en formato ASCII
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;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 PROC
mov ax,8 ;
add al,1 ;
aaa ;AX=0009h
mov ax,8 ;
add al,2 ;
aaa ;AX=0100h
mov ax,11110001b ;
add al,1 ;
aaa ;AX=0002h
mov ax,8 ;
add al,7 ;
aaa ;AX=0105h
add al,4 ;
aaa ;AX=0109h
add al,9 ;
aaa ;AX=0208h
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
Ejemplo de la instruccion: AAA (ajuste ASCII en suma). Del examen de ETCII del a�o
2001:
;------------------------------------------------------------------------------
; Programa que prueba la instruccion: AAA
;
; ah <- cociente (al/0Ah)
; al <- resto (al/0Ah)
;
;------------------------------------------------------------------------------
; Ejercicio: examen ETCII - 7/11/01
;------------------------------------------------------------------------------
;Definicion del segmento de codigo
;------------------------------------------------------------------------------
CODE SEGMENT
assume CS:code
start:
mov ax,16h
mov bx,191h
add ax,bx
aaa ;AX=0107h
add ax,7h
aaa ;AX=0204h
mov ax,4c00h
int 21h
CODE ENDS
END START
Ejemplo que muestra la diferencia entre las instrucciones: AAA y DAA
;------------------------------------------------------------------------------
; Programa que prueba las instrucciones: AAA y DAA
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;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 al,5
add al,7
aaa ;Ajuste BCD no empaquetado
xor ax,ax
mov al,5
add al,7
daa ;Ajuste BCD empaquetado
mov ax,4C00h
int 21h
CODE ENDS
END START
Ejemplo de la instrucci�n NEG (convertir a complemento a 2):
;------------------------------------------------------------------------------
;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 al,8
neg al ;Convertir a su complemento a 2
mov ax,4C00h
int 21h
CODE ENDS
END START
Otra forma de convertir a complemento a 2 mediante las instrucciones NOT e INC:
;------------------------------------------------------------------------------
;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 al,8
not al ;
inc al ;Convertir a su complemento a 2
mov ax,4C00h
int 21h
CODE ENDS
END START
5
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
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;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
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
restaura: ;
movsb ;
loop restaura ;Volver a dejar la pantalla como al principio
mov ax,4C00h
int 21h
CODE ENDS
END START
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
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;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
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 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
;------------------------------------------------------------------------------
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
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
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
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
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
lea dx,instalar
int 27h
instalar endp
CODE ENDS
END START
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
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
FIN: pop ds
pop es
pop ax
ret
desinstalar ENDP
CODE ENDS
END START
6 Estos ejercicios van a ser algo m�s complejos y son del nivel que se va a exigir
a aquellos que est�n cursando la asignatura de ETCII en la Universidad Aut�noma de
Madrid.
Hallar cual es el valor de AX tras la segunda instrucci�n AAA:
;------------------------------------------------------------------------------
;Definicion del segmento de codigo
;------------------------------------------------------------------------------
CODE SEGMENT
assume CS:code
start:
mov ax,16h
mov bx,191h
add ax,bx
aaa
add ax,7h
aaa
mov ax,4c00h
int 21h
CODE ENDS
END START
Hallar cual es el valor de AX tras la segunda instrucci�n AAA:
;------------------------------------------------------------------------------
;Definicion del segmento de codigo
;------------------------------------------------------------------------------
CODE SEGMENT
assume CS:code
start:
mov ax,123h
mov bx,77h
add ax,bx
aaa
add ax,5h
aaa
mov ax,4c00h
int 21h
CODE ENDS
END START
Hallar el valor de AX tras la instrucci�n "div bl":
;------------------------------------------------------------------------------
;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 PROC
;Inicializamos los registros de segmento
mov ax,pila
mov ss,ax
mov ax,905h
mov bx,2h
aad
mov ah,10h
div bl
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
Hallar el valor de AX tras la instrucci�n "aam":
;------------------------------------------------------------------------------
;Definicion del segmento de codigo
;------------------------------------------------------------------------------
CODE SEGMENT
assume CS:code
START:
mov al,9
mov cl,5
mul cl
aam
mov ax,4c00h
int 21h
CODE ENDS
END START
Hallar el valor de AX tras la instrucci�n "daa":
;------------------------------------------------------------------------------
;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 PROC
mov ax,23h
mov bx,77h
add ax,bx
xor ah,ah
daa
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
;------------------------------------------------------------------------------
;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 PROC
;Inicializamos los registros de segmento
mov ax,pila
mov ss,ax
mov cx,37FFh
xor bx,bx
push cx
push bx
mov bp,sp
mov ax,[bp+1]
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
Hallar el valor de AX tras la instrucci�n "mov ax,[bp+1]":
;------------------------------------------------------------------------------
;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 PROC
;Inicializamos los registros de segmento
mov ax,pila
mov ss,ax
mov ax,3759h
xor bx,bx
push ax
push bx
mov bp,sp
mov ax,[bp+1]
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
Hallar el valor de AX tras la instrucci�n "stosb":
;------------------------------------------------------------------------------
;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,ES:extra,SS:pila
;------------------------------------------------------------------------------
; Procedimiento inicial
;------------------------------------------------------------------------------
START PROC
mov si,40h
cld
mov byte ptr ds:[si],0Fh
xor cx,cx
mov al,0F0h
rep scasb
std
mov di,si
mov bx,ds
mov es,bx
stosb
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
Hallar el valor de AX tras la instrucci�n "rep lodsw":
;------------------------------------------------------------------------------
;Definicion del segmento de datos
;------------------------------------------------------------------------------
DATOS SEGMENT
texto db "Cadena_de_texto"
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
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
Otro ejercicio como el anterior:
;------------------------------------------------------------------------------
;Definicion del segmento de datos
;------------------------------------------------------------------------------
DATOS SEGMENT
texto db "Esto_es_una_cadena_de_texto",0
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
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
Y otro m�s. Las instrucciones de cadena son bastante potentes y como podreis ver es
mejor saber manejarlas con soltura:
;------------------------------------------------------------------------------
;Definicion del segmento de datos
;------------------------------------------------------------------------------
DATOS SEGMENT
texto db "Cadena_de_texto"
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
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
Hallar el valor de AX tras salir del bucle:
;------------------------------------------------------------------------------
;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 PROC
;Inicializamos los registros de segmento
mov ax,pila
mov ss,ax
mov bx,10h
xor ax,ax
mov cx,0FFFFh
L1:
add ax,bx
loop L1
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
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'
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;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
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:
;------------------------------------------------------------------------------
;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
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:
;------------------------------------------------------------------------------
;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
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
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
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
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
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
9
Otro problema de examen. Hallar el valor de AX tras la instrucci�n mov ax,word ptr
ds:[3]
;------------------------------------------------------------------------------
;Definicion del segmento de datos
;------------------------------------------------------------------------------
DATOS SEGMENT
dw 3Ah,7Bh,9Ch
db 34h,76h,65h
org 1
db 67h,31h,56h,"SE ACABO"
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
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
Muy similar al anterior:
;------------------------------------------------------------------------------
;Definicion del segmento de datos
;------------------------------------------------------------------------------
DATOS SEGMENT
dw 3Ah,7Bh,9Ch
db 34h,76h,65h
org 2
db 67h,31h,56h,"SE ACABO"
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
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
�Cu�l es el valor de AX tras la instrucci�n NOP?:
;------------------------------------------------------------------------------
;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,ES:extra,SS:pila
;------------------------------------------------------------------------------
; Procedimiento inicial
;------------------------------------------------------------------------------
START PROC
mov ax,1Fh
push ax
inc sp
push ax
dec sp
pop ax
pop ax
nop
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
Muy importantes tambi�n son los ejercicios de pila. Hallar el valor de AX tras la
instrucci�n NOP:
;------------------------------------------------------------------------------
;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 PROC
;Inicializamos los registros de segmento
mov ax,pila
mov ss,ax
mov al,5
mov bx,0FA45h
push bx
push ax
mov bp,sp
mov al,[bp+3]
nop
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
Estos ejercicios de pilas suelen tener truco la mayor�a de las veces ;) Hallar el
valor de AX tras el �ltimo POP:
;------------------------------------------------------------------------------
;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 PROC
;Inicializamos los registros de segmento
mov ax,pila
mov ss,ax
push 0F34h
push 63h
pop ax
inc sp
pop ax
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
10
Hallar el valor de AX tras la instrucci�n div bl:
;------------------------------------------------------------------------------
;Definicion del segmento de codigo
;------------------------------------------------------------------------------
CODE SEGMENT
assume cs:code
START PROC
mov ah,1
mov al,0D7h
xor bx,bx
stc
rcr bx,1
rcr bx,1
div bl
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
De nuevo un ejercicio sencillito para dejar a un lado los ex�menes (por el momento)
y relajarnos un poco y ver otra forma de inicializar variables. Este programa
muestra dos l�neas, una llena de '5' y otra de '@':
;------------------------------------------------------------------------------
;Definicion del segmento de datos
;------------------------------------------------------------------------------
DATOS SEGMENT
Cadena1 db 80 dup("5"),"$"
Cadena2 db 80 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
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
Volvemos con m�s instrucciones de cadena y otro ejercicio de examen. Hallar el
valor de CX tras la instrucci�n repnz scasb:
;------------------------------------------------------------------------------
;Definicion del segmento de datos
;------------------------------------------------------------------------------
DATOS SEGMENT
texto db "Esto es un texto",0,"Y este otro",0
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
push ds
pop es
cld
mov ax,4C00h
lea di,texto
mov cx,14h
repnz scasb
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
�Que es lo que encuentra el programa? "to" de la palabra "Esto" "ot" de la palabra
"otra"
;------------------------------------------------------------------------------
;Definicion del segmento de datos
;------------------------------------------------------------------------------
DATOS SEGMENT
cadena db "Esto es otra cadena"
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
cld
mov ax,datos
mov es,ax
mov cx,100h
mov ax,"ot"
lea di,cadena
repnz scasw
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
Hallar el valor de AX tras la instrucci�n mov al,byte ptr tabla[si]:
;------------------------------------------------------------------------------
;Definicion del segmento de datos
;------------------------------------------------------------------------------
DATOS SEGMENT
db 10,'A',32,45h,10001101b,16
tabla dw 15,'Dk','27',4F5h
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 si,si
mov ax,[si]
sub ax,[si]
mov al,byte ptr tabla[si]
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
Espero que estos 50 programas os sirvan para entender un poco mejor la asignatura
de ETC II.