Programa residente en memoria

Anuncio
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
Descargar