22
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16 AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS 16-1 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. 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 3. DESARROLLO 3.1 Capturar el siguiente módulo y salvarlo con el nombre DESVIA.ASM. %TITLE "modulo DESVIA.ASM que captura la salida a impresora" ;ensamblar con: TASM desvia ;ligar con TLINK /t desvia IDEAL MODEL tiny ;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.

practica 16 ensamblador 80386

Embed Size (px)

Citation preview

Page 1: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-1

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

3. DESARROLLO

3.1 Capturar el siguiente módulo y salvarlo con el nombre DESVIA.ASM. %TITLE "modulo DESVIA.ASM que captura la salida a impresora" ;ensamblar con: TASM desvia ;ligar con TLINK /t desvia

IDEAL MODEL tiny

;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.

Page 2: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-2

CODESEG assume CS:_text,DS:_text

org 100h

salto:

jmp inicio firma db 0,1,2,"-DESVIA-",2,1,0 ;firma del programa numeroID db ? ;numero para multiplexar int08h dd ? ;vector de interrupción 08h int13h dd ? ;vector de interrupción 13h int17h dd ? ;vector de interrupción 17h int21h dd ? ;vector de interrupción 21h int25h dd ? ;vector de interrupción 25h int26h dd ? ;vector de interrupción 26h int28h dd ? ;vector de interrupción 28h int2Fh dd ? ;vector de interrupción 2Fh BandError dd ? ;dirección de band. de error critico BandInt db 0 ;bandera interrupción de disco EnDOS dd ? ;dirección de bandera en DOS largo dw 4096 ;tamaño del buffer interno mitad dw 2048 ;mitad del buffer puntero dw 0 ;puntero del buffer SegBuf dw ? ;segmento del buffer bytes dw ? ;Numero de bytes en buffer contador db 91 ;contador de tiempo descendente PtoSerie db 0FEh,0 ;puerto PRN Redirigido NomArch db 128 dup (?) ;especificación del archivo

PROC IntReloj FAR

pushf ;salva banderas call [cs:int08h] ;llama manejador previo cli ;Deshabilita interrupciones

cmp [cs:contador],0 ;Brinca si contador je @@10 ;llego a cero dec [cs:contador] ;Decrementa contador jnz @@99 ;sale si no cero cmp [cs:puntero],0 ;Brinca si hay datos jne @@10 ;en el buffer mov [cs:contador],91 ;Repone el contador y sale jmp short @@99 ;si no

@@10:

push di ;Salva ES y DI push es cmp [cs:BandInt],0 ;Brinca si hay interrupción jne @@20 ;de disco

LOJ manipula interrupción 08h.

Page 3: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-3

les di,[cs:EnDOS] ;Brinca si esta en DOS cmp [byte ptr es:di],0 jne @@20 les di,[cs:BandError] ;Brinca si el error crítico cmp [byte ptr es:di],0 ;está activo jne @@20 call vacia ;Salva buffer en archivo

@@20: pop es ;Restaura ES y DI pop di

@@99: iret

ENDP IntReloj PROC IntImpre FAR

cmp [cs:PtoSerie],0FFh ;Brinca si la redirección jne @@20 ;está habilitada

@@10: jmp [cs:int17h] ;salta a rutina del BIOS

@@20:

cmp dx,[word ptr cs:PtoSerie] ;sale si este puerto PRN no esta jne @@10 ;actualmente redirigido cmp ah,03h ;sale si función trae código ja @@10 ;mayor que 03h

push di ;Salva ES y DI push es

or ah,ah ;Brinca si AH no es 0 jnz @@40 mov [cs:contador],91 ;Repone contador de tics mov di,[cs:puntero] ;apunta con DI al buffer cmp di,[cs:largo] ;Error si el buffer está je @@70 ;lleno mov es,[cs:SegBuf] ;apunta con ES al segmento mov [es:di],al ;pone en buffer al carácter inc di ;Incrementa puntero del buffer mov [cs:puntero],di ;Salva nuevo apuntador cmp di,[cs:mitad] ;sale si el buffer esta menos jb @@60 ;que medio lleno

@@30:

