Vistas de página en total

martes, 1 de octubre de 2013

CONSULTA- IMPRIMIR LONGITUD DE UNA CADENA

En respuesta a la consulta de Carlos Tovar, pongo este programa que imprime la longitud de una cadena.

  Definimos la cadena con la macro string, para que sea más simple de definir. Esta macro definirá la cadena como una array de bytes con una longitud de 30+2. 30 son los bytes pedidos y 2 son los bytes de control. El primero se guarda con la longitud máxima de la cadena y el segundo será en el que introducirá la longitud la función gets (servicio 0Ah de la Int 21h).

    Posicionamos los textos con gotxy y pedimos el texto a medir con gets.
    Para calcular su longitud hay dos maneras. La primera es usar la función strlen, lña cual te da la longitud de la cadena. Este sería el caso también de querer imprimir la longitud de una cadena que está en la memoria.
    Como en este caso la cadena la pedimos por teclado mediante la función 0Ah de la  Int 21h. Existe también la posibilidad de tomar directamente la longitud, del bufer de entrada. Ya que la int 21h lo guarda en el segund byte.
   Por ello existen dos opciones:

     Opción 1, usando la función de contaje de cadena strlen.
    Como los dos primeros byte del bufer string son usados como datos de control, cuando usamos la función strlen debemos direccionar dos byte más adelante. Por eso, la dirección indicada para strlen es "cadena+2"
    Este método puede servir para cualquier cadena guardada de otro modo, como puede ser leída de un fichero.

     Opción 2, aprovechando la propia función int21. En este caso simplemente leemos el segundo byte del bufer y su valor lo pasamos a un bufer DD, en este caso compuesto por dos DW, que nos servirá para que prinf imprima su valor.
   


IMPRIMIR LONGITUD DE UNA CADENA
; Copyright (C) 2013  José Ángel Moneo Fernández

;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.

;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.

;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
include main.mac
include stdio.mac
include string.mac

.model compact,pascal

.stack 250

.data
string cadena 30
longitud dw 0,0
msgtexto db "Introduce un texto",0



.code
 p proc far
      main
      clrscr
      gotoxy 10,9
      puts msgtexto
      gotoxy 10,10
      gets cadena

     ;opción 1                         ; opcion 2
                                            ; xor ax,ax
      strlen cadena+2            ;mov ax,cadena+1
      mov longitud,ax           ; mov longitud,ax
      gotoxy 20,12
      printf longitud
      getch al

      ret
 p endp

end p


sábado, 21 de septiembre de 2013

BASE DE DATOS

Hoy voy a colocar un programa mucho más laborioso, y lo voy a hacer de una sola vez.
     Este programa es un ejemplo de uso de las funciones de fichero, y en concreto del acceso a ficheros mediante la función rseek.
     En su día hice este programa para mostrar como crear y manipular registros en un a base de datos con ASM. Ahora me sirve para mostrar en un solo programa como utilizar todo lo que hasta ahora he colocado.

    El programa almacena las notas de alumnos en un curso. Cada fichero .DAT sería un curso.

  El programa pedirá el nombre de un fichero que usará como base de datos, para almacenar las notas del curso. Si se da un nombre que no existe, se creará el fichero. 



Si no damos un nombre, y pulsamos enter, se abrirá una ventana emergente con el directorio actual, para seleccionar el fichero deseado entre las bases de datos existentes

Una vez elegido el fichero se abrirá una pantalla con cuatro ventanas. 
En la superior-izquierda estará el listado de registros de la base de datos, ordenados por entrada. En esta ventana se verá  una flecha que indicará el registro seleccionado. Los valores de este registro se mostrarán en la ventana superior-derecha. Mediante las teclas up y dw se podrá mover la flecha por el listado de registros para ir seleccionando cada uno.

En la ventana inferior izquierda estará el menú y en la Inferior derecha la ayuda y los mensajes que va dando el programa.

 


Como se ve el interfaces es muy simple. Pero en este caso, el ejemplo, es para ver como crear un registro, y usarlo dentro de una base de datos. Es el típico programa Altas-Bajas-Modificaciones-Consultas, de un ejercicio de Programación de bases de datos.

  El programa almacena las notas de alumnos en un curso.
 Ejemplo ya compilado en Notas.exe

