Tutorial avanzado de Turbopascal Capítulo 1 Tecnología de programación avanzada de TURBO PASCAL
TURBO PASCAL es un producto de la empresa estadounidense BORLAND International y tiene una ventaja absoluta en el mercado de microcomputadores PASCAL. Supera las deficiencias del sistema de compilación PASCAL habitual que ocupa mucha memoria y realiza muchas extensiones útiles al PASCAL estándar, como su capacidad para manejar software y hardware de bajo nivel, sus poderosas capacidades gráficas y su soporte para Métodos de programación orientada a objetos, soporte para programación WINDOWS, etc. Es un lenguaje de programación de sistemas verdaderamente universal que es muy adecuado para desarrollar software de aplicaciones avanzadas, sistemas de gestión de bases de datos, compiladores, etc. Además, TURBO PASCAL también está equipado con un entorno de desarrollo de software integrado de alto rendimiento, que incluye una serie de funciones como edición, compilación, depuración y gestión de archivos.
Este capítulo explica las técnicas prácticas para desarrollar software avanzado utilizando TURBO PASCAL e introduce cómo utilizar algunas herramientas y técnicas para brindar comodidad a los programadores de TURBO PASCAL. Este capítulo describirá la tecnología de uso de unidades en programación, la tecnología de programación híbrida de TURBO PASCAL con lenguaje ensamblador y lenguaje C, la tecnología de implementación y uso de matrices dinámicas, los métodos de escritura de rutinas de interrupción, el uso de memoria extendida (EMS) y la expansión en programas. (XMS) método y método de procesamiento de datos estándar del programa como código, etc. Una unidad es un conjunto de procedimientos y funciones de TURBO PASCAL que se pueden compilar por separado de un programa TURBO PASCAL. Debido a que las unidades se compilan por separado, los programas que usan unidades se compilan rápidamente. Además, una sola unidad puede ser utilizada por múltiples programas. Aprovechar al máximo las ventajas de las unidades no sólo puede acelerar el desarrollo de software, sino también mejorar la capacidad de mantenimiento del programa.
§1.1.1 Estructura de la unidad
Una unidad consta de dos partes: la parte de interfaz y la parte de implementación. Por ejemplo:
unidad
interfaz {comienzo de la parte de la interfaz}
usa {Parte de descripción pública ***} implementación {comienza la parte de implementación} {Parte de descripción privada} {Definición de proceso o función } comenzar {Inicio de la parte de inicialización} {Código de inicialización} fin. 1. unidad Comienza con la palabra reservada interfaz, entre el encabezado de la unidad y la parte de implementación. En esta sección, se describen los encabezados de constantes, tipos, variables, procedimientos y funciones comunes. Si un programa utiliza una unidad, puede acceder a todas las variables, tipos de datos, procedimientos y funciones definidas en la parte de interfaz de la unidad. La parte de la interfaz solo contiene los encabezados de procedimientos y funciones. Las partes de implementación de procedimientos y funciones se definen en la parte de implementación de la unidad. Para utilizar una unidad en un programa, sólo necesita saber cómo llamar a los procedimientos en la unidad, pero no cómo se implementan los procedimientos. 2. Parte de implementación La parte de implementación comienza con la palabra reservada implementación. La parte de implementación define el cuerpo del programa para todos los procedimientos y funciones declarados en la parte de la interfaz. Además, la parte de implementación puede tener sus propias instrucciones. Estas instrucciones son programas locales y externos que no conocen su existencia y no pueden llamarlas. Debido a que todos los objetos declarados en la parte de implementación tienen un alcance local, los cambios en la parte de implementación no son visibles para otras unidades y programas. Por lo tanto, modificar la parte de implementación de una unidad no requiere recompilar la unidad que usa esta unidad. Solo necesita compilar la unidad modificada y el programa que usa esta unidad. Sin embargo, si se modifica la parte de la interfaz, todas las unidades y programas que utilicen esta unidad deberán volver a compilarse o incluso modificarse. En la parte de implementación, si hay una cláusula de usos, debe seguir a la palabra reservada implementación. Si la descripción del procedimiento es de tipo externo, debe utilizar el comando de compilación {$L file name.OBJ} para vincularlo al programa. Las funciones o procedimientos descritos en la parte de la interfaz, excepto los tipos en línea, deben reproducirse en la parte de implementación y sus encabezados deben ser coherentes con la parte de la interfaz o utilizar un formato abreviado. 3. Parte de inicialización La parte de implementación completa de la unidad generalmente se incluye entre las palabras reservadas implementación y final. Sin embargo, si coloca la palabra reservada comenzar antes de finalizar y escribe algunas declaraciones entre ellas, estas declaraciones serán la parte de inicialización de la unidad. Cualquier variable se puede inicializar en la parte de inicialización, y estas variables pueden ser utilizadas por la unidad o por el programa a través de la parte de interfaz. Los archivos se pueden abrir en esta sección para que los utilicen los programas. Por ejemplo, la unidad estándar Impresora usa su sección de inicialización para dirigir todas las llamadas de salida al archivo de texto Lst para que pueda usarse en declaraciones de escritura. Cuando se ejecuta un programa que utiliza unidades, antes de ejecutar el cuerpo principal del programa, las partes de inicialización de todas las unidades que utiliza se llaman en el orden especificado en la cláusula de usos. §1.1.2 Uso de unidades Cuando utilice unidades, debe enumerar los nombres de todas las unidades utilizadas en la declaración de usos, con comas (,) separadas. Por ejemplo: uses dos,crt; Cuando el compilador escanea la cláusula uses, agrega la información de la interfaz de cada unidad a la tabla de símbolos y al mismo tiempo agrega la parte de implementación El código de máquina está conectado con el código del programa. 1. Referencia directa a unidades La cláusula de usos de un módulo (programa o unidad) solo necesita enumerar los nombres de las unidades utilizadas directamente por el módulo. Por ejemplo: programa prog; usa unidad2; const a = b; comenzar writeln('a=',a); end. unidad unidad2; interfaz utiliza unidad1; const b = c; implementación end. unidad unidad1; interfaz const c = 1; implementación const b = 2; end. La unidad2 usa la unidad1, el programa principal usa la unidad2 e indirectamente usa la unidad1. Si se cambia la parte de la interfaz de la unidad, se deben volver a compilar todas las unidades o programas que utilicen esta unidad. Pero si se cambia la parte de implementación de la unidad, no es necesario volver a compilar la unidad que la utiliza. En el ejemplo anterior, si se cambia la parte de la interfaz de la unidad1 (como C=2), se debe volver a compilar la unidad2; si solo se cambia la parte de implementación (b=1), no es necesario volver a compilar la unidad2. Al compilar una unidad, TURBO PASCAL calcula el número de versión de la unidad, que es la suma de verificación de la parte de la interfaz de la unidad. En el ejemplo anterior, al compilar la unidad2, el número de versión actual de la unidad1 se almacena en la versión compilada de la unidad2. Al compilar el programa principal, el número de versión de la unidad1 se compara con el número de versión almacenado en la unidad2. , significa que unit2 está compilada, la parte de la interfaz de unit1 ha sido cambiada, el compilador muestra un mensaje de error y vuelve a compilar unit2. 2. Referencia circular de la unidad Dado que la unidad utilizada en la parte de implementación es invisible para el usuario, la cláusula de usos se coloca en la parte de implementación de la unidad para ocultarla aún más. la unidad. El siguiente ejemplo ilustra cómo dos unidades se refieren entre sí. El programa principal Circular utiliza la unidad de visualización, y la unidad de visualización explica el proceso Writexy en la parte de la interfaz. Tiene tres parámetros: valores de coordenadas xey e información de texto que se mostrará si (x, y). en la pantalla, Writexy mueve el cursor a (x, y) y muestra la información; de lo contrario, se llama al procedimiento simple de manejo de errores ShowError, y el procedimiento ShowError a su vez llama a Writexy para mostrar la información del error, lo que crea un problema de referencia circular. de la unidad. Programa principal: programa circular; usa crt,display; comenzar writexy(1,1,'Esquina superior izquierda de la pantalla'); writexy(100,100,'Camino de la pantalla'); writexy(81-length ('Regreso a la realidad'),15,'Regreso a la realidad'); fin. unidad de visualización: unidad de visualización; interfaz procedimiento Writexy(x,y:integer;Message:string); implementación usa CRT,Error; procedimiento Writexy; comenzar si (x en [1..80]) y (y en [1..25]) entonces comenzar gotoxy(x,y); escribir(mensaje); fin otro ShowError('Coordenadas Writexy no válidas'); end; end. Unidad de error: Error de unidad; interfaz procedimiento ShowError(ErrMessage); implementación utiliza visualización; procedimiento ShowError; comenzar Writexy(1,25,'Error: '+ErrMessage); fin; fin. Las cláusulas de uso de las partes de implementación de las unidades de visualización y error se refieren entre sí. TURBO PASCAL puede compilar completamente las partes de la interfaz de las dos unidades. Siempre que las partes de la interfaz no dependan entre sí, las partes de implementación pueden llamarse entre sí. otro. §1.1.3 Unidades y programas grandes Las unidades son la base de la programación modular TURBO PASCAL. Se utilizan para crear procedimientos y funciones que pueden ser utilizadas por muchos programas pero que no. Requiere programas fuente. Biblioteca, que es la base para dividir un programa grande en múltiples módulos relacionados. Normalmente, un programa grande se puede dividir en unidades, que agrupan el proceso por su funcionalidad. Por ejemplo, un programa de edición se puede dividir en varias partes, como inicialización, impresión, lectura y escritura de archivos y formato. Alternativamente, puede haber una unidad "global" que defina constantes, tipos de datos, variables, procedimientos y funciones globales, que pueden ser utilizados por todas las unidades y el programa principal. El marco de un programa grande es el siguiente: Editor de programas; usa dos, crt, impresora, p> EditarGlobal; EditarInit; EditarImprimir; Editar Archivo; EditarFormato; ... ... comenzar ... finalizar. Otra razón para utilizar unidades en el desarrollo de programas grandes es relacionado con las restricciones del segmento de Código. El procesador 8086 requiere una longitud de segmento de código de hasta 64 K. Esto significa que ni el programa principal ni ninguna unidad pueden superar los 64K. TURBOPASCAL resuelve este problema colocando cada unidad en un segmento separado. §1.2 Programación mixta con lenguaje ensamblador TURBO PASCAL es famoso por su rápida velocidad de compilación y su código objeto generado compacto y de alta velocidad. En la mayoría de los casos, se pueden completar diversas programaciones usando solo TURBO PASCAL. Sin embargo, en los programas de interfaz de hardware, programas de control en tiempo real y operaciones de punto flotante a gran escala, se requiere lenguaje ensamblador para la programación. Aunque TURBO PASCAL proporciona declaraciones y comandos INLINE, así como lenguaje ensamblador integrado (TURBO PASCAL 6.00), esto está lejos de ser suficiente. Esta sección analiza en detalle la tecnología de programación híbrida entre TURBO PASCAL y el lenguaje ensamblador, y enumera una gran cantidad de ejemplos. §1.2.1 Protocolo de llamada de TURBO PASCAL Al programar un programa TURBO PASCAL y una subrutina de ensamblaje externo juntos, el método de llamada de la subrutina y la transferencia de parámetros de funciones o procedimientos deben Estar involucrado. A continuación se analiza cómo los métodos y funciones devuelven valores. §1.2.1.1 El método de llamada de subprogramas y el método de retorno de subprogramas Cuando el programa TURBO PASCAL llama al subprograma de ensamblaje, puede ser una llamada cercana o una llamada lejana. Por lo tanto, cuando el programa TURBO PASCAL llama a la subrutina de ensamblaje, hay dos métodos diferentes para guardar la dirección de retorno dependiendo del método de llamada: ① Cuando se llama recientemente, debido a que es una llamada dentro del segmento, solo se inserta la dirección IP de desplazamiento la pila, que ocupa 2 bytes; ② Cuando se llama de forma remota, debido a que es una llamada entre segmentos, el valor del segmento de código CS y la dirección de desplazamiento IP deben colocarse en la pila, que ocupa 4 bytes. Cuando la subrutina de ensamblaje se llama directamente en el programa principal, generalmente se usa una llamada cercana y la subrutina de ensamblaje usa un método de retorno cercano. Cuando se usa la instrucción RET, hay dos situaciones cuando se usa una subrutina de ensamblaje; en una unidad TURBO PASCAL: ① Para los subprogramas explicados en la parte de la interfaz de la unidad, se debe usar el método de retorno lejano en el subprograma de ensamblaje y se debe usar la instrucción RETF ② Para los subprogramas explicados en la sección de explicación de la unidad, el retorno cercano; El método debe usarse en el subprograma de ensamblaje y se debe usar la instrucción RET. Después de que finaliza el subprograma de ensamblaje, para regresar correctamente al programa de llamada, el puntero superior de la pila debe apuntar a la dirección de retorno correcta, que se inserta en la pila proporcionando parámetros en la instrucción de retorno. RETF (o RET) Se implementa mediante el método del número de bytes ocupados por el tiempo. §1.2.1.2 Método de paso de parámetros TURBO PASCAL usa la pila para pasar parámetros a procedimientos y funciones. Los parámetros se ingresan de izquierda a derecha (orden de descripción). pila, por ejemplo, al llamar al procedimiento PROC (A, B, C: INTEGER; VAR D), la situación de la pila se muestra en la Figura 1-1. 殌┌────────────┐ │+0E│ El valor del parámetro A│ ↑ │ ├─ ─ ──────────┤ │ Parámetro│+0C│ Valor del parámetro B│ │Parámetro │ ├───────── ─ ──┤ │ Número│+0A│ Valor del parámetro C│ │Número │ ├────────────┤ │ Presione│ +8│ Dirección de segmento del parámetro D│ │Out │ ├─────────────┤ │ Pila│ +6 │ Dirección de compensación del parámetro D│ │Stack │ ├────────────┤ │ Shun│ +4│ Dirección de segmento devuelta por el proceso │ │Evitar │ ├─────────────┤ │ Pedido│ +2│ Dirección de compensación devuelta por el proceso│ │Pedido ↓ ├────────────┤ │ │ Valor del registro de PA│ └────── ─── ───┘ Figura 1-1. La situación de la pila de TURBO PASCAL llamando remotamente al ensamblador PROC Cuando TURBO PASCAL llama a una subrutina, hay dos métodos para pasarla. parámetros. Es decir, el método para pasar valor y dirección. Estos dos métodos de paso de parámetros se explican a continuación. Los métodos para insertar varios tipos de parámetros en la pila se muestran en la Tabla 1-1. (1) Método de paso de valores En la lista de parámetros formales del procedimiento o función de TURBO PASCAL, los parámetros se definen en forma de parámetros de valor y el tipo es registro, matriz , o cadena, punteros y otros tipos distintos de los tipos compuestos, como tipo de byte (BYTE), tipo de entero corto (SHORTINT), tipo de entero (INTEGER), tipo de fuente (WORD), tipo de entero largo (LONGINT), tipo de carácter ( CHAR), tipo booleano (BOOLEAN), tipo de número real (REAL), etc. Cuando TURBO PASCAL llama a una subrutina, inserta directamente los valores de los parámetros reales en la pila de izquierda a derecha. La subrutina de ensamblaje puede obtener directamente el valor real. valores de parámetros de la pila. (2) Método de transmisión de dirección En la lista de parámetros formales del procedimiento o función de TURBO PASCAL, los parámetros se definen en forma de variables y en forma de registros, cadenas y matrices. , punteros Para parámetros de valor definidos por tipos compuestos, cuando TURBO PASCAL llama a una subrutina, envía las direcciones de parámetros reales del programa que llama a la pila en orden de izquierda a derecha. La subrutina de ensamblaje obtiene la dirección del parámetro real de la pila para obtener el valor del parámetro. De manera similar, la subrutina de ensamblaje puede almacenar los resultados de la operación en las variables correspondientes para transmitirlos al programa que llama. Tabla 1-1. Métodos para insertar varios tipos de parámetros en la pila 殌───────┬────┬─────┐< / p> │Tipo de parámetro formal│Método de transferencia│Número de bytes en la pila│ ├───────┼────┼─────┤ │char,boolean │ │ │ │byte,shortint,│ valor│ 2 │ │entero,palabra │ │ │ ├ ───────┼────┼─────┤ │longint,single│ Valor de paso│ 4 │ ├────── ─┼─────┼─────┤ │valor │real│ 6 │ ├───────┼────┼─ ────┤ │doble │ valor│ 8 │ ├───────┼────┼─────┤ │cadena,puntero│ Pasar dirección│ 4 │ │Variable│ │ │ └───────┴────┴─── ─ ─┘殣 §1.2.1.3 Transferencia del valor de retorno de la función El método de transferencia del valor de retorno de la función TURBO PASCAL varía según el tipo de valor de retorno de la función. Algunos usan la dirección. se lleva a cabo de diferentes maneras y también se lleva a cabo en modo de registro. Por ejemplo, si se pasa la dirección, primero se inserta la dirección (4 bytes) en la pila, luego se ingresan los parámetros de la función y, finalmente, la dirección. Se introduce la dirección de retorno de la función. Los métodos de transferencia de varios tipos de devolución de funciones se muestran en la Tabla 1-2. Tabla 1-2. Métodos de transferencia de varios tipos de retorno de funciones 殌┌───────┬──────────┬── ─. ───┐ │ Tipo de retorno de función│ Método de retorno│ Número de bytes ocupados│ ├───────┼──────── ── ┼──────┤ │boolean,byte, │ en el registro AL│ 1 │ │char,shortint │ │ │ ├─ ───────┼──────────┼──────┤ │palabra,entero │ en registro AX│ 2 │ ├───────┼───────────┼──────┤ │longint │ La posición alta está en DX, la posición baja es en AX │ 4 │ ├───────┼───────────┼──────┤ │real │ De mayor a menor DX, BX, AX en │ 6 │ ├────────┼──────────┼───────┤ │puntero │La dirección del segmento está en DX, el desplazamiento está en AX │ 4 │ ├───────┼────────── ─┼────────┤ │string │ En la dirección señalada por DS:SI│ Sin límite│ └───────┴ ────────────┴── ────┘ 殣 §1.2.2 Formato de escritura de subrutina de ensamblaje Según el protocolo de llamada de TURBO PASCAL, el propósito general de la subrutina de ensamblaje externo. El formato de escritura es el siguiente: TÍTULO nombre del programa DOSSEG LOCALS @@ .MODEL TPASCAL CODE ASUME CS:@CODE nombre de función o proceso PÚBLICO Nombre del proceso o función: PUSH BP MOV BP, SP … POP BP El número de bytes de pila ocupados por el parámetro RETF END La subrutina de ensamblaje anterior está en formato TURBO ASSEMBLER y todas las subrutinas de ensamblaje de este artículo adoptan este formato. El formato de esta subrutina de ensamblaje se explica a continuación: . El módulo de ensamblaje debe adoptar el modo TPASCAL . En el módulo de ensamblaje, el proceso o función llamado por TURBO PASCAL; descrito como el atributo PUBLIC; La instrucción de retorno de subrutina depende de la situación específica. RET se utiliza para llamadas cercanas y RETF para llamadas lejanas; . consulte la lista de parámetros formales de la subrutina. El número de bytes ocupados por todos los parámetros en la pila después de ser insertados en la pila cuando finalice el módulo de ensamblaje. §1.2.3 Formato de escritura del programa TURBO PASCAL En TURBO PASCAL, el formato para declarar subrutinas externas es el siguiente: procedimiento prc(a, b : entero; var c : real);externo; func(a, b : entero): real; Es decir, en el procedimiento habitual de TURBO PASCAL o declaración de función Agregue la palabra clave externa después. En el programa principal o unidad de programa que declara un procedimiento o función externa, use la directiva de compilación {$L} para cargar el módulo de objeto ensamblado. Cuando se utilizan procedimientos o funciones de ensamblaje externo en un programa TURBO PASCAL, el método es el mismo que el de los procedimientos y funciones generales de TURBO PASCAL. §1.2.4 Análisis de ejemplos típicos del uso de subrutinas de ensamblaje externas en el programa principal Cuando se usan subrutinas de ensamblaje externas directamente en el programa principal de TURBO PASCAL, el método de llamada cercana generalmente es Por lo tanto, la instrucción de retorno de la subrutina de ensamblaje es RET. Cuando se especifica específicamente el método de llamada remota, se utiliza la instrucción de retorno RETF. 1. El proceso de pasar parámetros sin parámetros programa prog1; {$L prog1.obj} procedimiento DisplayOk; externo; comienzo MostrarOk; fin. Título PROG1 LOCALS @@ DOSSEG .MODEL TPASCAL .CODE ASUME CS:@CODE OkMsg db 'OK!', 0dh, 0ah,'$' ; Procedimiento DisplayOk PUBLIC DisplayOk DisplayOk: push ds ;Guardar segmento de datos p> push cs ;Insertar segmento de código en la pila pop ds ;Segmento de datos emergente mov ah,09 ;Mostrar cadena mov dx, offset OkMsg ;Dirección de cadena int 21h ;Llamada a función DOS pop ds ;Restaurar segmento de datos ret ;Cerca de retorno fin ; Fin del submódulo de ensamblaje 2. El proceso de pasar parámetros de valores de caracteres programa prog2; {$L prog2.obj} procedimiento DisplayInt(ch : char);externo; comenzar DisplayInt('a'); fin. Título PROG2 LOCALS @@ DOSSEG .MODEL TPASCAL .CODE ASSUME CS:@ CÓDIGO ; Procedimiento DisplayInt PUBLIC DisplayInt DisplayInt: push bp mov bp,sp< / p> mov ah,02 ;Mostrar caracteres mov dl,[bp+4] ;Obtener parámetros de la pila int 21h ;Llamada a función DOS pop bp ret 2; Los parámetros formales ocupan 2 bytes en la pila end 3. Pasar parámetros de valores de caracteres y variables enteras Procedimiento de parámetros<. /p> programa prog3; {$L prog3.obj} procedimiento ProcArg(ch : char;var i : entero);externo; var i: entero; comenzar ProcArg('d',i); writeln(i); end. Título PROG3 LOCALS @@ DOSSEG .MODEL TPASCAL .CODE p> ASUME CS:@CODE ; Procedimiento ProcArg PUBLIC ProcArg ProcArg: push bp mov bp,sp xor ax,ax mov al,byte ptr [bp+8] ; tomar parámetros de caracteres les si, [pb+4] ; Toma la variable entera Dirección mov es:[si],al pop bp ret 6; los parámetros formales ocupan 6 bytes en la pila end 4. Función que pasa parámetros de valor de carácter y devuelve tipo entero programa prog4; {$L prog4.obj} func func(ch: char): entero; externo; comenzar writeln(func('a')); fin. Título PROG4 LOCALS @@ DOSSEG .MODEL TPASCAL .CODE ASSUME CS:@CODE ; Función de procedimiento Función PÚBLICA func: push bp mov bp,sp xor ax,ax mov al,byte ptr [bp+4] ;Obtener valor del parámetro de carácter pop bp ret 2 ;Los parámetros formales ocupan 2 bytes en la pila end ;El valor de retorno de la subrutina está en el registro AX Pase los parámetros de valor de cadena y devuelva la función de cadena de. tipo programa prog5; {$L prog5.obj} función func(s: cadena): cadena externa; comenzar escribir( func('abcd') ); end. Título PROG5 LOCALS @@ DOSSEG .MODEL TPASCAL .CODE ASSUME CS:@CODE Función de procedimiento p> Función PÚBLICA función: empujar bp mov bp,sp empujar ds xor ch,ch lds si,[bp+4] ;Obtener la dirección de la cadena S les di,[bp+8] ;Obtener la dirección del valor de retorno mov cl,[si] inc cl cld @@1: lodsb p > stosb loop @@1 pop ds pop bp ret 4 ;La dirección de la cadena S es La pila ocupa 4 bytes end 6. Pasa los parámetros de valor entero largo y devuelve la función de entero largo programa prog6; {$L prog6.obj} función func(li: LongInt): Longint; externo; var i: longint; comenzar i := func(111111110); writeln(i); end. Título PROG6 LOCALS @ @ DOSSEG .MODEL TPASCAL .CODE ASSUME CS:@CODE Función de procedimiento; Función PÚBLICA > func: push bp mov bp,sp mov ax,[bp+4] ; toma el bit alto del entero largo< / p> mov dx,[bp+6] ;Obtener el bit bajo de un entero largo les si,[bp+8] ;Obtener la dirección de retorno de la función mov es: [si],dx mov es:[si+2],ax pop bp ret 4; la pila 4 bytes end 7. Funciones que pasan parámetros numéricos reales y devuelven números reales programa prog7; { $ L prog7.obj} función func(r: real): real; externo; var r: real; comenzar r := func(11111.1110); writeln(r); end. Título PROG7 LOCALS @@ DOSSEG .MODEL TPASCAL .CODE ASSUME CS:@CODE Función de procedimiento ; p> Función PÚBLICA función: empujar bp mov bp,sp mov ax,[bp+ 4] ;Tomar el valor del número real R mov bx,[bp+6] ; mov dx,[bp+8] ; les si, [bp+0ah] ;Obtener la dirección de retorno de la función mov es:[si],dx mov es:[si+2],bx mov es:[si+4],ax pop bp ret 6 ;El número real R ocupa 6 bytes en la pila end -------------------------------------------- ----