cmp [cs:BandInt],0 ;Brinca si bandera de interrupción jne @@60 ;de disco esta puesta les di,[cs:EnDOS] ;Brinca si bandera En DOS cmp [byte ptr es:di],0 ;está puesta jne @@60

;IntImpre manipula interrupción 17h.

;Procesa interrupción 17h, función 00h (transmite carácter a impresora).

Page 4: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-4

les di,[cs:BandError] ;Brinca si error critico cmp [byte ptr es:di],0 ;está activo jne @@60 call vacia ;manda buffer al disco jmp short @@60 ;y sale

@@40:

cmp ah,01h ;Brinca si AH no es 1 jne @@50 cmp [cs:puntero],0 ;sale si el buffer je @@60 ;está vacío jmp @@30 ;lo manda al disco, si no

@@50:

mov di,[cs:puntero] ;trae puntero del buffer cmp di,[cs:largo] ;¿está el buffer lleno? je @@70 ;Error si así es

@@60: mov ah,90h ;Retorna señal de OK en AH pop es ;Restaura ES y DI pop di iret ;Retorna de la interrupción

@@70:

mov ah,08h ;Retorna error de E/S en AH pop es ;Restaura ES y DI pop di iret ;Retorna de la interrupción

ENDP IntImpre PROC IntDOS

pushf ;Salva banderas cmp [cs:puntero],0 ;salva si el buffer está je @@20 ;vacío

push di push es cmp [cs:BandInt],0 ;Brinca si una interrupción jne @@10 ;de disco está activa les di,[cs:EnDOS] ;Brinca si bandera En DOS cmp [byte ptr es:di],0 ;está activa jne @@10 les di,[cs:BandError] ;Brinca si error critico cmp [byte ptr es:di],0 ;está vigente jne @@10

Procesa interrupción 17h, función 01h (inicializa impresora).

;Procesa interrupción 17h, función 02h (trae estado de impresora).

;INTDOS manipula interrupción 21h.

Page 5: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-5

call vacia ;salva el buffer en archivo @@10:

pop es ;Restaura registros pop di

@@20:

popf ;Restaura banderas jmp [cs:int21h] ;sale a manejador original

ENDP IntDOS PROC IntDOSOcioso FAR

pushf ;salva banderas call [cs:int28h] ;llama manejador previo cli ;Deshabilita interrupciones

cmp [cs:puntero],0 ;sale si el buffer je @@99 ;está vacío

cmp [cs:BandInt],0 ;Brinca si una interrupción jne @@99 ;de disco esta activa push di ;Salva ES y DI push es les di,[cs:BandError] ;Checa el estado de bandera cmp [byte ptr es:di],0 ;de error critico pop es ;Restaura ES y DI pop di jne @@99 ;sale si la bandera está activa call vacia ;si no, salva buffer

@@99: iret ;Retorna desde interrupción

ENDP IntDOSOcioso ;INTDISCO manipula interrupción 13h. PROC IntDisco FAR

pushf ;Salva banderas or [cs:BandInt],02h ;pone bandera de disco popf ;Retira banderas pushf ;salva banderas call [cs:int13h] ;llama manejador previo pushf ;Salva banderas and [cs:BandInt],0FDh ;limpia bandera de disco popf ;Retira banderas ret 2 ;Retorno con banderas intactas

ENDP IntDisco ;INTLECTURAABS manipula interrupción 25h. PROC IntLecturaAbs FAR

pushf ;Salva banderas or [cs:BandInt],04h ;pone bandera de disco

; INTDOSOCIOSO manipula interrupción 28h.

Page 6: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-6

popf ;Retira banderas call [cs:int25h] ;llama manejador previo pushf ;Salva banderas and [cs:BandInt],0FBh ;limpia bandera de disco popf ;Retira banderas ret ;Retorna con banderas en pila

ENDP IntLecturaAbs ;INTESCRABS manipula interrupción 26h. PROC IntEscrAbs FAR

pushf ;Salva banderas or [cs:BandInt],08h ;pone bandera de disco popf ;Retira banderas call [cs:int26h] ;llama manejador previo pushf ;Salva banderas and [cs:BandInt],0F7h ;limpia bandera de disco popf ;Retira banderas ret ;Retorna con banderas en pila

