Capítulo VI: EL ENSAMBLADOR EN ENTORNO DOS






6.1. - TIPOS DE PROGRAMAS EJECUTABLES BAJO DOS.

     Antes de que el COMMAND.COM pase el control al programa que se pretende ejecutar, se crea un bloque de 256 bytes llamado PSP (Program Segment Prefix), cuya descripción detallada se verá en el próximo capítulo. En él aparecen datos tales como la dirección de retorno al dos cuando finalice el programa, la dirección de retorno en caso de Ctrl-Break y en caso de errores críticos. Además de la cantidad de memoria disponible y los posibles parámetros suministrados del programa. Cuando el programa toma el control, DS y ES apuntan al PSP. Tipos de programas:

     En los de tipo COM:
          - CS apunta al PSP e IP=100h (el programa empieza tras el PSP).
          - SS apunta al PSP y SP toma la dirección más alta dentro del segmento del PSP.

     En los de tipo EXE:
          - CS e IP toman los valores del punto de arranque del programa (directiva END etiqueta).
          - SS apunta al segmento de pila y SP = tamaño de la pila definida.

     Si el programa es COM podemos terminarlo con la interrupción 20h (INT 20h), o simplemente con un RET si la pila no está desequilibrada (apunta a un INT 20h que hay en la posición 0 del PSP); otra manera de acabar es por medio de la función 4Ch del sistema (disponible desde el DOS 2.0) que acaba cualquier programa sin problemas y sin ningún tipo de requerimientos adicionales, tanto COM como EXE.

     Los programas de tipo COM se cargan en memoria tal y como están en disco, entregándoseles el control. Los de tipo EXE, que pueden llegar a manejar múltiples segmentos de código de hasta 64 Kb, se almacenan en disco «semiensamblados». En realidad, al ser cargados en memoria, el DOS tiene que realizar la última fase de montaje, calculando las direcciones de memoria absolutas. Por ello, estos programas tienen un formato especial en disco, generado por los ensambladores y compiladores, y su imagen en memoria no se corresponde realmente con lo que está grabado en el disco, aunque esto al usuario no le importe. Por ello, no se extrañe el lector de haber visto alguna vez ficheros EXE de más de 640 Kb: evidentemente, no se cargan enteros en memoria aunque lo parezca. Los programas COM no hacen referencias a datos o direcciones separados más de 64 Kb, por lo que todos los saltos y desplazamientos son relativos a los registros de segmento (no se cambia CS ni DS) con lo que no es necesaria la fase de «montaje». No obstante, un programa COM puede hacer lo que le de la gana con los registros de segmento y acceder a más de 64 Kb de memoria, por cuenta y riesgo del programador. En general, la programación en ensamblador está hoy en día relegada a pequeños programas residentes, controladores de dispositivos o rutinas de apoyo a programas hechos en otros lenguajes, por lo que no es estrictamente necesario trabajar con programas EXE realizados en ensamblador. Salvo excepciones, la mayoría de los programas desarrollados en este libro serán de tipo COM ya que los EXE ocuparían algo más, aunque el ensamblador da algo más de comodidad al programador en los mismos.


6.2. - EJEMPLO DE PROGRAMA DE TIPO COM.

     El siguiente ejemplo escribe una cadena en pantalla llamando a uno de los servicios estándar de impresión del DOS (función 9 de INT 21h):

      cr        EQU   13               ; constante de retorno de carro
      lf        EQU   10               ; constante de salto de línea

      programa  SEGMENT                ; segmento común a CS, DS, ES, SS.

                ASSUME CS:programa, DS:programa

                ORG   100h             ; programa de tipo COM

      inicio:   LEA   DX,texto         ; dirección de texto a imprimir
                MOV   AH,9             ; función de impresión
                INT   21h              ; llamar al DOS
                INT   20h              ; volver al sistema operativo

      texto     DB    cr,lf,"Grupo Universitario de Informática.",cr,lf,"$"

      programa  ENDS                   ; fin del segmento

                END   inicio           ; fin del programa y punto de inicio

     Olvidándonos de los comentarios que comienzan por «;», en las primeras lineas las directivas EQU definen dos constantes para el preprocesador del compilador: cr=13 y lf=10. El programa, de tipo COM, consta de un único segmento. La directiva ASSUME indica que, por defecto, las instrucciones máquina se ensamblarán para el registro CS en este segmento (lo más lógico, por otra parte); también conviene asumir el registro DS, de lo contrario, si hubiera que acceder a una variable, el ensamblador añadiría el prefijo del segmento CS a la instrucción al no estar seguro de que DS apunta a los datos, consumiendo más memoria. Se pueden añadir los demás registros de segmento en el ASSUME, aunque es redundante. El ORG 100h es obligatorio en programas COM, ya que estos programas serán cargados en memoria en la posición CS:100h. Al final, la dirección del texto a imprimir se coloca en DS:DX (CS=DS=ES=SS en un programa COM recién ejecutado) y se llama al DOS. El carácter '$' delimita la cadena a imprimir, lo cual es una herencia del CP/M (sería más interesante que fuera el 0 el delimitador) por razones históricas. Se acaba el programa con INT 20h. El punto de arranque es indicado con la directiva END, aunque en realidad en los programas COM el punto indicado (en el ejemplo, «inicio») debe estar forzosamente al principio del programa. Obsérvese que no se genera código hasta llegar a la línea «inicio:», todo lo anterior son directivas.


6.3. - EJEMPLO DE PROGRAMA DE TIPO EXE.

     Los programas EXE (listado al final de esta sección) requieren algo más de elaboración. En primer lugar, es necesario definir una pila y reservar espacio para la misma. Al contrario que los programas COM (cuya pila se sitúa al final del segmento compartido también con el código y los datos) esta característica obliga a definir un tamaño prudente en función de las necesidades del programa. Téngase en cuenta que en la pila se almacenan las direcciones de retorno de las subrutinas y al llamar a una función de la BIOS la pila es usada con intensidad. En general, con medio kilobyte basta para programas tan sencillos como el del ejemplo, e incluso para otros mucho más complejos. El límite máximo está en 64 Kb. El segmento de pila se nombra siempre STACK y con el TLINK de Borland es necesario indicar también la clase 'STACK'.

     Como se ve, son definidos por separado el segmento de código, pila y datos, lo que también ayuda a estructurar más el programa. El segmento de código se define como procedimiento FAR, entre otras razones para que el ensamblador ensamble el RET del final (con el que se vuelve al DOS) como un RETF. La directiva ASSUME asocia cada registro de segmento con su correspondiente segmento. Como puede observarse al principio del programa, es necesario preparar «a mano» la dirección de retorno al sistema. El PUSH DS del principio coloca el segmento del PSP en la pila; el XOR AX,AX coloca un cero en AX (esta instrucción gasta un byte menos que MOV AX,0) y el PUSH AX mete ese 0 en la pila. Con ello, al volver al DOS con RET (RETF en realidad) el control pasará a DS:0, esto es, a la primera instrucción del PSP (INT 20h). Aunque pueda parecer un tanto lioso, es un juego de niños y estas tres instrucciones consecutivas (PUSH DS / XOR AX,AX / PUSH AX) son la manera de empezar de cientos de programas EXE, que después acaban con RET. En general, a partir del DOS 2.0 es más aconsejable terminar el programa con la función 4Ch del DOS, que no requiere que CS apunte al PSP ni precisa de preparación alguna en la pila y además permite retornar un código de ERRORLEVEL en AL: en los programas futuros esto se hará con bastante frecuencia.

     También debe observarse cómo se inicializa DS, ya que en los programas EXE por defecto no apunta a los datos. Ahora puede preguntarse el lector, por curiosidad, ¿qué valdrá «datos»?: datos tiene un valor relativo asignado por el ensamblador; cuando el programa sea cargado en memoria, en el proceso de montaje y en función de cuál sea la primera posición de memoria libre, se le asignará un valor determinado por el montador del sistema operativo.

      cr          EQU   13
      lf          EQU   10


      ; Segmento de datos

      datos       SEGMENT
      texto       DB    cr,lf,"Texto a imprimir",cr,lf,"$"
      datos       ENDS


      ; Segmento de pila

      pila        SEGMENT STACK 'STACK'   ; poner STACK es obligatorio
                  DB    128 dup ('pila')  ; reservados 512 bytes
      pila        ENDS


      ; Segmento de código

      codigo      SEGMENT
      ejemplo     PROC  FAR
                  ASSUME CS:codigo, DS:datos, SS:pila

                  ; poner dirección de retorno al DOS en la pila:

                  PUSH  DS        ; segmento del PSP
                  XOR   AX,AX     ; AX = 0
                  PUSH  AX        ; desplazamiento 0 al PSP

                  ; direccionar segmento de datos con DS

                  MOV    AX,datos ; AX = dirección del segmento de datos
                  MOV    DS,AX    ; inicializar DS

                  ; escribir texto                                          

                  LEA   DX,texto   ; DS:DX = dirección del texto
                  MOV   AH,9
                  INT   21h

                  ; volver al DOS

                  RET              ; en realidad, RETF (PROC FAR)

      ejemplo     ENDP                                                      

      codigo      ENDS             ; fin del código
                  END   ejemplo    ; punto de arranque del programa

