Está en la página 1de 51

http://www.victorsanchez2.com/manuales/asm/pag002.

php

1
Escribir un programa en ensamblador que muestre un mensaje por pantalla mediante
interrupciones:

;------------------------------------------------------------------------------
;Definicion del segmento de datos
;------------------------------------------------------------------------------
DATOS SEGMENT

saludo db "Hola mundo!!!","$"

DATOS ENDS

;------------------------------------------------------------------------------
;Definicion del segmento de codigo
;------------------------------------------------------------------------------
CODE SEGMENT
assume cs:code,ds:datos

START PROC
mov ax,datos ;
mov ds,ax ;Inicializar

mov dx,offset saludo ;Cargar la direccion del saludo


mov ah,9 ;Opcion que va a servir a la interrupcion 21h para
;indicar que debe mostrar por pantalla el offset
;que hay en DX hasta que encuentre el caracter '$'
int 21h ;Interrupcion que lo mostrara por pantalla

mov ax,4C00h ;
int 21h ;Terminar el programa

START ENDP

CODE ENDS
END START

Escribir un programa en ensamblador que muestre un mensaje por pantalla accediendo


a la memoria de video (0B800h):

;------------------------------------------------------------------------------
;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)

b_clear: ;Bucle que se encargara de recorrer los 2000


;caracteres de la pantalla para limpiarla
mov al,20h ;20h=" " Rellenar la pantalla con espacios
mov ah,1bh ;Fondo azul, letras blancas
mov es:[di],ax
inc di
inc di
loop b_clear

mov ax,0B800h
mov es,ax
mov si,offset saludo
mov di,(80*7+17)*2 ;Linea 7, caracter 18
mov cx,13

b_saludo: ;Bucle que se encargara de recorrer los 2000


;caracteres de la pantalla para limpiarla
mov al,[si]
mov ah,1bh ;Fondo azul, letras blancas
mov es:[di],ax
inc si ;Pasamos a apuntar a la siguiente letra del saludo
inc di
inc di
loop b_saludo

mov ax,4C00h ;
int 21h ;Terminar el programa

START ENDP

CODE ENDS
END START

Este programa pide el nombre al usuario y lo muestra por pantalla:

;------------------------------------------------------------------------------
;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)

b_clear: ;Bucle que se encargara de recorrer los 2000


;caracteres de la pantalla para limpiarla
mov al,20h ;20h=" " Rellenar la pantalla con espacios
mov ah,1bh ;Fondo azul, letras blancas
mov es:[di],ax
inc di
inc di
loop b_clear
;Mostramos un mensaje
mov si,offset mensaje
mov di,(80*10+10)*2 ;Linea 10, columna 10
mov cx,49 ;Tama�o del mensaje

b_saludo: ;Bucle que se encargara de recorrer los 2000


;caracteres de la pantalla para limpiarla
mov al,[si]
mov ah,1bh ;Fondo azul, letras blancas
mov es:[di],ax
inc si ;Pasamos a apuntar a la siguiente letra del saludo
inc di
inc di
loop b_saludo

;Mensaje al usuario para que introduzca su nombre


mov si,offset pregunta_nombre
mov di,(80*12+10)*2 ;Linea 12, columna 10
mov cx,20

b_pide_nombre: ;Bucle que se encargara de recorrer los 2000


;caracteres de la pantalla para limpiarla
mov al,[si]
mov ah,1bh ;Fondo azul, letras blancas
mov es:[di],ax
inc si ;Pasamos a apuntar a la siguiente letra del saludo
inc di
inc di
loop b_pide_nombre

;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

El mismo programa que antes, pero ahora con llamadas a funciones:

;------------------------------------------------------------------------------
;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

call inicializa_seg ;Inicializa los registros de segmento


call limpia_pantalla ;Limpiamos la pantalla
call muestra_mensaje ;Mensaje de informacion
call pide_nombre ;Pide el nombre al usuario
call muestra_nombre ;Muestra por pantalla el nombre del usuario

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