ENDP IntEscrAbs ; 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 ;Salva registro de banderas cmp ah,[cs:numeroID] ;Brinca si AH tiene el je @@10 ;número ID de multiplexar popf ;Repone banderas jmp [cs:int2Fh] ;Ejecuta la interrupción

;Funcion 00h verifica si el programa está instalado. @@10:

popf ;Repone banderas or al,al ;Brinca si código de función jnz @@20 ;es diferente a 00h mov al,0FFh ;pone AL a FFH push cs ;apunta ES:DI a firma pop es ;del programa mov di,offset firma

Page 7: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-7

iret ;Retorna de la interrupción ;Funcion 01h reporta el estatus de la redirección. @@20:

cmp al,01h ;Brinca si código de función jne @@30 ;es otro que 01h mov al,[cs:PtoSerie] ;pone número de impresora en AL push cs ;apunta con ES al segmento pop es mov di,offset NomArch ;apunta DI a nombre de archivo iret ;Retorna de la interrupción

;Función 02h designa una nueva impresora o nombre de arch. para redirección. @@30:

cmp [cs:puntero],0 ;Brinca si buffer de je @@40 ;salida está vacío call vacia ;manda buffer al disco

@@40: mov [cs:PtoSerie],bl ;Salva numero de impresora cmp bl,0FFh ;Brinca si la redirección je @@99 ;está cancelada push es ;Salva ES push cs ;apunta con ES a este segmento pop es mov di,offset NomArch ;apunta DI a nombre de archivo cld ;limpia bandera de dirección

@@50: movsb ;Copia un carácter cmp [byte ptr si-1],0 ;¿Fue un cero? jne @@50 ;No, entonces salta para atrás pop es ;Restaura ES

@@99: iret ;Retorna de la interrupción

ENDP IntMplex ;VACIA vacia el buffer. PROC vacia

push ax bx cx dx ds ;Salva registros

mov ax,cs ;apunta con DS al segmento mov ds,ax ;de código asume ds:_text

mov [ds:contador],91 ;Repone el contador mov ax,[ds:puntero] ;Retira puntero del buffer mov [ds:bytes],ax ;lo salva para después mov [ds:puntero],0 ;Repone el puntero sti ;permite interrupciones

call AbreArch ;intenta abrir el archivo jc @@99 ;Brinca si falla

Page 8: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-8

mov bx,ax ;Transfiere handle a BX

mov ax,4202h ;Mueve puntero de archivo xor cx,cx ;al fin del mismo mov dx,cx int 21h

mov ah,40h ;Copia buffer de salida mov cx,[ds:bytes] ;al disco xor dx,dx mov ds,[ds:SegBuf] assume ds:nothing int 21h

mov ah,3Eh ;Cierra archivo int 21h

@@99:

pop ds dx cx bx ax ;Restaura registros y sale ret

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 AbreArch

mov ax,3D01h ;intenta abrir el archivo mov dx,offset NomArch ;para escritura int 21h jnc @@10 ;Brinca si se pudo

mov ax,4301h ;intenta quitar todos los xor cx,cx ;atributos del archivo mov dx,offset NomArch int 21h

mov ax,3D01h ;reintenta abrirlo mov dx,offset NomArch ;para escritura int 21h jnc @@10 ;Brinca si lo logro

mov ah,3Ch ;intenta crear el archivo xor cx,cx ;como nuevo mov dx,offset NomArch int 21h jnc @@10 ;Brinca si hecho

stc ;pone bandera CF y sale ret ;retorno

@@10: clc ;limpia bandera de acarreo ret ;y sale

Page 9: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-9

ENDP AbreArch

