Programacion Modular
Programacion Modular
MODULAR
EN
ENSAMBLADOR DEL 80x86
INTRODUCCIN.La programacin modular es la tcnica que consiste en hacer independientes una serie de
mdulos de programa, de tal forma que el programa resultante est formado por un mdulo
principal y varios secundarios que se enlazan con el anterior.
Los mdulos pueden ser codificados en el mismo fichero fuente que el programa principal, o
pueden estar en ficheros fuente independientes. En este caso cada uno de los mdulos se
compila o ensambla (segn el caso) de forma independiente, obtenindose el mdulo objeto
correspondiente. Con el linkador se enlazan todos juntos para formar un slo fichero ejecutable.
El contenido de los mdulos secundarios suele ser estar organizado en procedimientos y
funciones. De esta forma un mismo procedimiento puede ser utilizado en cualquier otro
programa, formndose as una librera de funciones y procedimientos.
No slo se pueden utilizar los procedimientos de un mdulo, sino que tambin se puede hacer
referencia a las variables declaradas en cada uno de llos. No obstante sto no es recomendable,
utilizndose como va de comunicacin con los procedimientos, el paso de parmetros por la
pila.
Una de las mayores ventajas de la programacin modular, en este caso en ensamblador, es la de
poder hacer llamadas a rutinas escritas en ensamblador desde un lenguaje de alto nivel. De esta
forma se consigue acceder a recursos del sistema que no eran accesibles desde Pascal o C. An
en el caso de que s lo fueran, seguramente se ejecutarn de una forma mucho ms rpida y
eficiente que la opcin que nos proporciona el lenguaje de alto nivel.
En los siguientes apartados se hablar de cada una de las opciones disponibles a la hora de
construir mdulos de programa en ensamblador.
pg. 1
PROC
[NEAR] [FAR]
ENDP
Los procedimientos siempre estarn en el segmento de cdigo y la ltima instruccin del mismo
ser la de retorno RET para la familia del 8086.
Si el procedimiento va a ser llamado desde otro segmento de cdigo, se deber declarar de tipo
FAR, pudindose especificar NEAR o no en caso contrario.
En la fase de ensamblado, automticamente se sustituye la instruccin RET por RETF si el
procedimiento es lejano.
La llamada a un procedimiento se hace de a travs de la instruccin CALL:
call
nombre_proc
; se salvan los
; registros que se modifican
; incluido BP
; BP apunta al TOP de la pila
; recogida del parmetro
; se recuperan los
; registros
; salvados
; retorno ignorando los 2 bytes del parmetro
dir altas
dir bajas
pg. 3
; obtener segmento
; obtener desplazamiento
; en la pila segmento:offset
; llamada al procedimiento
proc
push bp
mov bp,sp
mov di,6[bp]
mov ax,8[bp]
mov es,ax
mov ax,es:[di]
----ret 4
ejemplo
endp
far
; recoger el offset de la variable
; recoger el segmento
; cargar registro segmento extra
; direccionar la variable
pg. 4
extrn inicializa:far
En el caso de las variables ocurre lo mismo. En el ejemplo se declara externa la variable modo
de tipo byte:
extrn modo:byte
El cuadro completo de tipos es el siguiente:
Descripcin
Especificador de distancia
Especificador tamao
Especificador de constantes
Tipos posibles
NEAR, FAR
BYTE, WORD, DWORD, FWORD, QWORD,
TBYTE
ABS
Por otra parte, en cada mdulo hay que declarar como pblicos los procedimientos y variables
que se quiera puedan ser utilizados por otros mdulos. Esto se hace a travs de la directiva
PUBLIC, seguida del nombre de la variable o procedimiento:
PUBLIC nombre [,nombre] ...
Ej:
Un aspecto importante es la posibilidad de fusionar varios segmentos del mismo tipo. Sera el
caso de formar un slo segmento de datos a partir de cada uno de los segmentos
correspondientes de los mdulos.
Para conseguirlo, se emplea la directiva GROUP. La sintaxis es la siguiente:
nombre_seg_grupo
GROUP
Si en cada mdulo tenemos un segmento llamado datos y se quieren fusionar en otro llamado
DGROUP, se debera incluir en cada mdulo la directiva:
dgroup GROUP datos
Una vez construidos todos los mdulos, se ensamblan por separado y se linkan o enlazan,
especificando el nombre del fichero ejecutable final, que suele coincidir con el del mdulo
principal.
link
pg. 5
; el parmetro en SS:[BP+8]
; borrar pantalla. Modo en AL
;
pop bp
pop ax
pop ds
; recuperar
; los registros
; afectados
ret 2
borra_pan endp
code ends
pg. 6
end
; el parmetro en SS:[BP+10]
LLAMADAS A FUNCIONES
En el caso de las funciones la declaracin es igual que para los procedimientos, slo que habr
que aadir el tipo del valor devuelto.
El siguiente ejemplo muestra la declaracin de dos funciones en Turbo Pascal y el cdigo en
Ensamblador de una de llas:
program ejemplo (input,output);
{$F+}
function power_2(a:integer;b:integer):integer; External;
function fact(n:integer):word; External;
{$L modulo.obj}
BEGIN
writeln('5 * 2^3 = ',power_2(5,3));
writeln('el factorial de 8 es ',fact(8));
END.
pg. 7
La llamada, como se puede observar ser de tipo far, luego la pila en la llamada queda como
sigue:
***********
a
BP + 12
b
BP + 10
CS
IP
BP
DS
CX
BP, SP
***********
dir altas
dir bajas
Nmero de bytes
2
2
2
4
4
8
10
2
4
pg. 8
Tipo
char , unsigned char
short , unsigned short
int , unsigned int
long , unsigned long
estructura o unin
puntero cercano
puntero lejano
Registro
AX
AX
AX
DX:AX
DX:AX
(direccin)
AX
DX:AX
Podemos utilizar la siguiente variacin que se encarga de adaptar el cdigo a las exigencias del
C:
dosseg
.MODEL small
.CODE
_borra_pan proc
push bp
push ds
push ax
mov bp,sp
mov al,08h[bp]
mov ah,0
int 10h
pop ax
pop ds
pop bp
ret
_borra_pan endp
PUBLIC _borra_pan
end
prin.c modulo.asm
donde prin.c es el fichero fuente en C y modulo.asm en ensamblador. Hay que tener en cuenta
que tcc llamar al fichero tasm.exe para ensamblar el fichero modulo.asm.
Es posible primero ensamblar modulo.asm y linkar con prin:
tasm /ml modulo.asm
tcc prin.c modulo.obj
pg. 9
pop bx
pop ds
pop bp
ret
_factorial endp
_borra_pan proc
push bp
push ds
push ax
mov bp,sp
mov al,08h[bp]
mov ah,0
int 10h
pop ax
pop ds
pop bp
ret
_borra_pan endp
PUBLIC _borra_pan
PUBLIC _power_2
PUBLIC _factorial
_TEXT ends
end
pg. 10
/ml
modulo.asm
/E /C
mylib.lib
+modulo.obj
,mylib.lst
_factorial
ppal.c mylib.lib
ppal.c:
#include <stdio.h>
void borra_pan(unsigned int modo);
int factorial(unsigned int i);
unsigned int power_2(unsigned int i,unsigned int j);
main()
{
borra_pan(3);
printf("el factorial de 4 es %d\n",factorial(4));
printf("3 * 2^5 , es %d",power_2(3,5));
}
slamente se enlazarn los mdulos que se necesiten. En este caso slo modulo
pg. 11
mod.asm:
; modulo para usar en 'C'
; ensamblar tasm /ml mod.asm para sensible a maysculas-minsculas
extrn _modo:word
_TEXT segment byte public 'CODE'
assume cs:_TEXT
_borra_pan proc
mov modo,77
call _borrar
ret
_borra_pan endp
extrn _borrar:near
PUBLIC _borra_pan
_TEXT ends
end
pg. 12