6.4. - PROCESO DE ENSAMBLAJE.

6.4.1. - TASM/MASM.

     Es el programa que convierte nuestro listado fuente en código objeto, es decir, lenguaje máquina en el que sólo faltan las referencias a rutinas externas. Permite la obtención de listados de código y de referencias cruzadas (símbolos, etiquetas, variables). En general, bastará con hacer TASM nombre_programa (se supone la extensión .ASM por defecto). El fichero final tiene extensión OBJ. En general, la sintaxis del TASM y MASM es más o menos equivalente: en el primero se obtiene ayuda con /H y en el segundo con /HELP. Con TASM, cuando se va a obtener la versión definitiva del programa, o si éste es corto -o el ordenador rápido- merece la pena utilizar el parámetro /m3, con objeto de que de dos/tres pasadas y optimize más el código. Por su lado, MASM presenta estadísticas adicionales si se indica /v y se puede cambiar con /Btamaño el nº de Kb de memoria que destina al fichero fuente, entre 1 y 63. La sintaxis es (tanto para TASM como MASM):

TASM fichero_fuente, fichero_listado, fichero_referencias_cruzadas

     Se puede omitir el fichero de listado y el de referencias cruzadas. Cuando se emplea MASM 6.X, para ensamblar los listados de este libro hay que indicar la opción /Zm para mantener la compatibilidad con las versiones anteriores del ensamblador, siendo además obligatorio indicar la extensión; como se genera directamente el fichero EXE hay que indicar /c si se desea evitar esto (si no se quiere que linke). La sintaxis quedaría:

ML /Zm fihero_fuente.asm

A continuación se listan los parámetros comunes a TASM 2.0 (y posterior) y MASM 4.0/5.0 (NO la 6.X):

/a y /sSeleccionan un orden alfabético o secuencial de los segmentos.
/cGenera un listado de referencias cruzadas en un fichero de extensión CRF listo para ser procesado por CREF (MASM) añadiendo además números de línea al listado, o bien incluye el listado de referencias cruzadas directamente dentro del listado del programa (caso de TASM). Las referencias cruzadas son un listado de todos los símbolos del programa, indicando los números de línea del mismo en que son definidos y referenciados.
/DDe la manera /Dsímbolo[=valor] permite crear el símbolo indicado, cuya presencia puede comprobarse en el programa con una directiva IF (es útil para definir externamente un símbolo que indique que el programa está en fase de depuración, de cara a ensamblar cierto código adicional). Aunque /d (en minúsculas) es un obsoleto parámetro de MASM para obtener un listado de la primera pasada del ensamblador, MASM 4.0 es capaz de darse cuenta de que se pretende definir un símbolo con /d a menos que se indique solo /d.
/eEmula las instrucciones de punto flotante del 80x87, apoyándose en una librería al efecto.
/IrutaPermite indicar el directorio donde el ensamblador debe de buscar los ficheros indicados en el programa fuente con INCLUDE.
/l[a]Con /l se genera un listado de ensamblaje y con /la un listado expandido.
/mCon /m se indica el nivel de preservación del sentido de mayúsculas y minúsculas en los símbolos: /ml hace que se consideres diferentes mayúsculas de minúsculas en todos los símbolos, /mx sólo con los símbolos globales y /mu hace que se mayusculicen todos los símbolos globales. Al ensamblar módulos para usar desde lenguaje C hay que indicar por lo menos /mx. En MASM 6.X se emplea /Cx en lugar de /mx, /Cp en lugar de /ml y /Cu en vez de /mu.
/nSuprime las tablas de símbolos en el listado.
/pVerifica que el código generado para el modo protegido es correcto (al emplear la directiva para generar instrucciones de modo protegido).
/tSuprime los mensajes si el ensamblaje es correcto.
/wIndica el nivel de advertencias: /w0 ninguna, /w1 sólo las serias y /w2 sólo consejos.
/XLista las condiciones falsas (ensamblaje condicional).
/zVisualiza la línea del error y no sólo el número de la misma.
/ZiGenera información simbólica para los depuradores de código.
/ZdIncluye sólo la información del número de línea.

6.4.2. - TLINK/LINK.

     El montador o linkador permite combinar varios módulos objeto, realizando las conexiones entre ellos y, finalmente, los convierte en módulo ejecutable de tipo EXE (empleando el ML de MASM 6.X se obtiene directamente el fichero EXE ya que invoca automáticamente al linkador). El linkador permite el uso de librerías de funciones y rutinas. TLINK, a diferencia de LINK, permite generar un fichero de tipo COM directamente de un OBJ si se indica el parámetro /t, lo que agiliza aún más el proceso. Puede obtenerse ayuda ejecutándolo sin parámetros. Los parámetros de TLINK son sensibles a mayúsculas y minúsculas, por lo que /T no es lo mismo que /t. Con LINK se obtiene ayuda indicando /HELP. Aunque los parámetros de uno y otro son bastante distintos, la sintaxis genérica de ambos es:

TLINK fich_obj(s), fich_exe, fich_map, fich_libreria, fich_def

     Los ficheros no necesarios se pueden omitir (o indicar NUL): para linkar el fichero prog1.obj y el prog2.obj con la librería math.lib generando PROG1.EXE basta con ejecutar TLINK prog1+prog2,,,math. Alternativamente se puede indicar TLINK @fichero para que tome los parámetros del fichero de texto FICHERO, en el caso de que estos sean demasiados y sea incómodo teclearlos cada vez que se linka. Los ficheros de texto de extensión MAP contienen información útil para el programador sobre la distribución de memoria de los segmentos.