LABEL FIN ;Datos que se descartan al quedar residente en memoria derechos db "DESVÍA 2.1 captura salida a impresora",13,10 db "De: Seminario de Lenguaje ensamblador 80386" db 13,10,13,10,"$" ayudar db "Captura salida a impresora en un archivo.",13,10,13,10 db "DESVÍA [PRNn[:]=[[d:][ruta]NomArch]] [/B=largo] " db "[/C]",13,10,13,10 db " PRNn Especifica el número de impresora.",13,10 db "/B=largo especifica el tamaño del buffer interno " db "en kilobytes (default=4K).",13,10 db "/C Cancela redirección.",13,10,13,10 db "Al correr DESVÍA sin parámetros se exhibe " db "el estado de la redirección.",13,10,"$" msjerr1 db "Sintaxis: DESVÍA [PRNn[:]=[[d:][ruta]NomArch]] " db "[/B=largo] [/C]",13,10 db "o bien:",13,10,13,10 db "DESVÍA [/?]",13,10,13,10,"$" msjerr2 db "Requiere DOS 4.0 o superior",13,10,"$" msjerr3 db "el largo del buffer permanece fijo una vez instalado" Crnl. db 13,10,"$" msjerr4 db " largo de buffer invalido (mínimo = 2, máximo = 32)" db 13,10,"$" msjerr5 db " numero de impresora invalido (debe ser PRN1, PRN2, PRN3)" db 13,10,"$" msjerr6 db "El archivo no se pudo abrir",13,10,"$" msjerr7 db "El programa no se pudo instalar",13,10,"$" msjerr8 db "Memoria insuficiente",13,10,"$" msg1 db "DESVÍA instalado",13,10,"$" msg2 db "Ningún impresora actualmente redirigida",13,10,"$" msg3 db "PRNn: esta ahora redirigida a $" instalado db 0 ;0 = No instalado DirFinL dw 0 ;dirección de fin de línea ;INICIO hace al programa residente en memoria. Assume ds:_text PROC inicio cld ;limpia bandera de dirección mov si,81h ;apunta SI a línea de comando call BuscaAyuda ;barre por la opción /? jnc @@10 ;Brinca si no lo halla

Page 10: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-10

mov ah,09h ;exhibe mensaje de ayuda mov dx,offset ayudar ;y sale int 21h mov ax,4C00h int 21h @@10: mov ah,09h ;exhibe mensaje de derechos mov dx,offset derechos int 21h ;Coteja versión de DOS y ve si programa ya esta instalado. mov dx,offset msjerr2 ;sale si versión de DOS mov ah,30h ;es menor que 4.0 int 21h cmp al,4 jae @@20 error: mov ah,09h ;exhibe mensaje de error y int 21h ;sale con ERRORLEVEL=1 mov ax,4C01h int 21h @@20: push es ;Salva ES call coteja ;ver si copia esta instalada jnc @@30 ;Brinca si no mov [ds:instalado],1 ;pone bandera si mov [ds:numeroID],ah ;también salva número ID @@30: pop ;Repone ES ;Pasa todo a mayúsculas en la línea de comando. @@40: mov si,81h ;apunta SI a línea de comando mov cl,[ds:si-1] ;CL = Número de caracteres xor ch,ch ;Convierte byte a palabra CX jcxz @@ ;hecho si CX = 0 @@50: cmp [byte ptr si],"a" ;lo deja si menor que "a" jb @@60 cmp [byte ptr si],"z" ;lo deja si mayor que "z" ja @@60 and [byte ptr si],0DFh ;la hace mayúscula @@60: inc si ;Avanza SI loop @@50 ;sigue hasta terminar @@65: mov si,81h ;Repone SI ; analiza la línea de comando.

Page 11: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-11

@@70: call HallaCar ;Halla parámetro jnc @@75 ;Brinca si no fin de línea jmp hecho ;sale del lazo de análisis @@75: cmp [byte ptr si],"/" ;Brinca si el carácter jne @@100 ;no es una diagonal ;Procesa la opción /B. Inc si ;Avanza SI Lodsb ;obtiene carácter Cmp al,"B" ;Brinca si no es una "B" Jne @@90 Cmp [ds:instalado],0 ;Error si /B dado con el Mov dx,offset msjerr3 ;programa ya instalado Jne error lodsb ;trae siguiente carácter cmp al,"=" ;Error si no es "=" mov dx,offset msjerr1 jne error cal AscABin ;trae el número tras el "=" mov dx,offset msjerr4 ;sale si hubo error jc error ;en la conversión cmp al,2 ;Error si menor que 2 jb error cmp al,32 ;Error si mayor que 32 ja error xor ah,ah ;Computa largo del buffer mov cl,10 ;en bytes corriendo shl ax,cl ;AX a la izquierda 10 bits or ax,ax ;Brinca si no igual a 0 jnz @@80 dec ax ;pone AX a FFFFH @@80: mov [ds:largo],ax ;salva largo del buffer shr ax,1 ;Divide largo del buffer por 2 mov [ds:mitad],ax ;lo registra jmp @@70 ;Retorna a lazo de análisis ;Procesa la opción /C. @@90: mov dx,offset msjerr1 ;Inicia puntero de error cmp al,"C" ;Error si no es una "C" jne error1 mov [ds:PtoSerie],0FFh ;Cancela redirección jmp @@70 ;Retorna a lazo interno ;Procesa un numero PRN de puerto. @@100: mov dx,offset msjerr1 ;Inicia puntero de error mov di,offset msjerr1+18 ;Punto DI a "PRN"

