LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16 PRÁCTICA 16 PROGRAMA RESIDENTE QUE PUEDE USAR FUNCIONES DE DOS PARA CAPTURAR LA SALIDA A IMPRESORA 1. INTRODUCCIÓN La práctica está dedicada a ilustrar el método para hacer programas residentes en memoria que sean capaces de poder acceder el disco duro a través de funciones de DOS. 2. 3. OBJETIVOS 2.1 El alumno aprenderá a usar técnicas muy avanzadas de uso de las funciones de DOS. 2.2 Aprenderá a hacer programas que se instalan en memoria para lograr algún fin específico. Dichos programas impiden su reinstalación, una vez que ya están instalados y pueden reconfigurarse a voluntad del usuario. 2.3 Se examinan algunas técnicas para cambiar vectores de interrupción DESARROLLO 3.1 %TITLE Capturar el siguiente módulo y salvarlo con el nombre DESVIA.ASM. "modulo DESVIA.ASM que captura la salida a impresora" ;ensamblar con: ;ligar con TASM TLINK /t desvia desvia ;DESVIA.COM captura salida a una impresora hacia un archivo. Su sintaxis es: ; ; DESVIA PRNn[:]=[[d:][ruta]NomArch] [/B=largo] [/C] ; ;donde PRNn especifica la impresora de la PC a enrutar (PRN1, ;PRN2 o PRN3), "NomArch" especifica el nombre del archivo, y "largo" ;especifica el tamaño del buffer interno de DESVÍA (en kilobytes). ;El "largo" por default es de 4K; Los valores aceptables son de 2K a 32K. ;Al correr DESVÍA sin parámetros en la línea de comandos, se exhibe (si hay) ;el puerto que es redirigido. Ejecutando con /C cancela la redirección. IDEAL MODEL tiny AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS 16-1 LENGUAJE ENSAMBLADOR 80386 CODESEG assume org 100h jmp inicio PRÁCTICA 16 CS:_text,DS:_text salto: firma numeroID db db 0,1,2,"-DESVIA-",2,1,0 ? ;firma del programa ;numero para multiplexar int08h int13h int17h int21h int25h int26h int28h int2Fh dd dd dd dd dd dd dd dd ? ? ? ? ? ? ? ? ;vector de interrupción 08h ;vector de interrupción 13h ;vector de interrupción 17h ;vector de interrupción 21h ;vector de interrupción 25h ;vector de interrupción 26h ;vector de interrupción 28h ;vector de interrupción 2Fh BandError BandInt EnDOS largo mitad puntero SegBuf bytes contador PtoSerie NomArch dd db dd dw dw dw dw ? 0 ? 4096 2048 0 ? dw ? 91 0FEh,0 128 dup (?) ;dirección de band. de error critico ;bandera interrupción de disco ;dirección de bandera en DOS ;tamaño del buffer interno ;mitad del buffer ;puntero del buffer ;segmento del buffer ;Numero de bytes en buffer ;contador de tiempo descendente ;puerto PRN Redirigido ;especificación del archivo db db db LOJ manipula interrupción 08h. PROC IntReloj pushf call [cs:int08h] cli cmp je dec jnz cmp jne mov jmp @@10: push push cmp jne FAR ;salva banderas ;llama manejador previo ;Deshabilita interrupciones [cs:contador],0 @@10 [cs:contador] @@99 [cs:puntero],0 @@10 [cs:contador],91 short @@99 ;Brinca si contador ;llego a cero ;Decrementa contador ;sale si no cero ;Brinca si hay datos ;en el buffer ;Repone el contador y sale ;si no di es [cs:BandInt],0 @@20 ;Salva ES y DI AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS ;Brinca si hay interrupción ;de disco 16-2 LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16 les cmp jne les cmp jne call @@20: pop pop @@99: iret di,[cs:EnDOS] [byte ptr es:di],0 @@20 di,[cs:BandError] [byte ptr es:di],0 @@20 vacia ;Brinca si esta en DOS es di ;Restaura ES y DI ENDP IntReloj ;IntImpre manipula interrupción 17h. PROC IntImpre FAR [cs:PtoSerie],0FFh @@20 ;Brinca si la redirección ;está habilitada [cs:int17h] ;salta a rutina del BIOS dx,[word ptr cs:PtoSerie] @@10 ah,03h @@10 ;sale si este puerto PRN no esta ;actualmente redirigido ;sale si función trae código ;mayor que 03h di es ;Salva ES y DI cmp jne @@10: jmp @@20: cmp jne cmp ja push push ;Brinca si el error crítico ;está activo ;Salva buffer en archivo ;Procesa interrupción 17h, función 00h (transmite carácter a impresora). or jnz mov mov cmp je mov mov inc mov cmp jb ah,ah @@40 [cs:contador],91 di,[cs:puntero] di,[cs:largo] @@70 es,[cs:SegBuf] [es:di],al di [cs:puntero],di di,[cs:mitad] @@60 ;Brinca si AH no es 0 @@30: cmp jne les cmp jne [cs:BandInt],0 @@60 di,[cs:EnDOS] [byte ptr es:di],0 @@60 ;Brinca si bandera de interrupción ;de disco esta puesta ;Brinca si bandera En DOS ;está puesta AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS ;Repone contador de tics ;apunta con DI al buffer ;Error si el buffer está ;lleno ;apunta con ES al segmento ;pone en buffer al carácter ;Incrementa puntero del buffer ;Salva nuevo apuntador ;sale si el buffer esta menos ;que medio lleno 16-3 LENGUAJE ENSAMBLADOR 80386 les cmp jne call jmp di,[cs:BandError] [byte ptr es:di],0 @@60 vacia short @@60 PRÁCTICA 16 ;Brinca si error critico ;está activo ;manda buffer al disco ;y sale Procesa interrupción 17h, función 01h (inicializa impresora). @@40: cmp jne cmp je jmp ah,01h @@50 [cs:puntero],0 @@60 @@30 ;Brinca si AH no es 1 ;sale si el buffer ;está vacío ;lo manda al disco, si no ;Procesa interrupción 17h, función 02h (trae estado de impresora). @@50: mov cmp je @@60: mov pop pop iret di,[cs:puntero] di,[cs:largo] @@70 ;trae puntero del buffer ;¿está el buffer lleno? ;Error si así es ah,90h es di ;Retorna señal de OK en AH ;Restaura ES y DI ;Retorna de la interrupción @@70: mov pop pop iret ah,08h es di ENDP IntImpre ;INTDOS manipula interrupción 21h. PROC IntDOS ;Retorna de la interrupción pushf cmp [cs:puntero],0 je @@20 push push cmp jne les cmp jne les cmp jne ;Retorna error de E/S en AH ;Restaura ES y DI di es [cs:BandInt],0 @@10 di,[cs:EnDOS] [byte ptr es:di],0 @@10 di,[cs:BandError] [byte ptr es:di],0 @@10 AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS ;Salva banderas ;salva si el buffer está ;vacío ;Brinca si una interrupción ;de disco está activa ;Brinca si bandera En DOS ;está activa ;Brinca si error critico ;está vigente 16-4 LENGUAJE ENSAMBLADOR 80386 call @@10: pop pop @@20: popf jmp ENDP vacia ;salva el buffer en archivo es di ;Restaura registros ;Restaura banderas ;sale a manejador original [cs:int21h] IntDOS ; INTDOSOCIOSO PROC PRÁCTICA 16 manipula interrupción 28h. IntDOSOcioso pushf call [cs:int28h] cli cmp je FAR ;salva banderas ;llama manejador previo ;Deshabilita interrupciones [cs:puntero],0 @@99 ;sale si el buffer ;está vacío cmp jne push push les cmp pop pop jne call @@99: iret [cs:BandInt],0 @@99 di es di,[cs:BandError] [byte ptr es:di],0 es di @@99 vacia ;Brinca si una interrupción ;de disco esta activa ;Salva ES y DI ENDP IntDOSOcioso ;INTDISCO manipula interrupción 13h. PROC IntDisco pushf or popf pushf call pushf and popf ret ENDP pushf or ;sale si la bandera está activa ;si no, salva buffer ;Retorna desde interrupción FAR ;Salva banderas ;pone bandera de disco ;Retira banderas ;salva banderas ;llama manejador previo ;Salva banderas ;limpia bandera de disco ;Retira banderas ;Retorno con banderas intactas [cs:BandInt],02h [cs:int13h] [cs:BandInt],0FDh 2 IntDisco ;INTLECTURAABS PROC ;Checa el estado de bandera ;de error critico ;Restaura ES y DI manipula interrupción 25h. IntLecturaAbs [cs:BandInt],04h AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS FAR ;Salva banderas ;pone bandera de disco 16-5 LENGUAJE ENSAMBLADOR 80386 popf call pushf and popf ret ENDP [cs:int25h] [cs:BandInt],0FBh PRÁCTICA 16 ;Retira banderas ;llama manejador previo ;Salva banderas ;limpia bandera de disco ;Retira banderas ;Retorna con banderas en pila IntLecturaAbs ;INTESCRABS manipula interrupción 26h. PROC IntEscrAbs FAR pushf or [cs:BandInt],08h popf call [cs:int26h] pushf and [cs:BandInt],0F7h popf ret ENDP IntEscrAbs ;Salva banderas ;pone bandera de disco ;Retira banderas ;llama manejador previo ;Salva banderas ;limpia bandera de disco ;Retira banderas ;Retorna con banderas en pila ; MPLEX_INT manipula interrupción 2FH. Si, de entrada, AH esta puesto con el ;numero ID de multiplexaje de DESVIA, MPLEX_INT usa el valor en AL como función ;Las funciones soportadas son: ; ; 00h Retorna FFh en AL para indicar que el programa esta instalado ; y retorna la dirección de su firma en ES:DI. ; ; 01h Retorna el numero de impresora actualmente redirigida ; (0, 1, or 2) en AL, o FFh si ninguna lo esta. Si AL ; contiene 0, 1, or 2, entonces ES:DI tiene la dirección del ; nombre del archivo de salida al cual se redirige. ; ; 02h Acepta el numero de la impresora a ser redirigida (0, 1, ; o 2) en BL y la dirección de un nombre de archivo en DS:SI. FFh ; cancela la redirección. Esta función causa que el buffer de salida ; sea vaciado. PROC IntMplex far pushf cmp ah,[cs:numeroID] je @@10 popf jmp [cs:int2Fh] ;Salva registro de banderas ;Brinca si AH tiene el ;número ID de multiplexar ;Repone banderas ;Ejecuta la interrupción ;Funcion 00h verifica si el programa está instalado. @@10: popf or jnz mov push pop mov al,al @@20 al,0FFh cs es di,offset firma AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS ;Repone banderas ;Brinca si código de función ;es diferente a 00h ;pone AL a FFH ;apunta ES:DI a firma ;del programa 16-6 LENGUAJE ENSAMBLADOR 80386 iret PRÁCTICA 16 ;Retorna de la interrupción ;Funcion 01h reporta el estatus de la redirección. @@20: cmp jne mov push pop mov iret al,01h @@30 al,[cs:PtoSerie] cs es di,offset NomArch ;Brinca si código de función ;es otro que 01h ;pone número de impresora en AL ;apunta con ES al segmento ;apunta DI a nombre de archivo ;Retorna de la interrupción ;Función 02h designa una nueva impresora o nombre de arch. para redirección. @@30: cmp je call @@40: mov cmp je push push pop mov cld @@50: movsb cmp jne pop @@99: iret ENDP [cs:puntero],0 @@40 vacia ;Brinca si buffer de ;salida está vacío ;manda buffer al disco [cs:PtoSerie],bl bl,0FFh @@99 es cs es di,offset NomArch ;Salva numero de impresora ;Brinca si la redirección ;está cancelada ;Salva ES ;apunta con ES a este segmento [byte ptr si-1],0 @@50 es ;apunta DI a nombre de archivo ;limpia bandera de dirección ;Copia un carácter ;¿Fue un cero? ;No, entonces salta para atrás ;Restaura ES ;Retorna de la interrupción IntMplex ;VACIA vacia el buffer. PROC push vacia ax bx cx dx ds ;Salva registros mov ax,cs mov ds,ax asume ds:_text ;apunta con DS al segmento ;de código mov mov mov mov sti [ds:contador],91 ax,[ds:puntero] [ds:bytes],ax [ds:puntero],0 ;Repone el contador ;Retira puntero del buffer ;lo salva para después ;Repone el puntero ;permite interrupciones call jc AbreArch @@99 ;intenta abrir el archivo ;Brinca si falla AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS 16-7 LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16 mov bx,ax ;Transfiere handle a BX mov xor mov int ax,4202h cx,cx dx,cx 21h ;Mueve puntero de archivo ;al fin del mismo mov mov xor mov ah,40h cx,[ds:bytes] dx,dx ds,[ds:SegBuf] assume ds:nothing int 21h ;Copia buffer de salida ;al disco mov int ah,3Eh 21h ;Cierra archivo @@99: pop ret ds dx cx bx ax ;Restaura registros y sale ENDP vacia ;ABREARCH intenta abrir o crear el archivo de la redirección. ;De retorno, el acarreo se limpia si el intento fue exitoso y el handle ;del archivo esta en AX. El acarreo en "1" implica que algo fallo. De ;entrada, DS debe apuntar al segmento de código. PROC mov mov int jnc AbreArch ax,3D01h dx,offset NomArch 21h @@10 mov xor mov int ax,4301h cx,cx dx,offset NomArch 21h ;intenta quitar todos los ;atributos del archivo mov mov int jnc ax,3D01h dx,offset NomArch 21h @@10 ;reintenta abrirlo ;para escritura mov xor mov int jnc ah,3Ch cx,cx dx,offset NomArch 21h @@10 ;intenta crear el archivo ;como nuevo stc ret @@10: clc ret AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS ;intenta abrir el archivo ;para escritura ;Brinca si se pudo ;Brinca si lo logro ;Brinca si hecho ;pone bandera CF y sale ;retorno ;limpia bandera de acarreo ;y sale 16-8 LENGUAJE ENSAMBLADOR 80386 ENDP PRÁCTICA 16 AbreArch LABEL FIN ;Datos que se descartan al quedar residente en memoria derechos db db db "DESVÍA 2.1 captura salida a impresora",13,10 "De: Seminario de Lenguaje ensamblador 80386" 13,10,13,10,"$" ayudar db db db db db db db db db "Captura salida a impresora en un archivo.",13,10,13,10 "DESVÍA [PRNn[:]=[[d:][ruta]NomArch]] [/B=largo] " "[/C]",13,10,13,10 Especifica el número de impresora.",13,10 " PRNn "/B=largo especifica el tamaño del buffer interno " "en kilobytes (default=4K).",13,10 Cancela redirección.",13,10,13,10 "/C "Al correr DESVÍA sin parámetros se exhibe " "el estado de la redirección.",13,10,"$" msjerr1 db db "Sintaxis: DESVÍA [PRNn[:]=[[d:][ruta]NomArch]] " "[/B=largo] [/C]",13,10 msjerr6 msjerr7 msjerr8 db db db db db db db db db db db db "o bien:",13,10,13,10 "DESVÍA [/?]",13,10,13,10,"$" "Requiere DOS 4.0 o superior",13,10,"$" "el largo del buffer permanece fijo una vez instalado" 13,10,"$" " largo de buffer invalido (mínimo = 2, máximo = 32)" 13,10,"$" " numero de impresora invalido (debe ser PRN1, PRN2, PRN3)" 13,10,"$" "El archivo no se pudo abrir",13,10,"$" "El programa no se pudo instalar",13,10,"$" "Memoria insuficiente",13,10,"$" msg1 msg2 msg3 db db db "DESVÍA instalado",13,10,"$" "Ningún impresora actualmente redirigida",13,10,"$" "PRNn: esta ahora redirigida a $" instalado DirFinL db dw 0 0 msjerr2 msjerr3 Crnl. msjerr4 msjerr5 ;0 = No instalado ;dirección de fin de línea ;INICIO hace al programa residente en memoria. Assume ds:_text PROC inicio cld mov call jnc si,81h BuscaAyuda @@10 AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS ;limpia bandera de dirección ;apunta SI a línea de comando ;barre por la opción /? ;Brinca si no lo halla 16-9 LENGUAJE ENSAMBLADOR 80386 mov mov int mov int @@10: mov mov int PRÁCTICA 16 ah,09h dx,offset ayudar 21h ax,4C00h 21h ;exhibe mensaje de ayuda ;y sale ah,09h dx,offset derechos 21h ;exhibe mensaje de derechos ;Coteja versión de DOS y ve si programa ya esta instalado. mov mov int cmp jae dx,offset msjerr2 ah,30h 21h al,4 @@20 ;sale si versión de DOS ;es menor que 4.0 mov int mov int ah,09h 21h ax,4C01h 21h ;exhibe mensaje de error y ;sale con ERRORLEVEL=1 es coteja @@30 [ds:instalado],1 [ds:numeroID],ah ;Salva ES ;ver si copia esta instalada ;Brinca si no ;pone bandera si ;también salva número ID error: @@20: push call jnc mov mov @@30: pop ;Repone ES ;Pasa todo a mayúsculas en la línea de comando. @@40: mov mov xor jcxz @@50: cmp jb cmp ja and @@60: inc loop @@65: mov si,81h cl,[ds:si-1] ch,ch @@ ;apunta SI a línea de comando ;CL = Número de caracteres ;Convierte byte a palabra CX ;hecho si CX = 0 [byte ptr si],"a" @@60 [byte ptr si],"z" @@60 [byte ptr si],0DFh ;lo deja si menor que "a" si @@50 ;Avanza SI ;sigue hasta terminar si,81h ;Repone SI ;lo deja si mayor que "z" ;la hace mayúscula ; analiza la línea de comando. AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS 16-10 LENGUAJE ENSAMBLADOR 80386 @@70: call jnc jmp @@75: cmp jne PRÁCTICA 16 HallaCar @@75 hecho ;Halla parámetro ;Brinca si no fin de línea ;sale del lazo de análisis [byte ptr si],"/" @@100 ;Brinca si el carácter ;no es una diagonal ;Procesa la opción /B. Inc Lodsb Cmp Jne Cmp Mov Jne lodsb cmp mov jne cal mov jc cmp jb cmp ja xor mov shl or jnz dec @@80: mov shr mov jmp si al,"B" @@90 [ds:instalado],0 dx,offset msjerr3 error al,"=" dx,offset msjerr1 error AscABin dx,offset msjerr4 error al,2 error al,32 error ah,ah cl,10 ax,cl ax,ax @@80 ax [ds:largo],ax ax,1 [ds:mitad],ax @@70 ;Avanza SI ;obtiene carácter ;Brinca si no es una "B" ;Error si /B dado con el ;programa ya instalado ;trae siguiente carácter ;Error si no es "=" ;trae el número tras el "=" ;sale si hubo error ;en la conversión ;Error si menor que 2 ;Error si mayor que 32 ;Computa largo del buffer ;en bytes corriendo ;AX a la izquierda 10 bits ;Brinca si no igual a 0 ;pone AX a FFFFH ;salva largo del buffer ;Divide largo del buffer por 2 ;lo registra ;Retorna a lazo de análisis ;Procesa la opción /C. @@90: mov cmp jne mov jmp dx,offset msjerr1 al,"C" error1 [ds:PtoSerie],0FFh @@70 ;Inicia puntero de error ;Error si no es una "C" ;Cancela redirección ;Retorna a lazo interno ;Procesa un numero PRN de puerto. @@100: mov mov dx,offset msjerr1 di,offset msjerr1+18 AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS ;Inicia puntero de error ;Punto DI a "PRN" 16-11 LENGUAJE ENSAMBLADOR 80386 mov repe jne cx,3 cmpsb error1 mov lodsb cmp jb cmp ja sub mov dx,offset msjerr5 al,"1" error1 al,"3" error1 al,31h [ds:PtoSerie],al mov cmp jne cmp je inc dx,offset msjerr1 [byte ptr si],":" @@110 [byte ptr si],0Dh error1 si @@110: lodsb cmp al,"=" jne error1 PRÁCTICA 16 ;carga CX con cuenta ;Compara cadenas ;Error si no iguales ;Inicia puntero de error ;trae número de puerto ;Error si menor que "1" ;Error si mayor que "3" ;Convierte a número de puerto ;lo salva ;Inicia puntero de error ;¿es siguiente carácter dos puntos? ;No, entonces brinca ;Error si fin de línea ;Salta dos puntos ;trae siguiente carácter ;Error si no "=" ;Procesa nombre de archivo que va con el número del puerto. push call jc mov @@120 mov pop mov mov int jnc si HallaDelim @@120 [ds:DirFinL],si ;salva dirección de cadena ;halla fin de cadena ;Brinca si fin de línea ;Salva dirección de fin de línea [byte ptr si],0 si di,offset NomArch ah,60h 21h @@130 ;Convierte a cadena ASCIIZ ;Retira dirección de cadena ;apunta DI a nombre de archivo ;y lo convierte en ;nombre de archivo ;Brinca si no error mov dx,offset msjerr6 ;sale si error jmp error error2: error1: @@130: call jc AbreArch error2 ;intenta abrir archivo mov mov int bx,ax ah,3Eh 21h ;cierra el archivo cmp je [ds:DirFinL],0 hecho ;¿llegó a fin de línea? ;Si, sale del análisis AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS 16-12 LENGUAJE ENSAMBLADOR 80386 mov inc jmp si,[ds:DirFinL] si @@70 PRÁCTICA 16 ;apunta SI a fin de NomArch ;Avanza tras del byte nulo ;regresa por mas ; Aquí llega cuando el análisis termina. hecho: cmp jne cmp Jne Inc jmp [ds:instalado],0 @@140 [ds:PtoSerie],0Feh instala [ds:PtoSerie] short instala ;Brinca si el programa ya ;está instalado ;¿número de puerto igual a FEH? ;No, entonces ir a instalar ;pone número de puerto a FFH ;ir instalar @@140: cmp je mov mov mov mov int [ds:PtoSerie],0Feh @@150 ah,[ds:numeroID] al,02h bl,[ds:PtoSerie] si,offset NomArch 2Fh ;¿número de puerto igual a FEH? ;si, entonces ya la hicimos ;envía nuevo no. de impresora ;y nombre de archivo a una ;copia instalada del ;programa @@150: call mov int SacaEstado ax,4C00h 21h ;exhibe estado de redirección ;sale con ERRORLEVEL=0 ;Instala el programa. instala: call mov jc mov mov int mov mov mplex_id dx,offset msjerr7 error1 [ds:numeroID],ah ah,34h 21h [word ds:EnDOS],bx [word ds:EnDOS+2],es ;Busca número múltiplex ID ;Error si ninguno disponible push mov int mov mov pop mov jc ds ax,5D06h 21h [word ds:BandError],si [word ds:BandError+2],ds ds dx,offset msjerr7 error1 ;Salva DS ;Obtiene y salva la dirección ;de bandera de error critico mov int mov mov mov ax,3508h 21h [word ds:int08h],bx [word ds:int08h+2],es ax,2508h ;Cambia interrupción 08h ;para IRQ0 (tic del reloj) AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS ;Salva numero ID ;Trae y salva la dirección de ;la bandera En DOS ;Restaura DS ;Error si función retorna ;con acarreo en "1" 16-13 LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16 mov int dx,offset IntReloj 21h mov int mov mov mov mov int ax,3513h 21h [word int13h],bx [word int13h+2],es ax,2513h dx,offset IntDisco 21h ;Cambia interrupción 13h ;de servicios de disco ;del BIOS mov int mov mov mov mov int ax,3517h 21h [word int17h],bx [word int17h+2],es ax,2517h dx,offset IntImpre 21h ;Cambia interrupción 17h ;de servicios de impresora ;del BIOS mov int mov mov mov mov int ax,3521h 21h [word int21h],bx [word int21h+2],es ax,2521h dx,offset IntDOS 21h ;Cambia interrupción 21h ;de llamado a DOS mov int mov mov mov mov int ax,3525h 21h [word int25h],bx [word int25h+2],es ax,2525h dx,offset IntLecturaAbs 21h ;Cambia interrupción 25h ;de lectura absoluta ;a disco mov ax,3526h int 21h mov [word int26h],bx mov [word int26h+2],es mov ax,2526h mov dx,offset IntEscrAbs int 21h ;Cambia interrupción 26h ;de escritura absoluta ;a disco mov int mov mov mov mov int ax,3528h 21h [word int28h],bx [word int28h+2],es ax,2528h dx,offset IntDOSOcioso 21h ;Cambia interrupción 28h ;de manejo de tiempo muerto ;del DOS mov int mov ax,352Fh 21h [word int2Fh],bx ;Cambia interrupción 2Fh ;de manejo de programas ;residentes AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS 16-14 LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16 mov mov mov int [word int2Fh+2],es ax,252Fh dx,offset IntMplex 21h mov mov int ah,49h es,[ds:2Ch] 21h ;trae dirección del segmento del ;bloque de ambiente ;y libera el segmento mov mov shr inc mov mov int ah,4Ah bx,offset FIN bx,4 bx cx,cs es,cx 21h ;encoge el bloque memoria ah,48h bx,[largo] cl,4 bx,cl bx 21h dx,offset msjerr8 no_error error ;pide un nuevo bloque ;de memoria para el buffer ;de datos [SegBuf],ax ;Salva dirección del segmento mov mov int call ah,09h dx,offset msg1 21h SacaEstado ;saca mensaje certificando ;la instalación mov mov shr inc int ax,3100h dx,offset FIN dx,4 dx 21h inicio ;Termina con función 31h mov mov mov shr inc int mov jnc jmp no_error: mov ENDP ;donde el programa está ;cargado ;Error si no hay ;suficiente memoria ;Saca estado de redirección ;HALLACAR avanza SI al siguiente carácter. Al retornar, el acarreo puesto ;indica que el fin de la línea fue alcanzado. PROC HallaCar Lodsb cmp je cmp je cmp je dec cmp al,09h HallaCar al,20h HallaCar al,2Ch HallaCar s al,0Dh AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS ;trae el siguiente carácter ;más si es tabulador ;más si es espacio ;más si es coma ;apunta SI al carácter ;sale con acarreo puesto 16-15 LENGUAJE ENSAMBLADOR 80386 je @@99 clc ret ;si línea fue alcanzado ;limpia acarreo y sale @@99: stc ret ENDP PRÁCTICA 16 ;pone acarreo y sale HallaCar ;HALLADELIM avanza SI al siguiente carácter blanco. Al retornar, ;CF = "1" indica que el fin de la línea fue alcanzado. PROC HallaDelim lodsb cmp je cmp je cmp je cmp jne dec stc ret @@99: dec clc ret ENDP al,09h @@99 al,20h @@99 al,2Ch @@99 al,0Dh HallaDelim ;trae el siguiente carácter ;sale si tabulador ;sale si es espacio ;sale si es coma ;hace más si fin ;de línea no alcanzado si ;pone acarreo y sale si ;limpia acarreo y sale HallaDelim ;BUSCAAYUDA barre la línea de comando por la opción /?. Si la halla, ;retorna con 1 en CF y SI contiene sesgo de la opción. Si no lo ;haya, acarreo = "0" PROC Push @@10: lodsb cmp je cmp jne cmp jne add sub stc ret BuscaAyuda si al,0Dh @@99 al,"?" @@10 [byte ptr si-2],"/" @@10 sp,2 si,2 AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS ;Salva SI ;trae un carácter ;sale si fin de línea ;más si no "?" ;más si no "/" ;limpia la pila ;Ajusta SI ;pone acarreo y sale 16-16 LENGUAJE ENSAMBLADOR 80386 @@99: pop clc ret ENDP si PRÁCTICA 16 ;Restaura SI ;limpia acarreo y sale BuscaAyuda ;COTEJA retorna acarreo puesto si el programa ya esta instalado, ;o acarreo limpio si no. Si CF retorna en "1", AH tiene el numero ;ID multiplex del programa. PROC Mov Mov @@10: push push xor mov int cmp jne coteja ax,0C000h cx,40h ;Inicia AH y AL ;Inicia cuenta ax cx di,di es,di 2Fh al,0FFh @@20 ;Salva AX y CX mov mov repe jne si,offset firma cx,14 cmpsb @@20 ;ver si la firma del programa ;aparece en la dirección ;retornada en ES:DI ;Brinca si no está pop pop stc ret cx ax ;limpia la pila y sale ;con acarreo puesto cx ax ah @@10 ;Retira AX y CX @@20: pop pop inc loop clc ret ENDP ;hace ES y DI cero ;Interrupción 2Fh ;nada aquí si AL no es ;igual a FFH ;siguiente ID de multiplex ;sigue hasta terminar ;sale con acarreo limpio coteja ;MPLEX_ID busca un numero ID de multiplex no usado. Si halla uno, ;lo retorna en AH con el acarreo limpio. Acarreo = "1" indica que ;no hay números ID actualmente disponibles. PROC Mov Mov mplex_id ax,0C000h cx,40h push push ax cx ;Inicia AH y AL ;Inicia cuenta @@10 AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS ;Salva AX y CX 16-17 LENGUAJE ENSAMBLADOR 80386 int or jz pop pop inc loop tc ret @@20: op op ic ret ENDP PRÁCTICA 16 2Fh al,al @@20 cx ax ah @@10 ;Interrupción 2Fh ;Brinca si AL = 0 x x ;la pila y sale ;acarreo limpio ;Retira AX y CX ;Incrementa numero ID ;sigue hasta acabar ;con CF puesto lex_id ;AscABin convierte un numero decimal entrado en forma ASCII en un valor ;binario en AL. El acarreo puesto al retornar indica que hubo error en ;la conversión. PROC xor xor mov AscABin ax,ax bh,bh dl,10 ;Inicia registros @@10: mov inc cmp je cmp je cmp je cmp je bl,[si] si al,09h @@99 bl,20h @@99 bl,2Ch @@99 bl,0Dh @@99 ;trae un carácter cmp jb cmp ja bl,"0" @@20 bl,"9" @@20 ;Error si carácter no es ;un número mu jc sub add cmp jna dl @@20 bl,30h ax,bx ax,255 @@10 ;Multiplica valor en AL por ;10 y sale si hay sobre flujo ;ASCII => binario ;suma último valor a AX ;Error si suma > 255 ;más hasta acabar @@20: dec stc ret AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS ;sale si es tabulador ;sale si es espacio ;sale si es coma ;sale si es retorno de carro ;pone acarreo y sale 16-18 LENGUAJE ENSAMBLADOR 80386 @@99: dec clc ret ENDP si PRÁCTICA 16 ;limpia acarreo y sale AscABin ;SACAESTADO exhibe el estado actual de redirección de impresoras. PROC Cmp Je SacaEstado [instalado],0 @@10 ;ver si programa ya instalado ;Brinca si no mov mov int jmp ah,[numeroID] al,01h 2Fh short @@20 ;Usa la interrupción multiplex ;(función 01h) para hallar ;cuál impresora (si hay) está ;redirigida mov mov mov mov al,[PtoSerie] bx,cs es,bx di,offset NomArch ;trae número de impresora ;apunta ES a este segmento @@20: cmp jne mov mov int ret al,0FFh @@30 ah,09h dx,offset msg2 21h ;Brinca si una impresora está ;actualmente redirigida ;saca aviso "Ninguna impresora ;redirigida" ;y sale @@30: add mov mov mov int call mov mov int ret al,31h [msg3+3],al dx,offset msg3 ah,09h 21h dos_out ah,09h dx,offset rcnl 21h ;Convierte número de impresora ;a ASCII y lo salva ;exhibe nombre de impresora ENDP SacaEstado @@10 ;apunta DI a nombre de archivo ;exhibe nombre de archivo ;fin de línea ;DOS_OUT saca la cadena ASCIIZ apuntada por ES:DI. PROC mov or jz mov int inc jmp dos_out dl,[es:di] dl,dl @@99 ah,02h 21h di dos_out AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS ;trae un carácter ;sale si es cero ;salida usando DOS ;función 02h ;Avanza DI al siguiente ;sigue hasta acabar 16-19 LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16 @@99: ret ENDP dos_out ENDS end salto 3.2 Formar el programa DESVIA.COM con los siguientes comandos: C\SEM386>tasm desvia C\SEM386>tlink /t desvia 3.3 Ejecutar DESVIA enrutando la impresora 1 al archivo SALIDA.PRN mediante: C:\SEM386>desvia prn1=salida.prn /B=8 Mandar ahora un archivo tipo texto a LPT1 o ejecutar ImprPant: y al terminar exhibir SALIDA.PRN en la pantalla. 3.4 Ejecutar el programa DESVIA de nuevo, dando la opción /C para cancelar la redirección: C:\SEM386>desvia /C EJEMPLO DE CORRIDA DE DESVIA CAPTURADA CON EL MISMO DESVIA: C:\>cd sem386 C:\SEM386>del salida.prn No se encontró el archivo C:\SEM386>desvia prn1=salida.prn DESVIA 2.1 captura salida a impresora De: Seminario de Lenguaje ensamblador 80386 DESVIA instalado PRN1: esta ahora redirigida a C:\SEM386\SALIDA.PRN C:\SEM386>dir *.lib/w El volumen de la unidad C es MS-DOS_6 El número de serie del volumen es 15CF-351C Directorio de C:\SEM386 A387.LIB CASIO.LIB MYSTUFF.LIB TAM.LIB REM.LIB 7 archivo(s) 139,046 bytes 129,130,496 bytes libres NOR.LIB PF.LIB C:\SEM386>desvia DESVIA 2.1 captura salida a impresora AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS 16-20 LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16 De: Seminario de Lenguaje ensamblador 80386 PRN1: esta ahora redirigida a C:\SEM386\SALIDA.PRN C:\SEM386>desvia /? Captura salida a impresora en un archivo. DESVIA [PRNn[:]=[[d:][ruta]NomArch]] [/B=largo] [/C] PRNn Especifica el número de impresora. /B=largo especifica el tamaño del buffer interno en kilobytes (default =4 K). /C Cancela redirección. Al correr DESVIA sin parámetros se exhibe el estado de la redirección. C:\SEM386>desvia /B=5 DESVIA 2.1 captura salida a impresora De: Seminario de Lenguaje ensamblador 80386 el largo del buffer permanece fijo una vez instalado C:\SEM386>desvia /c DESVIA 2.1 captura salida a impresora De: Seminario de Lenguaje ensamblador 80386 Ninguna impresora actualmente redirigida C:\SEM386>desvia DESVIA 2.1 captura salida a impresora De: Seminario de Lenguaje ensamblador 80386 Ninguna impresora actualmente redirigida C:\SEM386>desvia prn1=salida.prn DESVIA 2.1 captura salida a impresora De: Seminario de Lenguaje ensamblador 80386 PRN1: esta ahora redirigida a C:\SEM386\SALIDA.PRN C:\SEM386> C:\SEM386>desvia /c DESVIA 2.1 captura salida a impresora De: Seminario de Lenguaje ensamblador 80386 Ninguna impresora actualmente redirigida C:\SEM386>desvia DESVIA 2.1 captura salida a impresora De: Seminario de Lenguaje ensamblador 80386 Ninguna impresora actualmente redirigida C:\SEM386>desvia prn1=salida.prn DESVIA 2.1 captura salida a impresora De: Seminario de Lenguaje ensamblador 80386 PRN1: esta ahora redirigida a C:\SEM386\SALIDA.PRN C:\SEM386>desvia prn = aa.txt DESVIA 2.1 captura salida a impresora De: Seminario de Lenguaje ensamblador 80386 AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS 16-21 LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16 numero de impresora invalido (debe ser PRN1, PRN2, o PRN3) C:\SEM386> 4. TAREAS 4.1 Modificar DESVIA.ASM para que sólo pueda salvar la salida a impresora en el archivo MMMDD.PRN; donde MMM es la abreviatura del mes y DD corresponde al día es decir que el nombre del archivo se forme automáticamente. 4.2 Hacer un programa ,TOMA, que sea prácticamente una copia de DESVIA pero que, en vez de capturar la salida a impresora, capture la entrada serial de uno de sus puertos COMx. AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS 16-22