Conforme desarrollamos ejemplos más elaborados, el tamaño de nuestros archivos aumenta y muchas veces copiamos el mismo código en varios programas (por ejemplo, el código que despliega una imagen bmp). En este post, veremos una forma de cómo reusar funciones que están en un módulo (archivo) independiente.
Tomemos como ejemplo el programa de este post. El programa convierte dos cadenas a enteros usando la función atoi (ascii to integer), los suma y convierte el resultado a cadena usando itoa (integer to ascii) para poder desplegarlo. Las funciones itoa/atoi son funciones que podemos reusar en varios programas, por lo que es buena idea ponerlas en un archivo independiente.
Comencemos por colocar estas funciones en un archivo llamado libcad.asm. El segundo paso es crear un archivo que contenga los prototipos de las funciones que queremos usar en otros archivos. Llamemos a este archivo libcad.inc. El contenido del archivo libcad.inc es el siguiente:
.CODE EXTERNDEF atoi:NEAR EXTERNDEF itoa:NEAR @CurSeg ENDS
Noten que debemos especificar el segmento en donde se encuentra lo que queremos exportar. En este caso nuestras funciones se encuentran en el segmento .CODE; además, es recomendable cerrar el segmento ya que incluiremos este archivo en otros archivos. La palabra clave EXTERNDEF declara lo que queremos exportar, en este caso es seguida por el nombre de la función y el tipo de la función (NEAR, porque estamos usando .MODEL SMALL en nuestros programas).
El archivo libcad.inc se debe incluir tanto en el archivo que define las funciones como en los archivos que las usan. El archivo libcad.asm queda de la siguiente forma:
.model SMALL .STACK 128 INCLUDE libcad.inc .CODE ; ========= Convertir cadena a numero ===================== ; Parametros ; si: offset inicial de la cadena con respecto a DS ; Retorna ; bx: valor atoi proc NEAR xor bx,bx ;BX = 0 atoi_1: lodsb ;carga byte apuntado por SI en AL ;e incrementa si cmp al,'0' ;es numero ascii? [0-9] jb noascii ;no, salir cmp al,'9' ja noascii ;no, salir sub al,30h ;ascii '0'=30h, ascii '1'=31h...etc. cbw ;byte a word push ax mov ax,bx ;BX tendra el valor final mov cx,10 mul cx ;AX=AX*10 mov bx,ax pop ax add bx,ax jmp atoi_1 ;seguir mientras SI apunte a un numero ascii noascii: ret ;BX tiene el valor final atoi endp ; =============== Convertir numero a cadena =============== ; Parametros ; ax: valor ; bx: donde guardar la cadena final ; Retorna ; cadena itoa proc NEAR xor cx,cx ;CX = 0 itoa_1: cmp ax,0 ; El ciclo itoa_1 extrae los digitos del je itoa_2 ; menos al mas significativo de AX y los ; guarda en el stack. Al finalizar el xor dx,dx ; ciclo el digito mas significativo esta push bx ; arriba del stack. mov bx,10 ; CX contiene el numero de digitos div bx pop bx push dx inc cx jmp itoa_1 itoa_2: cmp cx,0 ; Esta seccion maneja el caso cuando ja itoa_3 ; el numero a convertir (AX) es 0. mov ax,'0' ; En este caso, el ciclo anterior mov [bx],ax ; no guarda valores en el stack y inc bx ; CX tiene el valor 0 jmp itoa_4 itoa_3: pop ax ; Extraemos los numero del stack add ax,30h ; lo pasamos a su valor ascii mov [bx],ax ; lo guardamos en la cadena final inc bx loop itoa_3 itoa_4: mov ax,'$' ; terminar cadena con '$' para mov [bx],ax ; imprimirla con la INT21h/AH=9 ret itoa endp end
Y el archivo de ejemplo que usa las funciones es el siguiente (ejem01.asm):
.model SMALL .STACK 128 INCLUDE libcad.inc .DATA cadena1 db '123$' cadena2 db '444$' cadena3 db 6 DUP(?) op1 dw ? op2 dw ? .CODE .STARTUP mov ax,@data mov ds,ax main proc ; SI parametro mov si, offset cadena1 call atoi mov op1,bx ; SI parametro mov si, offset cadena2 call atoi mov op2,bx ; sumar mov ax, op1 add ax, op2 mov bx, offset cadena3 call itoa mov dx, offset cadena3 call desplegar ; INT 21h / AH=4Ch retorna el control al sistema operativo ; termina el programa salir: mov ax,4c00h int 21h ret main endp ; ============ Proc: Desplegar mensaje ==================== ; Parametros ; dx: offset de cadena terminada por $ con respecto a DS desplegar proc ; INT 21h / AH=9 - despliega cadena apuntada por DS:DX. ; la cadena debe estar terminada por '$'. mov ah,09h ;mov dx, offset cad int 21h ret desplegar endp end
Para ensamblar y ligar estos archivos basta con invocar
ml EJEM01.ASM LIBCAD.ASM
No hay comentarios:
Publicar un comentario