Page 12: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-12

mov cx,3 ;carga CX con cuenta repe cmpsb ;Compara cadenas jne error1 ;Error si no iguales mov dx,offset msjerr5 ;Inicia puntero de error lodsb ;trae número de puerto cmp al,"1" ;Error si menor que "1" jb error1 cmp al,"3" ;Error si mayor que "3" ja error1 sub al,31h ;Convierte a número de puerto mov [ds:PtoSerie],al ;lo salva mov dx,offset msjerr1 ;Inicia puntero de error cmp [byte ptr si],":" ;¿es siguiente carácter dos puntos? jne @@110 ;No, entonces brinca cmp [byte ptr si],0Dh ;Error si fin de línea je error1 inc si ;Salta dos puntos @@110: lodsb ;trae siguiente carácter cmp al,"=" ;Error si no "=" jne error1 ;Procesa nombre de archivo que va con el número del puerto. push si ;salva dirección de cadena call HallaDelim ;halla fin de cadena jc @@120 ;Brinca si fin de línea mov [ds:DirFinL],si ;Salva dirección de fin de línea @@120 mov [byte ptr si],0 ;Convierte a cadena ASCIIZ pop si ;Retira dirección de cadena mov di,offset NomArch ;apunta DI a nombre de archivo mov ah,60h ;y lo convierte en int 21h ;nombre de archivo jnc @@130 ;Brinca si no error error2: mov dx,offset msjerr6 ;sale si error error1: jmp error @@130: call AbreArch ;intenta abrir archivo jc error2 mov bx,ax ;cierra el archivo mov ah,3Eh int 21h cmp [ds:DirFinL],0 ;¿llegó a fin de línea? je hecho ;Si, sale del análisis

Page 13: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-13

mov si,[ds:DirFinL] ;apunta SI a fin de NomArch inc si ;Avanza tras del byte nulo jmp @@70 ;regresa por mas ; Aquí llega cuando el análisis termina. hecho: cmp [ds:instalado],0 ;Brinca si el programa ya jne @@140 ;está instalado cmp [ds:PtoSerie],0Feh ;¿número de puerto igual a FEH? Jne instala ;No, entonces ir a instalar Inc [ds:PtoSerie] ;pone número de puerto a FFH jmp short instala ;ir instalar @@140: cmp [ds:PtoSerie],0Feh ;¿número de puerto igual a FEH? je @@150 ;si, entonces ya la hicimos mov ah,[ds:numeroID] ;envía nuevo no. de impresora mov al,02h ;y nombre de archivo a una mov bl,[ds:PtoSerie] ;copia instalada del mov si,offset NomArch ;programa int 2Fh @@150: call SacaEstado ;exhibe estado de redirección mov ax,4C00h ;sale con ERRORLEVEL=0 int 21h ;Instala el programa. instala: call mplex_id ;Busca número múltiplex ID mov dx,offset msjerr7 ;Error si ninguno disponible jc error1 mov [ds:numeroID],ah ;Salva numero ID mov ah,34h ;Trae y salva la dirección de int 21h ;la bandera En DOS mov [word ds:EnDOS],bx mov [word ds:EnDOS+2],es push ds ;Salva DS mov ax,5D06h ;Obtiene y salva la dirección int 21h ;de bandera de error critico mov [word ds:BandError],si mov [word ds:BandError+2],ds pop ds ;Restaura DS mov dx,offset msjerr7 ;Error si función retorna jc error1 ;con acarreo en "1" mov ax,3508h ;Cambia interrupción 08h int 21h ;para IRQ0 (tic del reloj) mov [word ds:int08h],bx mov [word ds:int08h+2],es mov ax,2508h