NOTAS.ASM
; Copyright (C) 2013  José Ángel Moneo Fernández

;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.

;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.

;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.

 include main.mac
include stdio.mac
include io.mac
include string.mac
include math.mac
include window.mac

.model compact,pascal

Horizontal equ 205
Vertical equ 186
eds equ 187
ide equ 188
eis equ 201
eii equ 200
medio equ 206
mb equ 202
ms equ 203
mi equ 204
md equ 185
eom equ "$"

;Definición del registro de la báse de datos
registro struc
        string Nom,25  
        string Eva_1,4
        string Eva_2,4
        string Eva_3,4
        db 13
registro ends

.stack 512

.data
   mens0    dB " M E N U ",0
   mens1    dB " 1.- Altas.",0
   mens2    dB " 2.- Bajas.",0
   mens3    dB " 3.- Modificaciones.",0
   mens4    dB " 4.- Salir.",0
   mens5    dB "A L T A S ",0
   mens7    dB "B A J A S ",0
   mens8    dB "Se borrará la persona indicada.",0
   mens9    dB "M O D I F I C A C I O N E S ",0
   MENS10   dB "No se ordenara.",0
   mens11   dB "A Y U D A",0
   mens12   dB "Elige un numero del 1 al 4.",0
   mens13   dB " Para mover la flecha de la primera",0
   mens14   dB "pantalla.",0
   mens15   dB " Para mover la flecha de la primera",0
   mens16   dB "pantalla.",0
   mens17   dB "L I S T A D O ",0
   mens19   dB "D A T O S ",0
   mens20   db "Tabla vacia ",0
   mens21   db "Imposible eliminar elementos. ",0
   mens22   db "Pulse una tecla para continuar.",0
   mens40   dB "¿Esta usted seguro (s/n)?",0
   flechas  dB "-- ",0
   mensno   db "Eva-1: ",0
   mensdi   DB "Eva-2: ",0
   menste   DB "Eva-3: ",0
   mensdn   DB "Nombre: ",0

  ;Marcos de ventana
   l1       db eis,38 dup (horizontal),ms,39 dup (horizontal),eds,0
   l2       db mi,38 dup (horizontal),medio,39 dup (horizontal),md,0
   l3       db eii,38 dup (horizontal),mb,39 dup (horizontal),ide,0
   solicita db "Digame el nombre de la base de datos o pulse enter",0
   base db "*.dat",0
   extension db ".dat",0
   string   file1,20
   op       DB "0"
   lin      DB 0
   col      DB 0
   xlin     DB 0
   res      DB 0
   flecha   DB 0
   pos      dw 0
   indice   DW 0
   comienzo Dw 0
   hand1    dw 0
   long1    dw 0,0
   long2    dw 0,0

;definición de bufer para lectura
   dim      leer, registro, 1
   dim      leer2,registro,1
   buffer   db 255 dup (0)



.code
     inicio proc far
        main
        push ds
        pop es
        clrscr
        setcolor verde
        gotoxy 20,10
        puts solicita
        gotoxy 20,12
        setcursor on
        scanf file1
        cmp file1+1,0
        jnz abase
        windir 10,10,base,file1+2
        jmp por_vent
abase:
        strcat file1+2,file1+2,extension
por_vent:
        setcolor blanco
        open file1+2, _R_W, hand1
        jnc bien
        new_file file1+2,_ARCHIVO,hand1

  bien:
        fseek hand1,_INICIO,0
        read hand1,2,indice
        setcursor off
        call mascara

     panta:
        call menu
     panta1:
        call listado
     lee:
        gotoxy 79, 23
        getch op
        cmp op, 0
        je lee
        cmp op, "1"
        jne s1
        clswindow 12,41,21,78
        gotoxy 55,13
        printf mens5
        call insertar
        jmp panta
     s1:
        cmp op, "2"
        jne s2
        clswindow 12,41,21,78
        gotoxy 55,13
        puts mens7
        gotoxy 42,16
        puts mens8
        call confirma
        jnz lee1
        jmp lee
    lee1:
        call elimina
  ;; test y realizacion de la confirmacion

        jmp panta
     s2:
        cmp op, "3"
        jne s3
        clswindow 12,41,21,78
        gotoxy 47,13
        puts mens9
        gotoxy 42, 16
        puts mens10
        call confirma
        jnz lee2
        jmp lee
    lee2:
        call modificar
        jmp panta
     s3:
        cmp op, "P"
        jne s4
        call baja
        jmp panta1
     s4:
        cmp op, "H"
        jne s5
        call sube
        jmp panta1
     s5:
        cmp op, "4"
        je final
        jmp panta1
    final:
        setcolor normal
        clrscr
        close hand1
        ret
