Vistas de página en total

Mostrando entradas con la etiqueta argc. Mostrar todas las entradas
Mostrando entradas con la etiqueta argc. Mostrar todas las entradas

miércoles, 11 de septiembre de 2013

COMANDO "TYPE"

    

  Con todo lo que he ido publicando en este blog hasta ahora, ya estamos en disposición de hacer el primer comando del sistema. En este caso voy a exponer el comando Type. Para evitar que choque con el comando interno del sistema vamos a llamarlo MyType.
      Este programa imprimirá un fichero sobre pantalla o sobre impresora. Y podremos hacerlo de forma continua o de forma paginada.
      Llevará como todos los comandos una ayuda implícita que podrá ser llamada a través de la línea de comandos con '/H', '/h', o '/?'. Cuando se introduzca alguno de estos comandos en la línea aparecerá la siguiente información.

      Este comando muestra el fichero especificado"
      Por Jose Angel Moneo"
      Formato: ver [unidad:][trayecto]fichero(s)        [/M] [/P][/H][/?]

                   /M ....Por páginas
                  /P .....Sobre impresora
                  /H o /?.......Ayuda

   En este caso el programa es muy sencillo. Solo tiene la rutina principal en la que analizamos y ejecutamos el comando y una subrutina para imprimir el fichero. Por lo tanto lo incluyo de forma íntegra en esta entrada.
   Es sencillo, no porque sea fácil hacer esto en ensamblador, sino porque ya dispongo de una librería de funciones y una estructura de programa suficientemente potente, para programar como si lo estuviera haciendo en alto nivel.
    La rutina principal lee la línea de comandos y analiza los parámetros pasados, para realizar posteriormente la acción correspondiente.
    Si no indicamos fichero en la línea de comandos, este Type, solicitará el fichero por ventana emergente mediante el windir.
    En el caso de que se pulse EXC y no se seleccione fichero en el windir, la función saldrá sin hacer nada.
    En una impresión paginada (/M) el fichero se irá imprimiendo, deteniendo el proceso al final de la pantalla y escribiendo "------MAS-----", para indicar que el fichero no ha terminado.
    Al final de proceso, siempre pedirá un CR antes de salir al sistema.

    En este caso, como se ve también he utilizado la macro FOR...NEXT, para realizar los bucles. Existe un SWITCH, en el programa que ha sido implementado de forma directa en ensamblador, ya que es muy simple. En la siguiente entrada creare una macro SWITCH...CASE, para poder ver como simplificar  el programa, aunque en este caso es innecesario, ya que está muy claro.


MYTYPE.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 io.mac
include argum.mac
include stdio.mac
include string.mac
include main.mac
include window.mac
include hi_level.mac

 .model compact,pascal

.stack 300

.data
dta _dta ?
mens1 db 10,13,"Par metro incorrecto",10,13,0
help db "Este comando muestra el fichero especificado"
     db 10,13,"Por Jose Angel Moneo"
     db 10,13,"Formato: ver [unidad:][trayecto]fichero(s)"
     db "   [/M] [/P][/H[/h] ",10,10,13, "    /M ....Por p ginas",10,13
     db "    /P .....Sobre impresora",10,13,0,"    /H o /? .....Ayuda",10,13,0

mens2 db "falta nombre de fichero",0
mens3 db "El fichero ",0
mens4 db " no existe.",0
mens6 db " No se puede abrir ",0
mens7 db "------------------ Presentando fichero ",0
mens8 db "------------------",10,13,0
mens9 db "-----------MAS----------",10,13,0
hay db 0
sw db 0
sw1 db 0
i db 0
salida dw 0
todo db "*.*",0
total db 40 dup (0)
camino db 40 dup (0)
buffer db 80 dup (0)
handle dw 0
ends

.code

Type proc far
        main
        setdta dta
        argc dl
        inc dl    ;inc 1 ya que cl empieza en 1   
  FOR cl,1,dl
        argv cl,si
        cmp byte ptr [si],'/'
        je switch1
        mov hay,1
        jmp fin_for1