6.4.3. - EXE2BIN.

     Los ficheros EXE generados por TLINK o LINK no son copia exacta de lo que aparece en la memoria, sino que el DOS -tras cargarlos- debe realizar una última operación de «montaje». Un programa COM en memoria es una copia del fichero del disco, es algo más corto y más sencillo de desensamblar. Al contrario de lo que algunos opinaron en su día, el tiempo ha demostrado que nunca llegarían a ser directamente compatibles con los actuales entornos multitarea.

     EXE2BIN permite transformar un fichero EXE en COM siempre que el módulo ocupe menos de 64K y que esté ensamblado con ORG 100h. Si no se indicó el parámetro /t en TLINK, será necesario este programa (al igual que cuando se utiliza LINK). Cuando se crean programas SYS (que se diferencian de los COM básicamente en que no tienen ORG 100h) no se puede ejecutar TLINK /t, por lo que es necesaria la ayuda de EXE2BIN para convertir el programa EXE en SYS. Sintaxis:

EXE2BIN fich.exe (a veces hay que indicar EXE2BIN fich.exe fich.com)

     Si el programa no contiene ORG 100h, EXE2BIN genera un fichero binario puro de extensión BIN. Si además existen referencias absolutas a segmentos, EXE2BIN preguntará el segmento en que va a correr (algunas versiones permiten indicarlo de la manera /Ssegmento): esto permite generar código para ser ejecutado en un segmento determinado de la memoria (como pueda ser una memoria EPROM o ROM).

6.4.4. - TLIB/LIB.

     El gestor de librerías permite reunir módulos objeto en un único fichero para poder tomar de él las rutinas que se necesiten en cada caso. En este libro no se desarrollan programas tan complejos que justifiquen su utilización. En cualquier caso, la sintaxis es la siguiente:

TLIB fichero_libreria comandos, fichero_listado

     Si no se indican comandos se obtiene simplemente información del contenido de la librería en el fichero de listado (que puede ser CON para listado por pantalla). Los comandos son de la forma <simbolo>nombre_de_módulo y pueden ser los siguientes:


     +     añade el módulo objeto indicado a la librería
     -     borra el módulo indicado de la librería
     *     saca el módulo de la librería sin borrarlo (extrae fichero OBJ)
     -+     alternativamente +-, reemplaza el módulo existente en la librería
     -*     alternativamente *-, extrae el módulo de la librería y lo borra de ella

     Por ejemplo, para añadir el módulo QUICK.OBJ, borrar el SLOW.OBJ y reemplazar el SORT.OBJ por una nueva versión en LIBRERIA.LIB se ejecutaría:

TLIB libreria +quick-slow-+sort

     Si la lista es muy larga se puede incluir en un fichero y ejecutar TLIB @fichero para que la lea del mismo (si no cabe en una línea del fichero, puede escribirse & al final antes de pasar a la siguiente).