inicio endp

baja proc near
        xor ax,ax
        mov al,flecha
        add ax, comienzo
        INC AX
        cmp ax,indice
        jAe b3
        cmp flecha,7
        jae b1
        inc flecha
        jmp b3
    B1:
        inc comienzo
     b3:
        ret
baja endp
;; pide confirmacion y devuelve en la bandera  z=0 si se dijo NO y
;; z=1 si se dijo
;; SI
;; no modifica nigún registro

confirma proc near  uses ax bx dx
   otro:
        gotoxy 42,20
        puts mens40
        gotoxy 42,21
        getch op
        mov ax,0
        cmp op,'s'
        je conf
        cmp op,'S'
        je conf
        cmp op,'n'
        je salir
        cmp op,'N'
        je salir
        jmp otro
  conf:
        mov ax,1
  salir:
        or ax,ax
        pushf
        clswindow 12,41,21,78
        popf
        ret
confirma endp
sube proc near
        cmp flecha, 0
        je su1
        dec flecha
        jmp su3
     su1:
        cmp comienzo,0
        je su3
        dec comienzo
     su3:
        ret
sube endp

mascara proc near
        setcolor blanco
        clrscr
        mov cl, 1
     inicios0:
        gotoxy 0, cl
        putchar vertical
        gotoxy 39, cl
        putchar vertical
        gotoxy 79, cl
        putchar vertical
        add cl, 1
        cmp cl, 22
        jne inicios0
        gotoxy 0,0
        puts l1
        gotoxy 0,11
        puts l2
        gotoxy 0,22
        puts l3
        ret
mascara endp


menu PROC near
          gotoxy 15,13
          puts mens0
          gotoxy 10,15
          puts mens1
          gotoxy 10, 17
          puts mens2
          gotoxy 10, 19
          puts mens3
          gotoxy 10, 21
          puts mens4
          gotoxy 55,13
          puts mens11
          gotoxy 42,15
          puts mens12
          gotoxy 42,17
          puts mens13
          gotoxy 44,18
          puts mens14
          gotoxy 42,20
          puts mens15
          gotoxy 44,21
          puts mens16
          ret
menu endp


listado proc near
        setcursor off
        clswindow 1,1,10,38
        gotoxy 10, 1
        puts mens17
        cmp indice,0
        jne nofuer
        jmp fuer
nofuer:
        mov cl, flecha
        mov ax,comienzo
        mov pos,ax
        inc cl
        inc cl
        gotoxy 1, cl
        puts flechas
         mov cl,2
  nuevocampo:
        push cx
;; tomamos la posicion inicial del registro
        inc pos
        rseek hand1, pos,registro
        dec pos
        mov cx,size registro
        read hand1,cx,leer
        mov si, offset leer
        pop cx
        gotoxy 5,cl
        printf [si].Nom
        inc cl
        inc pos
        mov ax,indice
        cmp pos,ax
        jae fuer
        cmp cl,10
        jne nuevocampo
   fuer:
        call presentar
          ret
listado endp


presentar proc near
        clswindow 1,41,10,78
        call masentrada
        gotoxy 50,1
        puts mens19
        cmp indice,0
        jne con_pre
        jmp end_pre
      con_pre:
        xor Cx,Cx
        mov Cl,flecha
        add Cx,comienzo
        inc cx
        rseek hand1,Cx,registro
        dec cx
        mov cx,size registro
        read hand1,cx,leer
        mov si, offset leer
        gotoxy 51, 3
        printf [si].Nom
        gotoxy 51, 5
        printf [si].Eva_1
        gotoxy 51, 7
        printf [si].Eva_2
        gotoxy 51, 9
        printf [si].Eva_3
   end_pre:
        ret