push ax ;Guardar en la pila las variables que queremos


push cx ;conservar para cuando salgamos de la funcion

mov ax,0B800h ;En esta direccion comienza la memoria de video


mov es,ax ;Lo cargamos en el segmento extra
xor di,di ;Inicializar DI a 0
mov cx,80*25 ;El tama�o total es 2000 (80 lineas x 25 columnas)

b_clear: ;Bucle que se encargara de recorrer los 2000


;caracteres de la pantalla para limpiarla
mov al,20h ;20h=" " Rellenar la pantalla con espacios
mov ah,1bh ;Fondo azul, letras blancas
mov es:[di],ax
inc di
inc di
loop b_clear

pop cx ;Importante sacarlas en orden contrario al que las


pop ax ;guardamos

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

b_saludo: ;Bucle que se encargara de recorrer los 2000


;caracteres de la pantalla para limpiarla
mov al,[si]
mov ah,1bh ;Fondo azul, letras blancas
mov es:[di],ax
inc si ;Pasamos a apuntar a la siguiente letra del saludo
inc di
inc di
loop b_saludo

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

;Mensaje al usuario para que introduzca su nombre


mov si,offset pregunta_nombre
mov di,(80*12+10)*2 ;Linea 12, columna 10
mov cx,20

b_pide_nombre: ;Bucle que se encargara de recorrer los 2000


;caracteres de la pantalla para limpiarla
mov al,[si]
mov ah,1bh ;Fondo azul, letras blancas
mov es:[di],ax
inc si ;Pasamos a apuntar a la siguiente letra del saludo
inc di
inc di
loop b_pide_nombre

;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

Programa que calcula el factorial de 3 y lo muestra por pantalla:

;------------------------------------------------------------------------------
;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

factorial db 0 ;Variable para guardar el factorial

START PROC

call inicializar ;Inicializa los registros de segmento


mov sp,64 ;Carga el puntero de pila con el valor mas alto

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:

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
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
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:

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.

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':

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 dl,0 ;Primera linea en la que empezaremos a pintar


mov cx,10 ;Numero de lineas que vamos a tener

BucleLineas:
push cx

mov dh,0 ;Primera columna


mov cx,20 ;Numero de columnas

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

pop cx ;Recuperamos el contador de las lineas


inc dl ;Pasar a la siguiente linea
loop BucleLineas

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':

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
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

4 Vamos a ver diferentes ejemplos de instrucciones para entenderlas un poco mejor.


Ser� bueno tener un libro al lado para saber qu� hace cada instrucci�n.
Ejemplo de las instrucciones: CBW y CWD

;------------------------------------------------------------------------------
;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

neg al ;al pasa a ser un numero negativo (complemento a 2)


mov ah,4 ;basura, igual que en caso anterior
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
;------------------------------------------------------------------------------

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
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
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
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

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:

; 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
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:

; Ejercicio: examen ETCII - Febrero 2000

;------------------------------------------------------------------------------
;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

7 Las soluciones y archivos fuente de todos los ejercicios pod�is obtenerlos


escribi�ndome un e-mail para ped�rmelos.
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 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 si,offset texto


cld
mov cx,5
rep lodsw

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 si,offset texto


add si,19h
std
mov cx,5
rep lodsw

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 si,offset texto


add si,0Dh
std
mov cx,5
rep lodsw

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'
;------------------------------------------------------------------------------

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

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,word ptr ds:[3]

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,word ptr ds:[3]

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?:

; Ejercicio: examen ETCII - febrero 2002

;------------------------------------------------------------------------------
;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 dx,offset Cadena1


mov ah,9
int 21h

mov dx,offset Cadena2


mov ah,9
int 21h

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.

Y ya sab�is, si quer�is los archivos fuente y las soluciones escribid a


victorsanchez2 en gmail.com.

También podría gustarte