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