presentar endp

elimina proc near  uses es
        cmp indice,0
        jne elim
        clswindow 12,41,21,78
        gotoxy 42,15
        puts mens20
        gotoxy 42, 17
        puts mens21
        gotoxy 42,19
        puts mens22
        getch al
        jmp copi1
 elim:
        cld
        push ds
        pop es
        xor bx,bx
        mov bl,flecha
        add bx,comienzo
        inc bx
  copia:
        inc bx
        rseek hand1,bx,registro
        dec bx
        mov cx,size registro
        read hand1,cx,leer
        rseek hand1,bx,registro
        dec  bx
        mov cx,size registro
        write hand1,cx,leer
        inc bx
        inc bx
        cmp bx,indice
        jbe copia
        dec indice
        fseek hand1,_INICIO,0
        write hand1,2,indice
        cmp flecha,0
        jbe copi2
        dec flecha
        jmp copi1
 copi2:
        cmp comienzo,0
        jbe copi1
        dec comienzo
 copi1:
        ret
elimina endp

insertar proc near
        call masentrada
        gotoxy 50,1
        puts mens5
        setcursor on
        mov si, offset leer
        gotoxy 51, 3
        scanf [si].Nom
        gotoxy 51, 5
        scanf [si].Eva_1
        gotoxy 51, 7
        scanf [si].Eva_2
        gotoxy 51, 9
        scanf [si].Eva_3
        inc indice
        rseek hand1, indice,registro
        dec indice
        mov cx,size registro
        write hand1,cx,leer
        inc indice
        fseek hand1,_INICIO,0
        write hand1,2,indice
    ins1:
        call ordena
        setcursor off
        clswindow 1,41,10,78
        ret
insertar endp

ordena proc near
        mov dx,indice
        cmp dx,1
        ja otr_ord
        jmp end_ordena
   otr_ord:
        rseek hand1, dx,registro
        dec dx
        mov cx,size registro
        read hand1,cx,leer
        rseek hand1, dx,registro
        dec dx
        mov cx,size registro
        read hand1,cx,leer2
        strcmp  leer2.Nom+2,leer.Nom+2
        jbe end_ordena
        inc dx
        rseek hand1, dx,registro
        dec dx
        mov cx,size registro
        write hand1,cx,leer
        inc dx
        inc dx
        rseek hand1, dx,registro
        dec dx
        mov cx,size registro
        write hand1,cx,leer2
        cmp dx,1
        jbe end_ordena
        jmp otr_ord
    end_ordena:
        ret
ordena endp


modificar proc near
        setcursor on
        xor cx,cx
        mov cl,flecha
        add cx,comienzo
        push cx
        inc dx
        rseek hand1,cx,registro
        dec dx
        mov cx,size registro
        read hand1,cx,leer
        mov bx, offset leer
        lea di,[bx].Nom
        push bx
        gotoxy 51,3
        call modif
        pop bx
        lea di,[bx].Eva_1
        push bx
        gotoxy 51,5
        call modif
        pop bx
        lea di,[bx].Eva_2
        push bx
        gotoxy 51,7
        call modif
        pop bx
        lea di,[bx].Eva_3
        push bx
        gotoxy 51,9
        call modif
        pop bx
        pop cx
        inc dx
        rseek hand1,cx,registro
        dec dx
        mov cx,size registro
        write hand1,cx,leer
        setcursor off
        ret
modificar endp

modif proc near  uses es
        push ds
        pop es
        cld
        mov si,offset buffer
        mov al,[di]
        mov [si],al
        scanf  buffer

        cmp byte ptr [si+1],0
        je fin_modif
        xor cx, cx
        mov cl,[si+1]
        add cx,3
        rep movsb
   fin_modif:
       ret
modif endp

masentrada proc near
        clswindow 1,41,10,78
        gotoxy 43, 3
        puts mensdn
        gotoxy 43, 5
        puts mensno
        gotoxy 43, 7
        puts mensdi
        gotoxy 43, 9
        puts menste
        ret
masentrada endp
end inicio