Page 14: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-14

mov dx,offset IntReloj int 21h mov ax,3513h ;Cambia interrupción 13h int 21h ;de servicios de disco mov [word int13h],bx ;del BIOS mov [word int13h+2],es mov ax,2513h mov dx,offset IntDisco int 21h mov ax,3517h ;Cambia interrupción 17h int 21h ;de servicios de impresora mov [word int17h],bx ;del BIOS mov [word int17h+2],es mov ax,2517h mov dx,offset IntImpre int 21h mov ax,3521h ;Cambia interrupción 21h int 21h ;de llamado a DOS mov [word int21h],bx mov [word int21h+2],es mov ax,2521h mov dx,offset IntDOS int 21h mov ax,3525h ;Cambia interrupción 25h int 21h ;de lectura absoluta mov [word int25h],bx ;a disco mov [word int25h+2],es mov ax,2525h mov dx,offset IntLecturaAbs int 21h mov ax,3526h ;Cambia interrupción 26h int 21h ;de escritura absoluta mov [word int26h],bx ;a disco mov [word int26h+2],es mov ax,2526h mov dx,offset IntEscrAbs int 21h mov ax,3528h ;Cambia interrupción 28h int 21h ;de manejo de tiempo muerto mov [word int28h],bx ;del DOS mov [word int28h+2],es mov ax,2528h mov dx,offset IntDOSOcioso int 21h mov ax,352Fh ;Cambia interrupción 2Fh int 21h ;de manejo de programas mov [word int2Fh],bx ;residentes

Page 15: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-15

mov [word int2Fh+2],es mov ax,252Fh mov dx,offset IntMplex int 21h mov ah,49h ;trae dirección del segmento del mov es,[ds:2Ch] ;bloque de ambiente int 21h ;y libera el segmento mov ah,4Ah ;encoge el bloque memoria mov bx,offset FIN shr bx,4 inc bx mov cx,cs ;donde el programa está mov es,cx ;cargado int 21h mov ah,48h ;pide un nuevo bloque mov bx,[largo] ;de memoria para el buffer mov cl,4 ;de datos shr bx,cl inc bx int 21h mov dx,offset msjerr8 ;Error si no hay jnc no_error ;suficiente memoria jmp error no_error: mov [SegBuf],ax ;Salva dirección del segmento mov ah,09h ;saca mensaje certificando mov dx,offset msg1 ;la instalación int 21h call SacaEstado ;Saca estado de redirección mov ax,3100h ;Termina con función 31h mov dx,offset FIN shr dx,4 inc dx int 21h ENDP inicio ;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 ;trae el siguiente carácter cmp al,09h ;más si es tabulador je HallaCar cmp al,20h ;más si es espacio je HallaCar cmp al,2Ch ;más si es coma je HallaCar dec s ;apunta SI al carácter cmp al,0Dh ;sale con acarreo puesto

Page 16: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-16

je @@99 ;si línea fue alcanzado clc ;limpia acarreo y sale ret @@99: stc ;pone acarreo y sale ret ENDP 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 ;trae el siguiente carácter cmp al,09h ;sale si tabulador je @@99 cmp al,20h ;sale si es espacio je @@99 cmp al,2Ch ;sale si es coma je @@99 cmp al,0Dh ;hace más si fin jne HallaDelim ;de línea no alcanzado dec si ;pone acarreo y sale stc ret @@99: dec si ;limpia acarreo y sale clc ret ENDP 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 BuscaAyuda Push si ;Salva SI @@10: lodsb ;trae un carácter cmp al,0Dh ;sale si fin de línea je @@99 cmp al,"?" ;más si no "?" jne @@10 cmp [byte ptr si-2],"/" ;más si no "/" jne @@10 add sp,2 ;limpia la pila sub si,2 ;Ajusta SI stc ;pone acarreo y sale ret

Page 17: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-17