switch1:
        mov ah,[si+1]
        cmp ah,'H'
        je irah
        cmp ah,'h'
        je irah
        cmp ah,'?'
        je irah
        cmp ah,'M'
        je iram
        cmp ah,'m'
        je iram
        cmp ah,'P'
        je irap
        cmp ah,'p'
        je irap

   default:
        puts mens1
        puts help
        exit 1
   irah:
        puts help
        exit 0
  iram:
        mov sw,1
        jmp fin_for1
  irap:
        mov sw1,1
  fin_for1:
     NEXT cl

        cmp hay,0
        jne cpsw
        setcursor off
        windir 5,20,todo,dta._nombre
        cmp dta._nombre,0
        je nada
        call presenta
        exit 0
  nada:
        exit 1

cpsw:
        cmp sw1,1
        jne pantalla
        mov salida,_stdprn
        mov sw,0
        jmp alfor2

Pantalla:
        mov salida,_stdout
alfor2:

   FOR CL,1,DL
       argv cl,si
       cmp byte ptr [si],'/'
       je fin_for2
       getpath camino,[si]
       findfirst [si],_archivo
       jnc presentar
       puts mens3
      
puts  [si]
      
puts mens4
       jmp fin_for2
Presentar:
        call presenta
in_while:
        findnext
        jc fin_for2
        call presenta
        jmp in_while
fin_for2:
   NEXT CL
        exit 0
type endp


presenta proc near
        push cx
        strcpy total,camino
        strcat total,total,dta._nombre
        open total,_r,handle
        jnc abierto
       
puts mens3
       
puts total
       
puts mens6
        pop cx
        ret

abierto:
        clrscr
       
puts mens7
       
puts total
       
puts mens8
        mov cx,3
in_buc:
        read handle,80,buffer
        mov bx,ax
        cmp bx,0
        je salir_buc
        mov si,0
 resto:
        cmp si,bx
        je fin_buc
        write salida,1,[buffer+si]
        cmp byte ptr [buffer+si],10
        pushf
        inc si
        popf
        jne resto
        inc cx
        cmp cx,23
        jne resto
        cmp sw,1
        jne resto
       
puts mens9
        getch al
        mov cx,1
fin_buc:
        jmp in_buc
salir_buc:
        close handle
        getch al
        pop cx
        ret
presenta endp
end type


lunes, 9 de septiembre de 2013

EJEMPLO DE WINDIR Y LINEA DE COMANDOS DOS

    Lo que puse en la última entrada era una librería. Para poder usarla hace falta un programa.
    Este es, pues, un programa ejemplo de uso de la función windir.
    A la función se le pasa  la máscara a buscar y la función presenta los ficheros que encajen con la máscara, permitiendo seleccionar un fichero.
     Cuando se sale de windir, si se seleccionó un fichero, este se almacena en el buffer indicado en el parámetro file, y por lo tanto, lo podemos imprimir en pantalla.
   En este programa se usa la librería argum, de forma que podemos dar la máscara de búsqueda a través de la línea de comandos al llamar al ejecutable. Ejm wdir_ej    *.exe
   La máscara indicada en la línea de comandos será usada como máscara de búsqueda en windir. Si no indicamos nada se busca *.*.
  
   Este programa es pues el primero que pongo con recogida de datos de la línea de comandos.





WDIR_EJ.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 window.mac
include argum.mac

.model compact,pascal
.stack 200

.data
files db "*.*",0
file db 20 dup (0)
retor db 10,13,0

.code

p proc far
     main                 ;inicializa programa
     argc dl              ; comprueba si hay argumentos en la línea de comandos
     cmp dl,0
     jne seguir
     mov si,offset files
     jmp presenta

seguir:
     argv 1,si          ;recoje el primer argumento

presenta:
     windir 5,20,[si],file     ; llama a la función de directorio indicándole la máscara
     printf retor                  ;Imprimer un return
     printf file                      ; imprime el fichero
     ret
p endp
end p

viernes, 10 de mayo de 2013

_LIN_COMAND

   _LIN_COMAND - IMPLEMENTACIÓN DE  ARGC Y ARGV

  Una vez visto lo que queremos hacer y definido la parte exterior del programa, es decir lo que vemos y escribimos habitualmente, vamos a pasar al código almacenado en nuestras librerías.
   Para poder trabajar fácilmente, se crearon las liberías (.LIB). Estas son almacenes de código compilado, que serán recopiladas por el linker según vayan siendo declaradas.
   El programa declarará las librerías, que han de ser usadas, a través del compilador, y el linker las añadirá al código final, enlazando las llamadas a ellas con la posición donde coloca cada rutina. 
   Debido a que la unión la realiza el linker, el código fuente de las librerías ha de ser compilado y posteriormente almacenado en la librería.  Para ello usaremos el compilador, en este caso TASM, y posteriormente el gestor de librerías TLIB para almacenar el " código objeto" en la librería.
   Como todo esto es parte del manejo de los compiladores, no entraré en como se hace.
  Simplemente quiero recordar que la mayor parte del código a utilizar lo deberemos almacenar en las librerías. 
   Existen librerías ya construidas, que pueden ser usadas. Como el sistema que utilizo de paso de parámetros es el estandar de C, se pueden enlazar con nuestros programas cualquier rutina de las librerías de Borland C. En mi caso no existe librería C ya que, no hay código previo. Parto de cero. Todo el código es nuevo.
  Más adelante indicaré como aprovecharnos de funciones ya creadas en otras librerías, para realizar programas con apoyo de instrucciones más complejas.

 Como mostré en la declaración del Main.mac la macro main llama a una función que extrae los argumentos de la linea de comandos y los almacena en una estructura, para luego poder analizarlos individualmente. Esta función es la que hoy presento. La función _lin_comand.

   Como se ve en la definición de la función existe algunas novedades.
   Primero Public. Directiva de compilación que permite declarar el nombre como localizable por el linkador para poder asociar la rutina al resto del código. Public lo que hace es añadir una entrada en una tabla de referencias en la librería con el nombre y la dirección en del código dentro de la librería. De esta manera el linkador podrá tomar la función y añadirla al código en curso. Si no se declara no será localizable.
 Igualmente debemos publicar las variables que debamos alcanzar desde el exterior. En este caso   _argc y _argv, que son precisamente las que se declararon como extern en el argum.mac.
   
  La función _lin_comand recorre la linea de comandos del dos, y va tomando las palabras, almacenando la dirección de cada una en una lista de punteros llamada argv. El número de palabras lo guarda en argc.
  Esta función no será incorporada al main.mac si no se incluye la cabecera ARGUM.MAC



MAIN.ASM (Versión Clásica TASM2.0)
; 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/>.

title libreria del sistema operativo
code segment byte public 'code'
      assume ds:data, cs:code
      public _lin_comand
      public _argc
      public _argv
_lin_comand proc near
        push ds
        push es
        push dx
        push bx
        push cx
        push si
        push di
        xor cx, cx
        cld
        mov si, 81h
        mov ax, data
        mov es, ax
        mov di, offset _lista
        mov bx, 80h
        mov cl,[bx]
        rep movsb
        mov cl, [bx]
        inc cx
        push es
        pop ds
        cmp cx, 0
        ja anali
        mov _argc, 0
        jmp fin

    anali:
        mov bx, offset _argv
        mov di, offset _lista
        mov al,' '
    anali1:
        repe scasb
        cmp cx, 0
        je fin
        dec di
        inc cx
        mov [bx], di
        inc bx
        inc bx
        repne scasb
        inc _argc
        dec di
        mov byte ptr [di], 0
        inc di
        cmp cx, 0
        je fin
        jmp anali1

    fin:
        pop di
        pop si
        pop cx
        pop bx
        pop dx
        pop es
        pop ds
        ret
_lin_comand endp
code ends
data segment byte public 'data'
        _argc db 0
        _argv dw 16 dup(0)
        _lista db 20 dup(0)

data ends
end

Si aplicamos las macros de mejora de directivas mías definidas en main.mac quedará.

MAIN.ASM (Versión Propia con mis macros)
; 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
title libreria del sistema operativo

_modelo exe

_code
      public _lin_comand
      public _argc
      public _argv
_lin_comand proc near
        push ds
        push es
        push dx
        push bx
        push cx
        push si
        push di
        xor cx, cx
        cld
        mov si, 81h
        mov ax, data
        mov es, ax
        mov di, offset _lista
        mov bx, 80h
        mov cl,[bx]
        rep movsb
        mov cl, [bx]
        inc cx
        push es
        pop ds
        cmp cx, 0
        ja anali
        mov _argc, 0
        jmp fin

    anali:
        mov bx, offset _argv
        mov di, offset _lista
        mov al,' '
    anali1:
        repe scasb
        cmp cx, 0
        je fin
        dec di
        inc cx
        mov [bx], di
        inc bx
        inc bx
        repne scasb
        inc _argc
        dec di
        mov byte ptr [di], 0
        inc di
        cmp cx, 0
        je fin
        jmp anali1

    fin:
        pop di
        pop si
        pop cx
        pop bx
        pop dx
        pop es
        pop ds
        ret
_lin_comand endp

_data
        _argc db 0
        _argv dw 16 dup(0)
        _lista db 20 dup(0)
_end


  Como se ve hemos simplificado el programa y lo hemos acercado a TASM5.0. Además, ahora con solo cambiar la línea de"_model exe" a "_model com" podremos compilarla librería para realizar ficheros .com

lunes, 6 de mayo de 2013

ARGUM

ARGUM.MAC - TOMA DE ARGUMENTOS DE LA LÍNEA DE COMANDOS


Al igual que en "C", necesitamos tomar los argumentos que nos pasen del sistema, al ejecutar un programa, desde la linea de comandos, para tratarlos en nuestro programa. Esta función llamada como en "C", toma el argumento indicado, para poder tratarles posteriormente.

  En realidad son dos funciones ARGV y ARGC.
  
  Argc nos dará el número de argumentos y Argv nos permitirá tomar un puntero uno específico.
  Los datos de argumentos están cargados en la memoria, como una lista de cadenas. El proceso de descomponer la linea de comandos y almacenar cada argumento en una cadena independiente la realiza una rutina llamada Main, que será expuesta posteriormente y que será llamada al comienzo de cada programa, para la correcta inicialización de este.

  Este caso es más complejo que el anterior. Esta función utiliza el precompilador para crear una macro con parámetro adicional. El numero, que nos permitirá recoger el argumento que necesitemos de la lista de argumentos, y la dirección, que nos dirá en que dirección de memoria está este argumento.

   la función ifdif nos va a permitir usar la macro de dos modos. Podremos indicar en su llamada el argumento deseado y la dirección en la que queremos que nos almacene el puntero del argumento, o podemos no indicar argumentos y tomar bl y ax como indice y puntero por respectivamente. Esto nos permitirá utilizar la función en bucles ahorrando código, si utilizamos bl como contador.

  Como se ve la función es macro directa, su código es muy corto y no tiene sentido almacenarla en librería.
  En cambio se declara una función y dos variables que no están usadas. Las declaraciones extrn están puestas para indicar al compilador las variables  declaradas en _lin_comand.
   Están aquí y no en Main.mac, que es donde se usan, para que podamos eliminarlas de la compilación, simplemente no incluyendo esta cabecera si no necesitamos usar argumentos.
    


ARGUM.MAC
; 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/>.

     
extrn _argv:word     
extrn _argc:byte


argc macro dato
        mov dato,_argc
endm


argv macro numero,direccion
        push bx
        mov bh,0
   ifdif <numero>,<bl>    ;DECLARACION CONDICIONAL PARA USO CON Y SIN PARÁMETROS
        mov bl,numero
    endif
        dec bx
        shl bx,1
        add bx,offset _argv
        mov ax,[bx]
        pop bx
    ifdif <numero>,<ax>  ;DECLARACION CONDICIONAL PARA USO CON Y SIN PARÁMETROS
        mov direccion,ax
    endif
endm