6.4.5. TCREF/CREF.

     Esta utilidad genera listados en orden alfabético de los símbolos, como ayuda a la depuración. Con el MASM la opción /c crea un fichero de referencias cruzadas de extensión CRF (respondiendo afirmativamente cuando pregunta por el mismo o indicándolo explícitamente en la línea de comandos); la opción /c de TASM lo incluye en el listado, aunque si se indica el nombre del fichero de referencias cruzadas genera un fichero de extensión XRF. CREF y TCREF interpretan respectivamente los ficheros CRF y XRF generando un fichero de texto con extensión REF que contiene el listado de referencias cruzadas. Ej.:

                    TASM fichero,,,fichero
                    TCREF fichero

     Las referencias cruzadas son un listado de todos los símbolos del programa, indicando los números de línea del mismo en que son referenciados (la línea en que son definidos se marca con #); estos números de línea son relativos al listado de ensamblaje del programa (y no al fichero fuente). Es útil para depurar programas grandes y complejos.

6.4.6. - MAKE.

     Esta utilidad se apoya en unos ficheros especiales, al estilo de los BAT del DOS, de cara a automatizar el proceso de ensamblaje. Sólo es recomendable para programas grandes, divididos en módulos, en los que MAKE chequea la fecha y hora para ensamblar sólo las partes que hayan sido modificadas.
 

6.5. - LA UTILIDAD DEBUG/SYMDEB.

     La utilidad DEBUG incluída en los sistemas MS-DOS, es una herramienta para depuración de programas muy interesante que permite desensamblar los módulos y, además, ejecutar programas paso a paso, viendo las modificaciones que sufren los registros y banderas. Se trata de un programa menos complejo, cómodo y potente que depuradores de código como Turbo Debugger (de Borland) o Codeview (Microsoft), pero en algunos casos es más útil. Veremos ahora los principales comandos del DEBUG, los cuales también son admitidos en su mayoría por Codeview, por lo que el tiempo invertido en aprenderlos será útil no sólo para conocer el clásico y mítico DEBUG.

     Antes de empezar con ellos, conviene hacer referencia al programa SYMDEB que acompaña al MASM de Microsoft: se trata de un DEBUG mejorado, con ayuda, más rápido e inteligente (indica el tipo de función del sistema cuando al tracear un programa éste llama al DOS) y, en la práctica, es 99% compatible. También admite las instrucciones adicionales del 286 y los NEC V20/V30. Su diferencia principal es que al abandonarlo para volver al DOS restaura los vectores de interrupción, lo que puede no ser deseable en algunos casos muy concretos. Además, desde la versión 4.0 se admite el parámetro /S (con SYMDEB /S nomfich.ext) lo que permite conmutar entre la pantalla de depuración y la de ejecución pulsando la tecla '\'.

          Sintaxis general:     DEBUG [programa.ext [parámetros] ]

     Los programas pueden ser de tipo EXE o COM; en el caso de los primeros se les cargará ya montados y con los registros inicializados, listos para su ejecución. Evidentemente, los programas COM también se cargan con los registros inicializados y el correspondiente PSP preparado, así como con IP=100h. Los parámetros opcionales no son los de el DEBUG o SYMDEB sino los que normalmente se suministrarían al programa a depurar. También se pueden cargar otros ficheros de cualquier extensión o simplemente entrar en el programa sin cargar ningún fichero. Al entrar, aparecerá el prompt particular del DEBUG: un guión (-). Entonces se pueden teclear órdenes que constarán generalmente de una sola letra. La mayoría de las mismas admiten parámetros, que normalmente irán separados por comas. Estos parámetos pueden ser números hexadecimales de hasta dos o cuatro dígitos, registros y, además:

     - Cadenas de caracteres: Encerradas entre comillas simples o dobles. El texto puede a su vez encerrar fragmentos entrecomillados, empleando comillas distintas a las más exteriores. Ejemplo:

               "Cadena de caracteres", "Otra 'cadena' más", 'Curso de "8086"'

          Con SYMDEB debe tenerse cuidado de no colocar el nombre de un registro de segmento en mayúsculas y seguido de dos puntos, ya que no se interpretará correctamente:

               "ESTO ES: ESTA CADENA SERA MAL TRADUCIDA."

          La cadena 'ES:' no será bien traducida a sus correspondientes valores ASCII. Con DEBUG este problema no existe.

     - Direcciones: Pueden expresarse con sus correspondientes valores numéricos o bien apoyándose en algún registro de segmento, aunque el offset siempre será numérico: 1E93:AD21, CS:100, ES:19AC

          El depurador SYMDEB es mucho más flexible y permite también emplear registros de propósito general en el offset. Sería válida la dirección DS:BX+AX+104.

     - Rangos: Son dos direcciones separadas por una coma; o bien una dirección, la letra 'L' y un valor numérico que indica el número de bytes a partir de la dirección.

     - Listas: Son secuencias de bytes y/o cadenas separadas por comas:

               AC, "Texto de ejemplo", 0D, 0A, '$'

     El DEBUG del MS-DOS 5.0 y el SYMDEB poseen una ayuda invocable con el comando ?, en la que se resumen las principales órdenes. A continuación se listan las más interesantes:

     * Q  (Quit): permite abandonar el programa y volver al DOS.

     * D [<dirección> [numbytes]]  (dump): visualiza el contenido de la memoria. SYMDEB permite además visualizarla en palabras (DW), dobles palabras (DD), coma flotante ...

     * A [<dirección>]  (assemble): permite ensamblar a partir de CS:IP si no se indica una dirección concreta. Se admiten las directivas DB y DW del ensamblador. Las instrucciones que requieran indicar un registro de segmento, con DEBUG hay que ponerlas en una sola línea. Por ejemplo:

          XLAT  CS:                     ; mal ensamblado con DEBUG (no así con SYMDEB)
          MOV   WORD PTR ES:[100],1234  ; error en DEBUG (sí vale con SYMDEB)
          CS:                           ; bien emsamblado con ambos
                         XLAT
          ES:                           ; y esto también
          MOV   WORD PTR [100],1234

          Los saltos inter-segmento deben especificarse como FAR (ej., CALL FAR [100]) a no ser que sea evidente que lo son (ej. CALL 1234:5678).

     * E <dirección> [<lista>]  (enter): permite consultar y modificar la memoria, byte a byte. Por ejemplo, con E 230 1,2,3 se introducirían los bytes 1, 2 y 3 a partir de DS:230. Si no se indica <lista>, se visualizará la memoria byte a byte, pudiéndose modificar los bytes deseados, avanzar al siguiente (barra espaciadora) o retroceder al anterior (signo -). Para acabar se pulsa RETURN.

     * U [<direccion> [<rango>]]  (unassemble): desensambla la memoria. Como ejemplos válidos: U ES:100, U E000:1940 ... si se indica rango, DEBUG desensamblará ese número de bytes y SYMDEB ese número de líneas. Por defecto se emplea CS: como registro de segmento.

     * R [<registro>]  (register): permite visualizar y modificar el valor de los registros. Por ejemplo, si se ejecuta la orden 'rip', se solicitará un nuevo valor para IP; con RF se muestran los flags y se permite modificar alguno:

Flag Activo Borrado
Desbordamiento OV NV
Dirección DN (v) UP (^)
Interrupción EI DI
Signo NG (<0) PL (>0)
Cero ZR (=0) NZ (!=0)
Acarreo auxiliar AC NA
Paridad PE (par) PO (impar)
Acarreo CY NC

     * G [=<dirección> [,<dirección>,...]]  (go): ejecuta código desde CS:IP (a menos que se indique una dirección concreta). Si se trabaja sobre memoria ROM no debe indicarse la segunda dirección. Para que el flujo del programa se detenga en la 2ª dirección o posteriores debe pasar necesariamente por ella(s). Se puede indicar hasta 10 direcciones donde debe detenerse.

     * T [<veces>]  (trace): ejecuta una instrucción del programa (a partir de CS:IP) mostrando a continuación el estado de los registros y la siguiente instrucción. Ejecutar T10 equivaldría a ejecutar 16 veces el comando T. Si la instrucción es CALL o INT, se ejecutará como tal introduciéndose en la subrutina o servidor de interrupciones correspondiente (SYMDEB no entra en los INT 21h).

     * P [<veces>]  (proceed): similar al comando T, pero al encontrarse un CALL o INT lo ejecuta de golpe sin entrar en su interior (ojo, ¡esto último falla al tracear sobre memoria ROM!).

     * N <especificacion_fichero>  (name): se asigna un nombre al programa que está siendo creado o modificado. Se puede indicar la trayectoria de directorios.

     * L [<dirección>] (load): carga el fichero de nombre indicado con el comando N. Si es ejecutable lo prepara adecuadamente para su inmediata ejecución. En BX:CX queda depositado el tamaño del fichero (BX=0 para ficheros de menos de 64 Kb). Por defecto, la dirección es CS:100h.

     * L <dirección> <unidad> <primer_sector> <num_sectores>  (load): carga sectores de la unidad 0, 1, ... (A, B, ...) a memoria. Se trata de sectores lógicos del DOS y no los sectores físicos de la BIOS. Las versiones antiguas de SYMDEB dan errores en particiones de más de 32 Mb.

     * W [<dirección>] (write): graba el contenido de una zona de memoria a disco. Si no se indica la dirección, se graba desde CS:100h hasta CS:100h+número_bytes; el número de bytes se indica en BX:CX (no es una dirección segmentada sino un valor de 32 bits). Si se trata de un EXE no se permitirá grabarlo (para modificarlos, hay que renombrarles para cambiarles la extensión, aunque de esta manera no serán montados al cargarlos).

     * W <dirección> <unidad> <primer_sector> <num_sectores>  (write): graba sectores de la memoria a disco en la unidad 0, 1, ... (A, B, ...). Se trata de sectores lógicos del DOS y no los sectores físicos de la BIOS. Las versiones antiguas de SYMDEB dan errores en particiones de disco duro de más de 32 Mb.

     * S <rango> <lista>  (search): busca una cadena de bytes por la memoria. Para buscar la cadena "PEPE" terminada por cero en un área de 512 bytes desde DS:100 se haría: S 100 L 200 "PEPE",0 (por defecto se busca en DS:). No se encontraría sin embargo "pepe" (en minúsculas).

     * F <rango> <lista>  (fill): llena la zona de memoria especificada con repeticiones de la lista de bytes indicada. Por ejemplo, para rellenar códigos 0AAh 100h bytes a partir de 9800h:0 se ejecutaría F 9800:0 L 100 AA; en vez de AA se podría haber indicado una lista de bytes o cadenas de caracteres.

     * C <rango> <dirección>  (compare): compara dos zonas de memoria mostrando las diferencias. Por ejemplo, para comparar 5 bytes de DS:100 y DS:200 se hace: C 100 L 5 200.

     * M <rango> <dirección>  (move): Más que mover, copia una zona de memoria en otra de manera inteligente (controlando los posibles solapamientos de los bloques).

     * I <puerto>  (input): visualiza la lectura del puerto de E/S indicado.

     * O <puerto> <valor>  (output): envia un valor a un puerto de E/S.

     * H <valor1> <valor2>  (hexaritmetic): muestra la suma y resta de valor1 y valor2, ambos operandos de un máximo de 16 bits (si hay desbordamiento se trunca el resultado, que tampoco excede los 16 bits).

     También existen comandos en DEBUG para acceder a la memoria expandida: XS (obtener el estado de la memoria expandida), XA npag (localizar npag páginas), XD handle (desalojar el handle indicado) y XM pagina_logica pagina_fisica handle (mapear páginas).

     Con SYMDEB pueden además colocarse, con suma facilidad, puntos de ruptura (breakpoints); con DEBUG se pueden implementar con la orden G (indicando más de una dirección hasta un máximo de 10, donde debe detenerse el programa si pasa por ellas) aunque es más incómodo. En SYMDEB se pueden definir con BP dirección, borrarse con BC num_breakpoint, habilitarse con BP num_breakpoint (necesario antes de emplearlos), deshabilitarse con BD num_breakpoint y listar los definidos con BL. Además, SYMDEB puede visualizar datos en coma flotante de 32, 64 y 80 bits con el comando D (DS, DL y DT).

     SYMDEB es realmente un depurador simbólico (SYMbolic DEBugger) que permite mostrar información adicional y depurar con mayor comodidad los programas que han sido ensamblados con información de depuración.

     Una posibilidad interesante de DEBUG y SYMDEB es que admiten el redireccionamiento del sistema operativo. Ello permite, por ejemplo, crear ficheros ASCII con órdenes y después suministrárselas al programa, como en el siguiente ejemplo: DEBUG < ORDENES.TXT. La última orden de este fichero deberá ser Q (quit), de lo contrario no se devolvería el control al DOS ni se podría parar el programa (la entrada por defecto -el teclado- no actúa). También es versátil la posibilidad de redireccionar la salida. Por ejemplo, tras DEBUG > SALIDA.TXT, se puede teclear un comando para desensamblar (U) y otro para salir (Q): en el disco aparecerá el fichero con los datos del desensamblaje (se teclea a ciegas, lógicamente, porque la salida por pantalla ha sido redireccionada al fichero). Por supuesto, también es posible redireccionar entrada y salida a un tiempo: DEBUG < ORDENES.TXT > SALIDA.


6.6 - LAS FUNCIONES DEL DOS Y DE LA BIOS.

     El código de la BIOS, almacenado en las memorias ROM del ordenador, constituye la primera capa de software de los ordenadores compatibles. La BIOS accede directamente al hardware, liberando a los programas de usario de las tareas más complejas. Parte del código de la BIOS es actualizado durante el arranque del ordenador, con los ficheros que incluye el sistema operativo. El sistema operativo o DOS propiamente dicho se instala después: el DOS no realiza ningún acceso directo al hardware, en su lugar se apoya en la BIOS, constituyendo una segunda capa de software. El DOS pone a disposición de los programas de usuario unas funciones muy evolucionadas para acceder a los discos y a los recursos del ordenador. Por encima del DOS se suele colocar habitualmente al COMMAND.COM, aunque realmente el COMMAND no constituye capa alguna de software: es un simple programa de utilidad, como cualquier otro, ejecutado sobre el DOS y que además no pone ninguna función a disposición del sistema (al menos, documentada), su única misión es cargar otros programas.

FUNCIONES DE LA BIOS

     Las funciones de la BIOS se invocan, desde los programas de usuario, ejecutando una interrupción software con un cierto valor inicial en los registros. La BIOS emplea un cierto rango de interrupciones, cada una encargada de una tarea específica:

     INT 10h:     Servicios de Vídeo (texto y gráficos).
     INT 11h:     Informe sobre la configuración del equipo.
     INT 12h:     Informe sobre el tamaño de la memoria convencional.
     INT 13h:     Servicios de disco (muy elementales: pistas, sectores, etc.).
     INT 14h:     Comunicaciones en serie.
     INT 15h:     Funciones casette (PC) y servicios especiales del sistema (AT).
     INT 16h:     Servicios de teclado.
     INT 17h:     Servicios de impresora.
     INT 18h:     Llamar a la ROM del BASIC (sólo máquinas IBM).
     INT 19h:     Reinicialización del sistema.
     INT 1Ah:     Servicios horarios.
     INT 1Fh:     Apunta a la tabla de los caracteres ASCII 128-255 (8x8 puntos).

     La mayoría de las interrupciones se invocan solicitando una función determinada (que se indica en el registro AH al llamar) y se limitan a devolver un resultado en ciertos registros, realizando la tarea solicitada. En general, sólo resultan modificados los registros que devuelven algo, aunque BP es corrompido en los servicios de vídeo de las máquinas más obsoletas.

FUNCIONES DEL DOS

     El DOS emplea varias interrupciones, al igual que la BIOS; sin embargo, cuando se habla de funciones del DOS, todo el mundo sobreentiende que se trata de llamar a la INT 21h, la interrupción más importante con diferencia.

     INT 20h:     Terminar programa (tal vez en desuso).
     INT 21h:     Servicios del DOS.
     INT 22h:     Control de finalización de programas.
     INT 23h:     Tratamiento de Ctrl-C.
     INT 24h:     Tratamiento de errores críticos.
     INT 25h:     Lectura absoluta de disco (sectores lógicos).
     INT 26h:     Escritura absoluta en disco (sectores lógicos).
     INT 27h:     Terminar dejando residente el programa (en desuso).
     INT 28h:     Idle (ejecutada cuando el ordenador está inactivo).
     INT 29h:     Impresión rápida en pantalla (no tanto).
     INT 2Ah:     Red local MS NET.
     INT 2Bh-2Dh:     Uso interno del DOS.
     INT 2Eh:     Procesos Batch.
     INT 2Fh:     Interrupción Multiplex.
     INT 30h-31h:     Compatibilidad CP/M-80.
     INT 32h:     Reservada.

     Las funciones del DOS se invocan llamando a la INT 21h e indicando en el registro AH el número de función a ejecutar. Sólo modifican los registros en que devuelven los resultados, devolviendo normalmente el acarreo activo cuando se produce un error (con un código de error en el acumulador). Muchas funciones de los lenguajes de programación frecuentemente se limitan a llamar al DOS.

     Todos los valores mostrados a continuación son hexadecimales; el de la izquierda es el número de función (lo que hay que cargar en AH antes de llamar); algunas funciones del DOS se dividen a su vez en subfunciones, seleccionables mediante AL (segundo valor numérico, en los casos en que aparece). Las funciones marcadas con U> fueron históricamente indocumentadas, aunque Microsoft desclasificó casi todas ellas a partir del MS-DOS 5.0 (en muchas secciones de este libro, escritas con anterioridad, se las referencia aún como indocumentadas). Se indica también la versión del DOS a partir de la que están disponibles.

     En general, se debe intentar emplear siempre las funciones que requieran la menor versión posible del DOS; sin embargo, no es necesario buscar la compatibilidad con el DOS 1.0: esta versión no soporta subdirectorios, y el sistema de ficheros se basa en el horroroso método FCB. Los FCB ya no están soportados siquiera en la ventana de compatibilidad DOS de OS/2, siendo recomendable ignorar su existencia y trabajar con los handles, al estilo del UNIX, que consisten en unos números que identifican a los ficheros cuando son abiertos. Existen 5 handles predefinidos permanentemente abiertos: 0 (entrada estándar -teclado-), 1 (salida estándar -pantalla-), 2 (salida de error estándar -también pantalla-), 3 (entrada/salida por puerto serie) y 4 (salida por impresora): la pantalla, el teclado, etc. pueden ser manejados como simples ficheros.

     Las funciones precedidas de un asterisco son empleadas o mencionadas en este libro, y pueden consultarse en el apéndice al efecto al final del mismo.

                                                ENTRADA/SALIDA DE CARACTERES

 AH AL Versión  Nombre original                                                                                   Traducción
 -- -- -------  ------------------------------------------------------------------------------------------------------------
 01 -- DOS 1+ - READ CHARACTER FROM STANDARD INPUT, WITH ECHO .......... LEER CARACTER DE LA ENTRADA ESTANDAR, CON IMPRESION
*02 -- DOS 1+ - WRITE CHARACTER TO STANDARD OUTPUT ................................. ESCRIBIR CARACTER EN LA SALIDA ESTANDAR
 03 -- DOS 1+ - READ CHARACTER FROM STDAUX .................................................. LEER CARACTER DEL PUERTO SERIE
 04 -- DOS 1+ - WRITE CHARACTER TO STDAUX ............................................. ESCRIBIR CARACTER EN EL PUERTO SERIE
 05 -- DOS 1+ - WRITE CHARACTER TO PRINTER ............................................... ESCRIBIR CARACTER EN LA IMPRESORA
 06 -- DOS 1+ - DIRECT CONSOLE OUTPUT ............................................................. SALIDA DIRECTA A CONSOLA
 06 -- DOS 1+ - DIRECT CONSOLE INPUT ........................................................... ENTRADA DIRECTA POR CONSOLA
 07 -- DOS 1+ - DIRECT CHARACTER INPUT, WITHOUT ECHO ............................ LECTURA DIRECTA DE CARACTER, SIN IMPRESION
 08 -- DOS 1+ - CHARACTER INPUT WITHOUT ECHO .......................................... LECTURA DE CARACTERES, SIN IMPRESION
*09 -- DOS 1+ - WRITE STRING TO STANDARD OUTPUT ...................................... ESCRIBIR CADENA EN LA SALIDA ESTANDAR
*0A -- DOS 1+ - BUFFERED INPUT ............................................................ ENTRADA DESDE TECLADO POR BUFFER
 0B -- DOS 1+ - GET STDIN STATUS ..................................................... OBTENER ESTADO DE LA ENTRADA ESTANDAR
 0C -- DOS 1+ - FLUSH BUFFER AND READ STANDARD INPUT .......................... LIMPIAR BUFFER Y LEER DE LA ENTRADA ESTANDAR


                                                    GESTION DE FICHEROS

 0F -- DOS 1+ - OPEN FILE USING FCB ...................................................... APERTURA DE FICHERO EMPLEANDO FCB
 10 -- DOS 1+ - CLOSE FILE USING FCB .......................................................... CERRAR FICHERO EMPLEANDO FCB
 11 -- DOS 1+ - FIND FIRST MATCHING FILE USING FCB ..................................... BUSCAR PRIMER FICHERO EMPLEANDO FCB
 12 -- DOS 1+ - FIND NEXT MATCHING FILE USING FCB ..................................... BUSCAR PROXIMO FICHERO EMPLEANDO FCB
 13 -- DOS 1+ - DELETE FILE USING FCB ......................................................... BORRAR FICHERO EMPLEANDO FCB
 16 -- DOS 1+ - CREATE OR TRUNCATE FILE USING FCB ...................................... CREAR/TRUNCAR FICHERO EMPLEANDO FCB
 17 -- DOS 1+ - RENAME FILE USING FCB ...................................................... RENOMBRAR FICHERO EMPLEANDO FCB
 23 -- DOS 1+ - GET FILE SIZE FOR FCB .............................................. OBTENER TAMAÑO DE FICHERO EMPLEANDO FCB
 29 -- DOS 1+ - PARSE FILENAME INTO FCB ....................................... EXPANDIR EL NOMBRE DEL FICHERO EMPLEANDO FCB
*3C -- DOS 2+ - "CREAT" - CREATE OR TRUNCATE FILE ................................... CREAR/TRUNCAR FICHERO EMPLEANDO HANDLE
*3D -- DOS 2+ - "OPEN" - OPEN EXISTING FILE ....................................... ABRIR FICHERO EXISTENTE EMPLEANDO HANDLE
*3E -- DOS 2+ - "CLOSE" - CLOSE FILE ............................................. CERRAR FICHERO EXISTENTE EMPLEANDO HANDLE
 41 -- DOS 2+ - "UNLINK" - DELETE FILE ..................................................... BORRAR FICHERO EMPLEANDO HANDLE
 43 00 DOS 2+ - GET FILE ATTRIBUTES ......................................... OBTENER ATRIBUTOS DEL FICHERO EMPLEANDO HANDLE
 43 01 DOS 2+ - "CHMOD" - SET FILE ATTRIBUTES ............................. MODIFICAR ATRIBUTOS DEL FICHERO EMPLEANDO HANDLE
 45 -- DOS 2+ - "DUP" - DUPLICATE FILE HANDLE ........................................................... DUPLICAR EL HANDLE
 46 -- DOS 2+ - "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE ................................... REDIRECCIONAR EL HANDLE
 4E -- DOS 2+ - "FINDFIRST" - FIND FIRST MATCHING FILE .............................. BUSCAR PRIMER FICHERO EMPLEANDO HANDLE
 4F -- DOS 2+ - "FINDNEXT" - FIND NEXT MATCHING FILE ............................... BUSCAR PROXIMO FICHERO EMPLEANDO HANDLE
 56 -- DOS 2+ - "RENAME" - RENAME FILE .................................................. RENOMBRAR FICHERO EMPLEANDO HANDLE
 57 00 DOS 2+ - GET FILE'S DATE AND TIME ................................. OBTENER FECHA Y HORA DEL FICHERO EMPLEANDO HANDLE
 57 01 DOS 2+ - SET FILE'S DATE AND TIME .............................. ESTABLECER FECHA Y HORA DEL FICHERO EMPLEANDO HANDLE
 5A -- DOS 3+ - CREATE TEMPORARY FILE .............................................. CREAR FICHERO TEMPORAL EMPLEANDO HANDLE
 5B -- DOS 3+ - CREATE NEW FILE ............................. CREAR NUEVO FICHERO SIN MACHACARLO SI EXISTIA EMPLEANDO HANDLE
 67 -- DOS 3.3+ - SET HANDLE COUNT .............................. ESTABLECER MAXIMO NUMERO DE HANDLES PARA LA TAREA EN CURSO
 68 -- DOS 3.3+ - "FFLUSH" - COMMIT FILE ................................................... VOLCAR BUFFERS INTERNOS A DISCO
 

                                                OPERACIONES SOBRE FICHEROS

 14 -- DOS 1+ - SEQUENTIAL READ FROM FCB FILE .................................. LECTURA SECUENCIAL DE FICHERO EMPLEANDO FCB
 15 -- DOS 1+ - SEQUENTIAL WRITE TO FCB FILE ................................. ESCRITURA SECUENCIAL EN FICHERO EMPLEANDO FCB
*1A -- DOS 1+ - SET DISK TRANSFER AREA ADDRESS ................................. ESTABLECER EL AREA DE TRANSFERENCIA A DISCO
 21 -- DOS 1+ - READ RANDOM RECORD FROM FCB FILE ............................... LECTURA ALEATORIA DE REGISTRO EMPLEANDO FCB
 22 -- DOS 1+ - WRITE RANDOM RECORD TO FCB FILE .............................. ESCRITURA ALEATORIA DE REGISTRO EMPLEANDO FCB
 24 -- DOS 1+ - SET RANDOM RECORD NUMBER FOR FCB ......................... PASAR DE E/S SECUENCIAL A ALEATORIA EMPLEANDO FCB
 27 -- DOS 1+ - RANDOM BLOCK READ FROM FCB FILE .................................. LECTURA ALEATORIA DE BLOQUE EMPLEANDO FCB
 28 -- DOS 1+ - RANDOM BLOCK WRITE TO FCB FILE ................................. ESCRITURA ALEATORIA DE BLOQUE EMPLEANDO FCB
*2F -- DOS 2+ - GET DISK TRANSFER AREA ADDRESS ...................... OBTENER LA DIRECCION DEL AREA DE TRANSFERENCIA A DISCO
*3F -- DOS 2+ - "READ" - READ FROM FILE OR DEVICE ...................................... LEER DE UN FICHERO EMPLEANDO HANDLE
*40 -- DOS 2+ - "WRITE" - WRITE TO FILE OR DEVICE .................................. ESCRIBIR EN UN FICHERO EMPLEANDO HANDLE
 42 -- DOS 2+ - "LSEEK" - SET CURRENT FILE POSITION ............... MOVER EL PUNTERO RELATIVO EN EL FICHERO EMPLEANDO HANDLE
 5C -- DOS 3+ - "FLOCK" - RECORD LOCKING ......................... BLOQUEAR/DESBLOQUER UNA ZONA DEL FICHERO EMPLEANDO HANDLE


                                                OPERACIONES CON DIRECTORIOS

 39 -- DOS 2+ - "MKDIR" - CREATE SUBDIRECTORY .......................................................... CREAR SUBDIRECTORIO
 3A -- DOS 2+ - "RMDIR" - REMOVE SUBDIRECTORY ......................................................... BORRAR SUBDIRECTORIO
 3B -- DOS 2+ - "CHDIR" - SET CURRENT DIRECTORY ............................................... CAMBIAR EL DIRECTORIO ACTIVO
 47 -- DOS 2+ - "CWD" - GET CURRENT DIRECTORY ................................................. OBTENER EL DIRECTORIO ACTUAL
 

                                                      MANEJO DE DISCO 

 0D -- DOS 1+ - DISK RESET .......................................................................... REINICIALIZAR EL DISCO
 0E -- DOS 1+ - SELECT DEFAULT DRIVE ......................................................... ESTABLECER UNIDAD POR DEFECTO
 19 -- DOS 1+ - GET CURRENT DEFAULT DRIVE ............................................. OBTENER LA UNIDAD ACTUAL POR DEFECTO
 1B -- DOS 1+ - GET ALLOCATION INFORMATION FOR DEFAULT DRIVE ........ OBTENER INFORMACION DE ESPACIO EN EL DISCO POR DEFECTO
 1C -- DOS 1+ - GET ALLOCATION INFORMATION FOR SPECIFIC DRIVE .......... OBTENER INFORMACION DE ESPACIO EN EL DISCO INDICADO
 2E -- DOS 1+ - SET VERIFY FLAG ..................................................... ESTABLECER EL BANDERIN DE VERIFICACION
*36 -- DOS 2+ - GET FREE DISK SPACE ...................................................... OBTENER EL ESPACIO LIBRE EN DISCO
 54 -- DOS 2+ - GET VERIFY FLAG ........................................................ OBTENER EL BANDERIN DE VERIFICACION
 

                                                    CONTROL DE PROCESOS 

 00 -- DOS 1+ - TERMINATE PROGRAM ........................................................................ TERMINAR PROGRAMA
 26 -- DOS 1+ - CREATE NEW PROGRAM SEGMENT PREFIX ................................................................ CREAR PSP
*31 -- DOS 2+ - TERMINATE AND STAY RESIDENT ................................................ TERMINAR Y PERMANECER RESIDENTE
*4B -- DOS 2+ - "EXEC" - LOAD AND/OR EXECUTE PROGRAM .......................................... CARGAR Y/O EJECUTAR PROGRAMA
*4C -- DOS 2+ - "EXIT" - TERMINATE WITH RETURN CODE ................................ TERMINAR PROGRAMA CON CODIGO DE RETORNO
 4D -- DOS 2+ - GET RETURN CODE .................................................................. OBTENER CODIGO DE RETORNO
*50 -- DOS 2+ internal - SET CURRENT PROCESS ID (SET PSP ADDRESS) ...................... ESTABLECER DIRECCION DEL PSP ACTUAL
*51 -- DOS 2+ internal - GET CURRENT PROCESS ID (GET PSP ADDRESS) ......................... OBTENER DIRECCION DEL PSP ACTUAL
*62 -- DOS 3+ - GET CURRENT PSP ADDRESS ................................................... OBTENER DIRECCION DEL PSP ACTUAL
 

                                                     GESTION DE MEMORIA 

*48 -- DOS 2+ - ALLOCATE MEMORY ............................................................................ ASIGNAR MEMORIA
*49 -- DOS 2+ - FREE MEMORY ................................................................................ LIBERAR MEMORIA
*4A -- DOS 2+ - RESIZE MEMORY BLOCK ................................... MODIFICAR EL TAMAÑO DE UN BLOQUE DE MEMORIA ASIGNADA
*58 -- DOS 3+ - GET OR SET MEMORY ALLOCATION STRATEGY ............ OBTENER/ESTABLECER LA ESTRATEGIA DE ASIGNACION DE MEMORIA
*58 -- DOS 5.0 - GET OR SET UMB LINK STATE ................. OBTENER/ESTABLECER EL ESTADO DE CONEXION DE LA MEMORIA SUPERIOR
 

                                                   CONTROL DE FECHA Y HORA 

*2A -- DOS 1+ - GET SYSTEM DATE ............................................................... OBTENER LA FECHA DEL SISTEMA
 2B -- DOS 1+ - SET SYSTEM DATE ............................................................ ESTABLECER LA FECHA DEL SISTEMA
*2C -- DOS 1+ - GET SYSTEM TIME ................................................................ OBTENER LA HORA DEL SISTEMA
 2D -- DOS 1+ - SET SYSTEM TIME ............................................................. ESTABLECER LA HORA DEL SISTEMA
 

                                                     FUNCIONES MISCELANEAS 

 18 -- DOS 1+ - NULL FUNCTION FOR CP/M COMPATIBILITY ................................. FUNCION NULA PARA COMPATIBILIDAD CP/M
 1D -- DOS 1+ - NULL FUNCTION FOR CP/M COMPATIBILITY ................................. FUNCION NULA PARA COMPATIBILIDAD CP/M
 1E -- DOS 1+ - NULL FUNCTION FOR CP/M COMPATIBILITY ................................. FUNCION NULA PARA COMPATIBILIDAD CP/M
 1F -- DOS 1+ - GET DRIVE PARAMETER BLOCK FOR DEFAULT DRIVE ........................ OBTENER EL DPB DE LA UNIDAD POR DEFECTO
 20 -- DOS 1+ - NULL FUNCTION FOR CP/M COMPATIBILITY ................................. FUNCION NULA PARA COMPATIBILIDAD CP/M
*25 -- DOS 1+ - SET INTERRUPT VECTOR ..................................................... ESTABLECER VECTOR DE INTERRUPCION
*30 -- DOS 2+ - GET DOS VERSION .................................................................... OBTENER VERSION DEL DOS
 32 -- DOS 2+ - GET DOS DRIVE PARAMETER BLOCK FOR SPECIFIC DRIVE ...................... OBTENER EL DPB DE LA UNIDAD INDICADA
 33 -- DOS 2+ - EXTENDED BREAK CHECKING ...................................... CONTROLAR EL NIVEL DE DETECCION DE CTRL-BREAK
 33 02 DOS 3.x+ internal - GET AND SET EXTENDED CONTROL-BREAK CHECKING STATE .... INDICAR/OBTENER NIVEL DETECCION CTRL-BREAK
 33 05 DOS 4+ - GET BOOT DRIVE ............................................................... DETERMINAR UNIDAD DE ARRANQUE
 33 06 DOS 5.0 - GET TRUE VERSION NUMBER ...................................................... OBTENER VERSION REAL DEL DOS
*34 -- DOS 2+ - GET ADDRESS OF INDOS FLAG .................................................... OBTENER LA DIRECCION DE INDOS
*35 -- DOS 2+ - GET INTERRUPT VECTOR ..................................... OBTENER LA DIRECCION DE UN VECTOR DE INTERRUPCION
 37 00 DOS 2+ - "SWITCHAR" - GET SWITCH CHARACTER .............................. OBTENER EL CARACTER INDICADOR DE PARAMETROS
 37 01 DOS 2+ - "SWITCHAR" - SET SWITCH CHARACTER ........................... ESTABLECER EL CARACTER INDICADOR DE PARAMETROS
 37 -- DOS 2.x and 3.3+ only - "AVAILDEV" - SPECIFY \DEV\ PREFIX USE .................... CONTROLAR EL USO DEL PREFIJO \DEV\
*38 -- DOS 2+ - GET COUNTRY-SPECIFIC INFORMATION ...................................... OBTENER INFORMACION RELATIVA AL PAIS
 38 -- DOS 3+ - SET COUNTRY CODE ............................................................. ESTABLECER EL CODIGO DEL PAIS
 44 00 DOS 2+ - IOCTL - GET DEVICE INFORMATION ............................ CONTROL E/S: OBTENER INFORMACION DEL DISPOSITIVO
 44 01 DOS 2+ - IOCTL - SET DEVICE INFORMATION ......................... CONTROL E/S: ESTABLECER INFORMACION DEL DISPOSITIVO
 44 02 DOS 2+ - IOCTL - READ FROM CHARACTER DEVICE CONTROL CHANNEL ......... CONTROL E/S: LEER DE CANAL CONTROL DISP. CARAC.
 44 03 DOS 2+ - IOCTL - WRITE TO CHARACTER DEVICE CONTROL CHANNEL ...... CONTROL E/S: ESCRIBIR EN CANAL CONTROL DISP. CARAC.
 44 04 DOS 2+ - IOCTL - READ FROM BLOCK DEVICE CONTROL CHANNEL ............. CONTROL E/S: LEER DE CANAL CONTROL DISP. BLOQUE
 44 05 DOS 2+ - IOCTL - WRITE TO BLOCK DEVICE CONTROL CHANNEL .......... CONTROL E/S: ESCRIBIR EN CANAL CONTROL DISP. BLOQUE
 44 06 DOS 2+ - IOCTL - GET INPUT STATUS ......................................... CONTROL E/S: OBTENER ESTADO DE LA ENTRADA
 44 07 DOS 2+ - IOCTL - GET OUTPUT STATUS ......................................... CONTROL E/S: OBTENER ESTADO DE LA SALIDA
 44 08 DOS 3.0+ - IOCTL - CHECK IF BLOCK DEVICE REMOVABLE ........ CONTROL E/S: COMPROBAR SI EL DISP. DE BLOQUE ES REMOVIBLE
 44 09 DOS 3.1+ - IOCTL - CHECK IF BLOCK DEVICE REMOTE .............. CONTROL E/S: COMPROBAR SI EL DISP. DE BLOQUE ES REMOTO
 44 0A DOS 3.1+ - IOCTL - CHECK IF HANDLE IS REMOTE .......................... CONTROL E/S: COMPROBAR SI UN HANDLE ES REMOTO
 44 0B DOS 3.1+ - IOCTL - SET SHARING RETRY COUNT ........ CONTROL E/S: DEFINIR NUMERO DE REINTENTOS EN MODO DE COMPARTICION
 44 0C DOS 3.2+ - IOCTL - GENERIC CHARACTER DEVICE REQUEST ............. CONTROL E/S GENERAL PARA DISPOSITIVOS DE CARACTERES
 44 0D DOS 3.2+ - IOCTL - GENERIC BLOCK DEVICE REQUEST ..................... CONTROL E/S GENERAL PARA DISPOSITIVOS DE BLOQUE
 44 0E DOS 3.2+ - IOCTL - GET LOGICAL DRIVE MAP ..................................... OBTENER ASIGNACION DE UNIDADES LOGICAS
 44 0F DOS 3.2+ - IOCTL - SET LOGICAL DRIVE MAP ..................................... DEFINIR ASIGNACION DE UNIDADES LOGICAS
*52 -- U> DOS 2+ internal - "SYSVARS" - GET LIST OF LISTS ..................... OBTENER EL LISTADO DE LAS LISTAS DEL SISTEMA
 53 -- DOS 2+ internal - TRANSLATE BIOS PARAMETER BLOCK TO DRIVE PARAM BLOCK ............................ TRADUCIR BPB A DPB
 55 -- DOS 2+ internal - CREATE CHILD PSP ................................................................... CREAR PSP HIJO
*59 -- DOS 3+ - GET EXTENDED ERROR INFORMATION .................................... OBTENER INFORMACION EXTENDIDA DE ERRORES
*5D 06 U> DOS 3.0+ internal - GET ADDRESS OF DOS SWAPPABLE DATA AREA ..... OBTENER DIRECCION DEL AREA INTERCAMBIABLE DEL DOS
*5D 0A DOS 3.1+ - SET EXTENDED ERROR INFORMATION ............................... ESTABLECER INFORMACION EXTENDIDA DE ERRORES
*5D 0B U> DOS 4.x only internal - GET DOS SWAPPABLE DATA AREAS ....................... OBTENER AREAS INTERCAMBIABLES DEL DOS
 60 -- DOS 3.0+ - CANONICALIZE FILENAME OR PATH ........ EXPANDIR NOMBRE DE FICHERO A ESPECIFICACION COMPLETA DE DIRECTORIOS
 61 -- DOS 3+ - UNUSED .........................................................................................NO USADA AUN
 64 -- DOS 3.2+ internal - SET DEVICE DRIVER LOOKAHEAD FLAG ....... ESTABLECER BANDERIN DE LECTURA ADELANTADA DE DISPOSITIVO
 65 -- DOS 3.3+ - GET EXTENDED COUNTRY INFORMATION .................................. OBTENER INFORMACION EXTENDIDA DEL PAIS
 65 23 U> DOS 4+ internal - DETERMINE IF CHARACTER REPRESENTS YES/NO RESPONSE ....... DETERMINAR SI UNA LETRA INDICA SI O NO
 65 -- U> DOS 4+ internal - COUNTRY-DEPENDENT FILENAME CAPITALIZATION ....... MAYUSCULIZACION DE NOMBRE DEPENDIENTE DEL PAIS
 66 01 DOS 3.3+ - GET GLOBAL CODE PAGE TABLE ........................................... OBTENER LA PAGINA DE CODIGOS GLOBAL
 66 02 DOS 3.3+ - SET GLOBAL CODE PAGE TABLE ........................................ ESTABLECER LA PAGINA DE CODIGOS GLOBAL
 69 -- U> DOS 4+ internal - GET/SET DISK SERIAL NUMBER ................... OBTENER/ESTABLECER EL NUMERO DE SERIE DE UN DISCO
 6B -- U> DOS 5.0 - NULL FUNCTION ............................................................................. FUNCION NULA
 6C 00 DOS 4+ - EXTENDED OPEN/CREATE .............................. APERTURA/CREACION DE FICHEROS EXTENDIDA EMPLEANDO HANDLE

  • Volver al Índice