;****************************************************************
; //////******Comentarios a [email protected]******* *
;*Sencillo programa para iniciarse en el lenguaje ensamblador *
;*Este programa copia un fichero sobre otro existente, o crea *
;*el fichero de salida. *
;*En Ambos casos desaparece el contenido original del fichero de*
;*Salida , si lo hubiese.
;*Puede ocurrir, que en algunas partes de los registros analizados*
;*con el Debug, no sean coincidentes, con secuencias anteriores. *
;*Esto puede ser debido, a que el ejemplo se ha explicado en *
;*sucesivas ejecuciones del programa. * *
;*****************************************************************
.MODEL SMALL
.STACK
.DATA
;Bloque de datos para la entrada informativa de cabecera
Informativo db 0AH,0DH, '*****//Programa:"COPIA",creado por Berlanga***** '
db 0AH,0DH, '************ (mail) [email protected] *****************************'
db 0AH,0DH,'****COPIA UN FICHERO SOBRE OTRO ,O CREA UN NUEVO FICHERO DE SALIDA****** '
db 0AH,0DH,'*EN DONDE SE ESCRIBE EL CONTENIDO DEL DE ENTRADA, SOBREESCRIBIENDO DATOS*'
db 0AH,0DH,'*ENSAMBLADO CON: Microsoft (R) Macro Assembler Version 6.15.8803. '
db 0AH,0DH, '***********************/-Editado con VASM-*****************************. '
db 0AH,0DH, ' $' ;Esta es una de las muchas formas de dejar espacios en blanco.
;Longitud máxima del nombre de un fichero
Longitud_Nombre_Fichero=40
;
;Tamaño de los bloques de transferencia
Maxima_Longitud_Abrir=4096
;Mensajes que saldran por pantalla para facilitar el desarrollo
;del programa
EscriboMensaje1 db 0AH,0DH,'INTRODUZCA EL FICHERO DE ENTRADA: $'
EscriboMensaje2 db 0AH,0DH,'INTRODUZCA EL NOMBRE DEL FICHERO DE SALIDA: $'
EscriboMensaje3 db 'ERROR:El fichero de destino ya existe'
db 0dh,0ah,'$'
EscriboMensaje4 db 'ERROR: No se puede abrir el fichero de Entrada.'
db 0dh,0ah,'$'
EscriboMensaje5 db 'ERROR: No se puede abrir el fichero de Salida.'
db 0dh,0ah,'$'
EscriboMensaje6 db 'ERROR: de Lectura.', 0dh,0ah,'$'
EscriboMensaje7 db 'ERROR: de Escritura.', 0dh,0ah,'$'
EscriboMensaje8 db '!!!LA COPIA FINALIZO CON EXITO!!!.', 0dh,0ah,'$'
Avanza db 0dh,0ah,'$'
BufferDeEntradaTeclado db Longitud_Nombre_Fichero+1
DB ?
DB Longitud_Nombre_Fichero DUP (?)
;Espacio para las cadenas ASCII con los nombres
FicheroDeEntrada db Longitud_Nombre_Fichero +1 DUP(?)
FicheroDeSalida db Longitud_Nombre_Fichero +1 DUP(?)
;Variables para los Handles de fichero
HandleDeEntrada DW ?
HandleDeSalida DW ?
;Buffer para la copia de Datos
BufferCopiaDeDatos Db Maxima_Longitud_Abrir DUP (?)
;*********************************************************
;En esta parte optenida con debug (DOS) vemos como aparecen los
;datos una vez cargados en parte de la memoria. DESDE 16D6:0020 --> 16D6:0170
;16D6:0020 22 2C 63 72 65 61 64 6F-20 70 6F 72 20 42 65 72 ",creado por Ber
;16D6:0030 6C 61 6E 67 61 5C 5C 2A-2A 2A 2A 2A 20 0A 0D 2A langa***** ..*
;16D6:0040 2A 2A 2A 2A 2A 2A 2A 2A-2A 2A 2A 20 28 6D 61 69 *********** (mai
;16D6:0050 6C 29 20 62 65 72 6C 61-6E 67 61 32 32 40 68 6F l) berlanga22@ho
;16D6:0060 74 6D 61 69 6C 2E 63 6F-6D 20 2A 2A 2A 2A 2A 2A tmail.com ******
;16D6:0070 2A 2A 2A 2A 2A 2A 2A 2A-2A 2A 2A 2A 2A 2A 2A 2A ****************
;-d
;16D6:0080 2A 2A 2A 2A 2A 2A 2A 0A-0D 2A 2A 2A 2A 43 4F 50 *******..****COP
;16D6:0090 49 41 20 55 4E 20 46 49-43 48 45 52 4F 20 53 4F IA UN FICHERO SO
;16D6:00A0 42 52 45 20 4F 54 52 4F-20 2C 4F 20 43 52 45 41 BRE OTRO ,O CREA
;16D6:00B0 20 55 4E 20 4E 55 45 56-4F 20 46 49 43 48 45 52 UN NUEVO FICHER
;16D6:00C0 4F 20 44 45 20 53 41 4C-49 44 41 2A 2A 2A 2A 2A O DE SALIDA*****
;16D6:00D0 2A 20 0A 0D 2A 45 4E 20-44 4F 4E 44 45 20 53 45 * ..*EN DONDE SE
;16D6:00E0 20 45 53 43 52 49 42 45-20 45 4C 20 43 4F 4E 54 ESCRIBE EL CONT
;16D6:00F0 45 4E 49 44 4F 20 44 45-4C 20 44 45 20 45 4E 54 ENIDO DEL DE ENT
;-d
;16D6:0100 52 41 44 41 2C 20 53 4F-42 52 45 45 53 43 52 49 RADA, SOBREESCRI
;16D6:0110 42 49 45 4E 44 4F 20 44-41 54 4F 53 2A 0A 0D 2A BIENDO DATOS*..*
;16D6:0120 45 4E 53 41 4D 42 4C 41-44 4F 20 43 4F 4E 3A 20 ENSAMBLADO CON:
;16D6:0130 4D 69 63 72 6F 73 6F 66-74 20 28 52 29 20 4D 61 Microsoft (R) Ma
;16D6:0140 63 72 6F 20 41 73 73 65-6D 62 6C 65 72 20 56 65 cro Assembler Ve
;16D6:0150 72 73 69 6F 6E 20 36 2E-31 35 2E 38 38 30 33 2E rsion 6.15.8803.
;16D6:0160 20 0A 0D 20 20 24 0A 0D-49 4E 54 52 4F 44 55 5A .. $..INTRODUZ
;16D6:0170 43 41 20 45 4C 20 46 49-43 48 45 52 4F 20 44 45 CA EL FICHERO DE
; Aquà vemos las últimas instrucciones y cómo se muestra el contenido en
;pantalla.
;AX=16D6 BX=0000 CX=140A DX=0000 SP=03FE BP=0000 SI=0000 DI=0000
;DS=16D6 ES=16B7 SS=1808 CS=16C7 IP=0006 NV UP EI PL NZ NA PO NC
;16C7:0006 B409 MOV AH,09
;-t
;AX=09D6 BX=0000 CX=140A DX=0000 SP=03FE BP=0000 SI=0000 DI=0000
;DS=16D6 ES=16B7 SS=1808 CS=16C7 IP=0008 NV UP EI PL NZ NA PO NC
;16C7:0008 BA0800 MOV DX,0008
;-t
;AX=09D6 BX=0000 CX=140A DX=0008 SP=03FE BP=0000 SI=0000 DI=0000
;DS=16D6 ES=16B7 SS=1808 CS=16C7 IP=000B NV UP EI PL NZ NA PO NC
;16C7:000B CD21 INT 21
;-p
;*****//Programa:"COPIA",creado por Berlanga*****
;************ (mail) [email protected] *****************************
;****COPIA UN FICHERO SOBRE OTRO ,O CREA UN NUEVO FICHERO DE SALIDA******
;*EN DONDE SE ESCRIBE EL CONTENIDO DEL DE ENTRADA, SOBREESCRIBIENDO DATOS*
;*ENSAMBLADO CON: Microsoft (R) Macro Assembler Version 6.15.8803.
;***********************************************************
.CODE
;CONFIGUARCION DE LAS MACROS
;Generamos esta macro para los mensajes de presentación,
;pasándole un valor a través de: "EscriboMensaje"
EscriboMensajeEntrada MACRO EscriboMensaje
MOV AH,9
MOV DX,OFFSET EscriboMensaje
int 21h
ENDM
;Programamos una Macro para copiar cadenas de entrada a ASCIIZ
CopiarZ MACRO destino
;Una pequeña explicación para entender esta Macro.
;Copia el nombre del fichero del buffer de entrada del Teclado,
;y lo pone en el destino que demos al llamar a la macro.
cld ;Pone a 0 el indicador de dirección DF, por lo que los registros
;SI y/o DI se autoincrementan en las operaciones de cadenas,
; sin afectar al resto de los indicadores. Es NECESARIO colocarlo
;antes de las instrucciones de manejo de cadenas si no se conoce
;con seguridad el valor de DF.
mov cl,[BufferDeEntradaTeclado+1];<--16C7:0026 8A0E9B02 MOV CL,[029B]
xor ch,ch ;Hacemos 0 a ch
mov si,offset BufferDeEntradaTeclado+2 ;<<16C7:002C BE9C02 MOV SI,029C
mov di,offset destino ;<<16C7:002F BFC402 MOV DI,02C4
rep movsb ;Transfiere un byte o una palabra de la cadena origen
;direccionada por DS:SI a la cadena destino direccionada
; por ES:DI, incrementando o decrementando a continuación
;los registros SI y DI según el valor de DF (véanse CLD y STD)
;en una o dos unidades, dependiendo de si se trabaja con bytes
;o con palabras. Cadena origen y cadena destino son dos
;operandos redundantes que sólo indican el tipo del dato
;(byte o palabra) a comparar, es más cómodo colocar MOVSB o MOVSW
;para indicar bytes/palabras. Si se indica un registro de segmento,
;éste sustituirá en la cadena origen al DS ordinario.
;Una vez finalizada la secuencia repetida del MOVSB, tendremos en
;memoria lo siguiente:
;16D6:02C0 00 00 00 00 48 69 6C 61-72 69 6F 2E 74 78 74 00 ....Hilario.txt.
xor al,al ;Ponemos un cero en al, para el NULL
;Y lo transferimos al final de Hilario.txt con stosb
stosb ;Transfiere el operando origen almacenado en AX o AL,
;al destino direccionado por el registro DI sobre el segmento
;extra. Tras la operación, DI se incrementa o decrementa según
;el indicador DF (véanse CLD y STD) para apuntar al siguiente
;elemento de la cadena. Cadena_destino es un operando redundante
;que sólo indica el tipo del dato (byte o palabra) a cargar,
;es más cómodo colocar STOSB o STOSW para indicar bytes/palabras.
ENDM
;Construiremos una macro especÃfica para sacar los EscriboMensajes
;por la Consola.
Input MACRO EscriboMensaje
mov ah,9
mov dx,offset EscriboMensaje
int 21h
mov ah,0ah ;Lee una cadena de la entrada standard en un buffer
;entrada en ah 0ah, en ds:dx, dirección del buffer
;de entrada .El primer byte del buffer contiene la
;entrada del número máximo de caracteres leÃdos
;La entrada se realiza a partir de la posición actual
;del cursor.
mov dx,offset BufferDeEntradaTeclado
int 21h
mov ah,9
mov dx,offset Avanza
int 21h
ENDM
;Estableceremos esta MACRO para salir del programa
;señalando un error si lo hubiera.
Salir MACRO EscriboMensaje, errorlevel
mov dx,offset EscriboMensaje
mov ah,9
int 21h
mov ax,4c00h+errorlevel
int 21h
ENDM
Entrada PROC
;*******************************
mov ax,@DATA ;Inicializamos el segmento de Datos
mov ds,ax ;y el segmento extra
push ax
EscriboMensajeEntrada Informativo
;*****************************
Programa:
pop ax
mov es,ax
;Leemos el nombre del fichero de entrada
;************************************************************************
;La secuencia siguiente serÃa llamar a la Macro Input MACRO EscriboMensaje
;pasándole el valor EscriboMensaje1. Realizando la llamada de la siguiente
;forma Input EscriboMensaje1
;En este código analizado con el Debug del DOS, vemos cual serÃa la secuencia
; en los registros:
;AX=16D6 BX=0000 CX=140A DX=0008 SP=0400 BP=0000 SI=0000 DI=0000
;DS=16D6 ES=16D6 SS=1808 CS=16C7 IP=0010 NV UP EI PL NZ NA PO NC
;16C7:0010 B409 MOV AH,09
;-t
;AX=09D6 BX=0000 CX=140A DX=0008 SP=0400 BP=0000 SI=0000 DI=0000
;DS=16D6 ES=16D6 SS=1808 CS=16C7 IP=0012 NV UP EI PL NZ NA PO NC
;16C7:0012 BA6601 MOV DX,0166
;-t
;AX=09D6 BX=0000 CX=140A DX=0166 SP=0400 BP=0000 SI=0000 DI=0000
;DS=16D6 ES=16D6 SS=1808 CS=16C7 IP=0015 NV UP EI PL NZ NA PO NC
;16C7:0015 CD21 INT 21
;-p
;INTRODUZCA EL FICHERO DE ENTRADA: <<< Mensaje que retorna a pantalla
;AX=0924 BX=0000 CX=140A DX=0166 SP=0400 BP=0000 SI=0000 DI=0000
;DS=16D6 ES=16D6 SS=1808 CS=16C7 IP=0017 NV UP EI PL NZ NA PO NC
;16C7:0017 B40A MOV AH,0A
;-t
;AX=0A24 BX=0000 CX=140A DX=0166 SP=0400 BP=0000 SI=0000 DI=0000
;DS=16D6 ES=16D6 SS=1808 CS=16C7 IP=0019 NV UP EI PL NZ NA PO NC
;16C7:0019 BA9A02 MOV DX,029A
;-
;AX=09D6 BX=0000 CX=140A DX=0166 SP=0400 BP=0000 SI=0000 DI=0000
;DS=16D6 ES=16D6 SS=1808 CS=16C7 IP=0015 NV UP EI PL NZ NA PO NC
;16C7:0015 CD21 INT 21
;-p
;Hilario.txt <<<<Este serÃa el fichero de Entrada introducido en el buffer
;AX=0A0D BX=0000 CX=140A DX=029A SP=0400 BP=0000 SI=0000 DI=0000
;DS=16D6 ES=16D6 SS=1808 CS=16C7 IP=001E NV UP EI PL NZ NA PO NC
;16C7:001E B409 MOV AH,09
;AX=090D BX=0000 CX=140A DX=029A SP=0400 BP=0000 SI=0000 DI=0000
;DS=16D6 ES=16D6 SS=1808 CS=16C7 IP=0020 NV UP EI PL NZ NA PO NC
;16C7:0020 BA9702 MOV DX,0297
;-p
;AX=090D BX=0000 CX=140A DX=0297 SP=0400 BP=0000 SI=0000 DI=0000
;DS=16D6 ES=16D6 SS=1808 CS=16C7 IP=0023 NV UP EI PL NZ NA PO NC
;16C7:0023 CD21 INT 21
;-p
;No desarrollaremos con el Debug del DOS, más macros, dado que el proceso
;para el resto serÃa semejante según la secuencia establecida
Input EscriboMensaje1
;*************************
;Copia el nombre al FicheroDeEntrada convirtiéndolo a ASCII
;pasando los valores a FicheroDeEntrada. Deberéis de comprobar
;el proceso secuancial de esta Macro
CopiarZ FicheroDeEntrada
;Lee el nombre del fichero de salida
Input EscriboMensaje2
;************************************************
CopiarZ FicheroDeSalida
;Si esta MACRO es llamada pasándole el fichero de Salida
;nos quedarÃa ,al final, algo asà con del Debug del DOS:
;AX=0900 BX=0000 CX=0000 DX=018B SP=0400 BP=0000 SI=02A7 DI=02D0
;DS=16D6 ES=16D6 SS=1808 CS=16C7 IP=003C NV UP EI PL ZR NA PE NC
;16C7:003C CD21 INT 21
;-p
;INTRODUZCA EL NOMBRE DEL FICHERO DE SALIDA:
;AX=0924 BX=0000 CX=0000 DX=018B SP=0400 BP=0000 SI=02A7 DI=02D0
;DS=16D6 ES=16D6 SS=1808 CS=16C7 IP=003E NV UP EI PL ZR NA PE NC
;16C7:003E B40A MOV AH,0A
;********************************************
;Comprobamos ahora si el fichero de Salida Ya existe
;e intentamos abrirlo
mov ax,3d00h ;Lo abrimos para lectura
mov dx,Offset FicheroDeSalida
int 21h ;Si no existiera el fichero de salida,
;saltarÃamos para indicarlo
jc NoExisteFicheroDeSalida
;Cierra el fichero abierto
mov bx,ax ;Copia handle
mov ah,3eh
int 21h
;Mostramos el EscriboMensaje de error y salimos
Salir EscriboMensaje3,1
;Rutina NoExisteSalida
NoExisteFicheroDeSalida:
;Abrimos el fichero de entrada para Lectura
mov ax,3d00h
mov dx,offset FicheroDeEntrada
int 21h
jnc ExisteFicheroDeEntrada
;Sino fuese asÃ, mostramos el fichero de error y salimos
Salir EscriboMensaje4,2
ExisteFicheroDeEntrada:
;Guardamos el handle del fichero de Entrada
mov [HandleDeEntrada],ax
;Creamos el Fichero de salida
mov ah,3ch
xor cx,cx
mov dx,offset FicheroDeSalida
int 21h
jnc CreadoFicheroDeSalida
;Ahora mostramos el EscriboMensaje y salimos
Salir EscriboMensaje5,3
;**************************************************
;En esta parte vemos una de las opciones en las cuales introducimos
;el nombre del fichero :FICHSAL.TXT, por el teclado, cuando el fichero
;de salida no sea uno existente.
; AX=0A24 BX=0000 CX=0000 DX=029A SP=0400 BP=0000 SI=02A7 DI=02D0
;DS=16D6 ES=16D6 SS=1808 CS=16C7 IP=0043 NV UP EI PL ZR NA PE NC
;16C7:0043 CD21 INT 21
;-p
;fichsal.txt
;AX=0A0D BX=0000 CX=0000 DX=029A SP=0400 BP=0000 SI=02A7 DI=02D0
;DS=16D6 ES=16D6 SS=1808 CS=16C7 IP=0045 NV UP EI PL ZR NA PE NC
;16C7:0045 B409 MOV AH,09
;-t
;AX=090D BX=0000 CX=0000 DX=029A SP=0400 BP=0000 SI=02A7 DI=02D0
;DS=16D6 ES=16D6 SS=1808 CS=16C7 IP=0047 NV UP EI PL ZR NA PE NC
;16C7:0047 BA9702 MOV DX,0297
;-t
;AX=090D BX=0000 CX=0000 DX=0297 SP=0400 BP=0000 SI=02A7 DI=02D0
;DS=16D6 ES=16D6 SS=1808 CS=16C7 IP=004A NV UP EI PL ZR NA PE NC
;16C7:004A CD21 INT 21
;-p
;AX=0924 BX=0000 CX=0000 DX=0297 SP=0400 BP=0000 SI=02A7 DI=02D0
;DS=16D6 ES=16D6 SS=1808 CS=16C7 IP=004C NV UP EI PL ZR NA PE NC
;16C7:004C FC CLD
;***********************************************************************
;Comprobar con el debug del DOS, como queda el fichero de salida en Memoria
;16D6:02E0 00 00 00 00 00 00 00 00-00 00 00 00 00 66 69 63 .............fic
;16D6:02F0 68 73 61 6C 2E 74 78 74-00 00 00 00 00 00 00 00 hsal.txt........
;en el segmento 16D6 y en el desplazamiento 2ED, sino he contado mal, encontramos
;el primer carácter de fichsal.txt
;***********************************************************************
CreadoFicheroDeSalida:
mov [HandleDeSalida ],ax
;Ahora comenzamos el bucle que copia todo el fichero.
Bucle:
;Primero, lee Maxima_Longitud_Abrir bytes
mov ah,3fh
mov bx,[HandleDeEntrada]
mov cx,Maxima_Longitud_Abrir
MOV dx,offset BufferCopiaDeDatos
int 21h
;******************************************************
;Es muy conveniente, pararse en esta parte, y observar
;como actúa MOVSB, basándose en SI y DI, origen y destino de la memoria,
;para ir cambiando secuencialmente letra a letra del fichero HILARIO.TXT,
;para lograr depositar en el buffer de memoria los datos que serán reintegrados
;al fichero de Salida.
; AX=0924 BX=0000 CX=0003 DX=02E3 SP=0400 BP=0000 SI=02F0 DI=0341
;DS=16D6 ES=16D6 SS=180D CS=16C7 IP=0059 NV UP EI PL ZR NA PE NC
;16C7:0059 F3 REPZ
;16C7:005A A4 MOVSB
;-T
;AX=0924 BX=0000 CX=0002 DX=02E3 SP=0400 BP=0000 SI=02F1 DI=0342
;DS=16D6 ES=16D6 SS=180D CS=16C7 IP=0059 NV UP EI PL ZR NA PE NC
;16C7:0059 F3 REPZ
;16C7:005A A4 MOVSB
;-T
;AX=0924 BX=0000 CX=0001 DX=02E3 SP=0400 BP=0000 SI=02F2 DI=0343
;DS=16D6 ES=16D6 SS=180D CS=16C7 IP=0059 NV UP EI PL ZR NA PE NC
;16C7:0059 F3 REPZ
;16C7:005A A4 MOVSB
;-T
;AX=0924 BX=0000 CX=0000 DX=02E3 SP=0400 BP=0000 SI=02F3 DI=0344
;DS=16D6 ES=16D6 SS=180D CS=16C7 IP=005B NV UP EI PL ZR NA PE NC
;16C7:005B 32C0 XOR AL,AL
;
jnc LecturaBien
;Muestra el EscriboMensaje y sale cerrando los ficheros
Salir EscriboMensaje6,4
LecturaBien:
;Guarda el número de bytes leÃdos
push ax
;Ahora escribe los bytes leÃdos
mov cx,cx
mov ah,40h
mov bx,[HandleDeSalida]
mov dx,offset BufferCopiaDeDatos
int 21h
jnc EscrituraBien
;Muestra EscriboMensaje y sale
Salir EscriboMensaje7,5
EscrituraBien:
pop ax
cmp ax,Maxima_Longitud_Abrir
jz Bucle
Salir EscriboMensaje8,0
Entrada ENDP
END Entrada
Copia de ficheros
Programa en ensamblador que copia un fichero sobre otro.
Descargar adjuntos
COMPARTE ESTE TUTORIAL
COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP