Codigo fuente programa para copiar ficheros en Ensambler


;****************************************************************
;  //////******Comentarios a berlanga22@hotmail.com*******\\\\\ *
;*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) berlanga22@hotmail.com *****************************’
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) berlanga22@hotmail.com *****************************
;****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

fuente: lawebdelprogramador.com

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s