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