@@99: pop si ;Restaura SI clc ;limpia acarreo y sale ret ENDP 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 coteja Mov ax,0C000h ;Inicia AH y AL Mov cx,40h ;Inicia cuenta @@10: push ax ;Salva AX y CX push cx xor di,di ;hace ES y DI cero mov es,di int 2Fh ;Interrupción 2Fh cmp al,0FFh ;nada aquí si AL no es jne @@20 ;igual a FFH mov si,offset firma ;ver si la firma del programa mov cx,14 ;aparece en la dirección repe cmpsb ;retornada en ES:DI jne @@20 ;Brinca si no está pop cx ;limpia la pila y sale pop ax ;con acarreo puesto stc ret @@20: pop cx ;Retira AX y CX pop ax inc ah ;siguiente ID de multiplex loop @@10 ;sigue hasta terminar clc ;sale con acarreo limpio ret ENDP 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 mplex_id Mov ax,0C000h ;Inicia AH y AL Mov cx,40h ;Inicia cuenta @@10 push ax ;Salva AX y CX push cx

Page 18: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-18

int 2Fh ;Interrupción 2Fh or al,al ;Brinca si AL = 0 jz @@20 pop cx ;Retira AX y CX pop ax inc ah ;Incrementa numero ID loop @@10 ;sigue hasta acabar tc ;con CF puesto ret @@20: op x ;la pila y sale op x ;acarreo limpio ic ret ENDP 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 AscABin xor ax,ax ;Inicia registros xor bh,bh mov dl,10 @@10: mov bl,[si] ;trae un carácter inc si cmp al,09h ;sale si es tabulador je @@99 cmp bl,20h ;sale si es espacio je @@99 cmp bl,2Ch ;sale si es coma je @@99 cmp bl,0Dh ;sale si es retorno de carro je @@99 cmp bl,"0" ;Error si carácter no es jb @@20 ;un número cmp bl,"9" ja @@20 mu dl ;Multiplica valor en AL por jc @@20 ;10 y sale si hay sobre flujo sub bl,30h ;ASCII => binario add ax,bx ;suma último valor a AX cmp ax,255 ;Error si suma > 255 jna @@10 ;más hasta acabar @@20: dec ;pone acarreo y sale stc ret

Page 19: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-19

@@99: dec si ;limpia acarreo y sale clc ret ENDP AscABin ;SACAESTADO exhibe el estado actual de redirección de impresoras. PROC SacaEstado Cmp [instalado],0 ;ver si programa ya instalado Je @@10 ;Brinca si no mov ah,[numeroID] ;Usa la interrupción multiplex mov al,01h ;(función 01h) para hallar int 2Fh ;cuál impresora (si hay) está jmp short @@20 ;redirigida @@10 mov al,[PtoSerie] ;trae número de impresora mov bx,cs ;apunta ES a este segmento mov es,bx mov di,offset NomArch ;apunta DI a nombre de archivo @@20: cmp al,0FFh ;Brinca si una impresora está jne @@30 ;actualmente redirigida mov ah,09h ;saca aviso "Ninguna impresora mov dx,offset msg2 ;redirigida" int 21h ;y sale ret @@30: add al,31h ;Convierte número de impresora mov [msg3+3],al ;a ASCII y lo salva mov dx,offset msg3 ;exhibe nombre de impresora mov ah,09h int 21h call dos_out ;exhibe nombre de archivo mov ah,09h ;fin de línea mov dx,offset rcnl int 21h ret ENDP SacaEstado ;DOS_OUT saca la cadena ASCIIZ apuntada por ES:DI. PROC dos_out mov dl,[es:di] ;trae un carácter or dl,dl ;sale si es cero jz @@99 mov ah,02h ;salida usando DOS int 21h ;función 02h inc di ;Avanza DI al siguiente jmp dos_out ;sigue hasta acabar

Page 20: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-20

@@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 NOR.LIB PF.LIB TAM.LIB REM.LIB 7 archivo(s) 139,046 bytes 129,130,496 bytes libres

C:\SEM386>desvia DESVIA 2.1 captura salida a impresora

Page 21: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-21

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

Page 22: practica 16 ensamblador 80386

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 16

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS

16-22

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.