Programación General > ASM (Ensamblador)
Error Al Escribir En Archivo Desde Asm
blend:
que tal banda, si alguien puede ayudarme se los agradeceria infinitamente.
El problema es que estoy haciendo un program que guarde datos en un archivo externo, y si lo hago, pero el problema es que me imprime la cadena que yo escribo, pero enseguida imprime mas caracteres, por ejemplo, en mi seccion de datos tengo esto:
--- Código: Text ---ARCHIVO DB 'datos.txt',0 ;NOMBRE DEL ARCHIVOHANDLED DW ? ;PARA EL HANDLED DEL ARCHIVOVARMENU DB 0AH,0DH,'1.- CONSULTA' DB 0AH,0DH,'2.- ALTA' DB 0AH,0DH,'3.- BUSQUEDA' DB 0AH,0DH,'' DB 0AH,0DH,'TECLEA OPCION ','$' DATOS LABEL BYTELONGMAX DB 20NOMLONG DB ?BUFFER DB 21 DUP (32)MSGNOM DB 'Nombre: ','$' MSGFERROR1 DB 'ERROR AL ABRIR ARCHIVO !!!','$'MSGFERROR2 DB 'ERROR AL ESCRIBIR EN ARCHIVO !!!','$'MSGFERROR3 DB 'ERROR AL CERRAR EL ARCHIVO !!!','$'
y al ejecutar mi archivo ASM en el archivo txt me guarda esto:
--- Citar ---LOQUEYOTECLEO
Nombre: $ERROR AL ABRIR ARCHIVO !!!$ERROR AL ESC
--- Fin de la cita ---
Espero que me puedan hechar una mano, si alguien se interesa, aqui coloco todo mi codigo
--- Código: Text --- PAGE 60, 132TITLE ALTAS, BAJAS Y CONSULTAS ;-------------------------------------------------------------------;VARIABLES DIRECTAS;BIOS EQU 10H ;INTERRUPCION DEL BIOSDOS EQU 21H ;INTERRUPCION DEL DOS TEC1 EQU 49 ;DEFINICION DE LA TECLA '1'TEC2 EQU 50 ;DEFINICION DE LA TECLA '2'TEC3 EQU 51 ;DEFINICION DE LA TECLA '3'ESKP EQU 27 ;DEFINICION DE LA TECLA 'ESC' .MODEL SMALL.STACK.DATA ;-------------------------------------------------------------------; MENSAJES DEL MENU (VARIABLES); ARCHIVO DB 'datos.txt',0 ;NOMBRE DEL ARCHIVOHANDLED DW ? ;PARA EL HANDLED DEL ARCHIVOVARMENU DB 0AH,0DH,'1.- CONSULTA' DB 0AH,0DH,'2.- ALTA' DB 0AH,0DH,'3.- BUSQUEDA' DB 0AH,0DH,'' DB 0AH,0DH,'TECLEA OPCION ','$' DATOS LABEL BYTELONGMAX DB 20NOMLONG DB ?BUFFER DB 21 DUP (32)MSGNOM DB 'Nombre: ','$' MSGFERROR1 DB 'ERROR AL ABRIR ARCHIVO !!!','$'MSGFERROR2 DB 'ERROR AL ESCRIBIR EN ARCHIVO !!!','$'MSGFERROR3 DB 'ERROR AL CERRAR EL ARCHIVO !!!','$' .CODE ;*******************************************************************;* *;* PROCEDIMIENTO PRINCIPAL *;* *;******************************************************************* ;-------------------------------------------------------------------;PROCEDIMIENTO PRINCIPAL (FAR);BEGIN PROC FAR MOV AX, @DATA MOV DS, AX CALL FOPENH INI: CALL MENU CALL FPUT CALL FCLOSEH ;JMP INI FIN: MOV AH, 4CH INT DOSBEGIN ENDP ;*******************************************************************;* *;* PROCEDIMIENTOS PARA EL MANEJO DEL ARCHIVO *;* *;******************************************************************* ;-------------------------------------------------------------------;PROCEDIMIENTO PARA ABRIR UN ARCHIVO EMPLEANDO HANDLED;FOPENH PROC NEAR LEA DX, ARCHIVO;NOMBRE DEL ARCHIVO MOV AH, 3DH ;SERVICIO PARA ABRIR ARCHIVO MOV AL, 01 ;TIPO DE PERMISO ;00 -> SOLO LECTURA ;01 -> SOLO ESCRITURA ;02 -> LECTURA YE ESCRITURA INT DOS JB FERROR1 MOV [HANDLED], AX ;GUARDAR HANDLE RETFOPENH ENDP ;-------------------------------------------------------------------;PROCEDIMIENTO PARA CERRAR UN ARCHIVO EMPLEADO HANDLED;FCLOSEH PROC NEAR MOV AH, 3EH MOV BX, [HANDLED] INT DOS JB FERROR3 RETFCLOSEH ENDP ;-------------------------------------------------------------------;PROCEDIMIENTO PARA ESCRIBIR EN EL ARCHIVO EMPLEADO HANDLED;FPUT PROC NEAR MOV AH, 40H ;SERVICIO PARA ESCRIBIR EN ARCHIVO MOV BX, [HANDLED] LEA CX, LONGMAX ;NUMERO DE BYTES A ESCRIBIR LEA DX, BUFFER ;DATO A ESCRIBIR INT DOS JB FERROR2 RETFPUT ENDP ;*******************************************************************;* *;* PROCEDIMIENTOS PARA EL MENU *;* *;* 1.- CONSULTA *;* 2.- ALTA *;* 3.- BUSQUEDA *;* *;* TECLEA OPCION *;******************************************************************* ;-------------------------------------------------------------------;PROCEDIMIENTO PARA MOSTRAR MENU Y ESPERAR A QUE SELECCIONE;EN CASO DE OPRIMIR 'ESC', SALDRA DEL PROGRAMA;MENU PROC NEAR CALL CLR ;LIMPIAR PANTALLA LEA DX, VARMENU;CARGAR MENSAJE DE MENU MOV AH, 09H ;IMPRIME LO QUE ESTE EN DX INT DOS MOV AH, 07H ;LEER CARACTER SIN IMPRESION INT DOS ;GUARDANDO EL CARACTER CALL LEERCRC ;PROCEDIMIENTO PARA LEER CARACTER RETMENU ENDP ;-------------------------------------------------------------------;PROCEDIMIENTO PARA LEER LA OPCION;LEERCRC PROC NEAR CMP AL, TEC2 ;Z SE ACTIVA SI EL RESULTADO ES CERO JE ALT ;SI Z SE ACTIVA SE REALIZA EL SALTO CMP AL, ESKP JE FIN ALT: CALL CLR CALL CUR MOV AH, 09H LEA DX, MSGNOM ;IMPRIMIR MENSAJE 'NOMBRE: ' INT DOS MOV AH, 0AH ;ENTRADA DESDE TECLADO LEA DX, DATOS INT DOS RET LEERCRC ENDP ;*******************************************************************;* *;* PROCEDIMIENTOS PARA MENSAJES DE ERROR O EXITO *;* *;******************************************************************* ;-------------------------------------------------------------------;PROCEDIMIENTO PARA ERROR AL ABRIR ARCHIVO;FERROR1 PROC NEAR CALL CLR LEA DX, MSGFERROR1 MOV AH, 09H INT DOS RETFERROR1 ENDP ;-------------------------------------------------------------------;PROCEDIMIENTO PARA ERROR AL ABRIR ARCHIVO;FERROR2 PROC NEAR CALL CLR LEA DX, MSGFERROR2 MOV AH, 09H INT DOS RETFERROR2 ENDP ;-------------------------------------------------------------------;PROCEDIMIENTO PARA ERROR AL ABRIR ARCHIVO;FERROR3 PROC NEAR CALL CLR LEA DX, MSGFERROR3 MOV AH, 09H INT DOS RETFERROR3 ENDP ;*******************************************************************;* *;* PROCEDIMIENTOS VARIOS *;* *;******************************************************************* ;-------------------------------------------------------------------;PROCEDIMIENTO PARA LIMPIAR PANTALLA; CLR PROC NEAR MOV AH, 06H ;SERVICIO PARA RECORRER PANTALLA MOV BH, 03H ;COLOR MOV CX, 0000H ;POSICION INICIAL (DE - ) MOV DX, 184FH ;POSICION FINAL ( - A) INT BIOS RETCLR ENDP ;-------------------------------------------------------------------;PROCEDIMIENTO PARA POSICIONAR CURSOR AL PRINCIPIO; CUR PROC NEAR MOV AH, 02H MOV BH, 00 MOV DX, 0000 INT BIOS RETCUR ENDP END BEGIN
Eternal Idol:
En FPUT usas la direccion de memoria de LONGMAX, deberias usar el tamaño de la cadena a escribir, ni siquiera el valor de LONGMAX seria correcto. Ademas no veo donde estas usando BUFFER excepto en FPUT, deberias primero asignarle sus caracteres ...
Depuralo para ver esto mejor (cosa que yo no hice).
blend:
Primero una disculpa por responder hasta hoy.
--- Citar ---En FPUT usas la direccion de memoria de LONGMAX, deberias usar el tamaño de la cadena a escribir
--- Fin de la cita ---
intente hacer eso y da el mismo resultado
--- Citar ---Ademas no veo donde estas usando BUFFER excepto en FPUT, deberias primero asignarle sus caracteres ...
--- Fin de la cita ---
De hecho yo tambien pense lo mismo, por que el profe solo asi lo hizo y no nos explico bien, pero despues de indagar tengo una respuesta, cuando se define una variable de tipo LABEL, esta se comporta como una estructura en C. Cuando se llama al servicio 0AH del DOS para leer una cadena se tiene esto:
BX : LONGITUD MAXIMA A LEER
CX : SE GUARDA LA CANTIDAD DE BYTES ESCRITOS
DX : DIRECCION EN DONDE SE GUARDARA LO TECLEADO
entonces cuando yo hago
DATOS LABEL BYTE
MAX DB 10
LONG DB ?
NOM DB ?
MOV DX, DATOS
MOV AH, 0AH
INT 21H
entonces a mi entender :blink: (y que asi es como sucede), se toma de MAX los caracteres a leer, en LONG se guardara el numero de caracteres escritos y por ultimo en NOM se guarda la cadena, y cuando quiera imprimir la cadena solamente mandare a imprimir la variable NOM (NOTA: antes de hacer esto se tiene que agregar a esa variable al final el caracter de salida $) y ya esta.
Eso es todo, pero te agradesco esa observacion por que ni siquiera me habia dado cuenta y me puse a investigarlo XD.
Y hacerca de mi problema inicial sobre el error al escribir en el archivo, ya lo he solucionado, no de la mejor manera que yo hubiera querido, pero almenos ya quedo, aunque no me doy por vencido y sigo practicando :comp:
gracias...
Eternal Idol:
--- Cita de: "blend" ---intente hacer eso y da el mismo resultado
--- Fin de la cita ---
http://www.ctyme.com/intr/rb-2791.htm
No depure el programa, en realidad ni siquiera intente ensamblarlo, solo vi eso que era muy evidente.
--- Cita de: "blend" ---De hecho yo tambien pense lo mismo, por que el profe solo asi lo hizo y no nos explico bien, pero despues de indagar tengo una respuesta, cuando se define una variable de tipo LABEL, esta se comporta como una estructura en C. Cuando se llama al servicio 0AH del DOS para leer una cadena se tiene esto:
--- Fin de la cita ---
Como dije no lo veia, aunque claro que ahora viendo la documentacion tambien se hace evidente:
http://www.ctyme.com/intr/rb-2563.htm#Table1344
--- Cita de: "blend" ---Y hacerca de mi problema inicial sobre el error al escribir en el archivo, ya lo he solucionado, no de la mejor manera que yo hubiera querido, pero almenos ya quedo, aunque no me doy por vencido y sigo practicando
--- Fin de la cita ---
Si, lo solucionaste solo permitiendo 10 caracteres (pasando ese valor a la funcion de lectura) pero lo podrias solucionar facilmente introduciendo una variable que guardara el valor devuelto en AX en la lectura (cantidad de bytes leidos) y usando eso en lugar de LONGMAX en FPUT.
blend:
De hecho no lo solucione de esa forma :P
Como mi codigo tiene errores que son evidentes (para mi no tanto, si no ya lo hubiera solucionado :D ), y al imprimir, me imprimia lo que estaba en la variable siguiente, lo que hice fue colocar una variable en ese lugar que contenia solamente espacios y asi no se veria ningun caracter.
Como dije, no es la mejor forma de haber solucionado el problema, pero en ocaciones se tiene que recurrir a metodos sucios.
Saludos :hola:
Navegación
[#] Página Siguiente
Ir a la versión completa