En esta práctica se va a ver la forma de introducir rutinas en ensamblador dentro de un programa C. Para ello se incluye una pequeña introducción teorica, que corresponde al capítulo XIII del libro "El Universo Digital del IBM PC, AT y PS/2", disponible en Internet, en la dirección http://www.gui.uva.es/udigital
Para una mejor comprensión se entrega también un ejemplo de un programa en C con parte en ensamblador. Se han utilizado dos métodos diferentes para incluir dicho ensamblador.
El código en C es el siguiente:
/*************************************************************************/
/*
UNIVERSIDAD AUTONOMA DE MADRID
*/
/*
E. T. S. de Ingeniería Informática
*/
/*
Laboratorio de E. T. C. II
*/
/*
Enero 1999
*/
/*
*/
/* Ejemplo sencillo de uso de ensamblador desde un
programa en C.
*/
/*
*/
/* En el ejemplo se ven dos formas de usarlo:
*/
/* - Como código insertado.
*/
/* - Como llamadas a librerias generadas desde el
ensamblador.
*/
/*
*/
/*************************************************************************/
#include <CONIO.H>
#include <STDIO.H>
#include <DOS.H>
int valor_retorno;
/* Variable de retorno de la función en ensamblador */
extern atributo();
/* Función en ensamblador. Modifica el color del borde de la pantalla,
según un parámetro */
extern cursor();
/* Función en ensamblador. Posiciona el cursor en la fila,columna
indicada. 2 parámetros */
/***************************************************************************
Procedimiento que borra la pantalla. El cuerpo está definido
en ensamblador. Comienza por la directiva asm y está comprendido
entre llaves. Admite parámetros con el formato general de C. ****************************************************************************/
void borrar_pantalla (int esq_sup_izda, int esq_inf_dcha, char atrib)
{
asm{
mov cx,esq_sup_izda
/* Esquina superior izquierda */
mov dx,esq_inf_dcha
/* Esquina inferior derecha
*/
mov bh,atrib
/* Atributo de pantalla
*/
mov ax,0600h
/* Valor de la interrupcion BIOS */
int 10h
/* Llamada a la interrupcion
*/
}
}
void main()
{
int i, fila, columna;
borrar_pantalla(0,0x184F,0x07);
cursor (0,0);
printf ("Introducir fila y columna a presentar el texto:\n");
printf (" Fila: ");
scanf ("%d", &fila);
printf (" Columna: ");
scanf ("%d", &columna);
cursor (fila,columna);
printf ("Prueba de color del borde.\n");
for (i=0; i<16; i++) {
valor_retorno = atributo (i);
/* retorna el valor del registro AX */
delay (500);
}
atributo (0);
}
Código fuente del fichero en C: pinchar aquí
Y el código en ensamblador es:
; DEFINICION DEL SEGMENTO DE DATOS
_DATOS SEGMENT WORD PUBLIC 'DATA'
FILA DB 0
COL DB 0
_DATOS ENDS
;_______________________________________________________________
; DEFINICION DEL SEGMENTO DE CODIGO
_CODIGO SEGMENT BYTE PUBLIC 'CODE'
ASSUME CS:_CODIGO,DS:_DATOS,SS:_DATOS
PUBLIC _atributo ; funcion
accesible desde el programa C PUBLIC _cursor
_atributo PROC NEAR
PUSH BP
MOV BP,SP
MOV CX,[BP+4] ; recupera la variable
MOV AH,0BH
; petición
MOV BH,00
; selecciona color de fondo
MOV BL,CL
INT 10H
MOV AX,0
MOV SP,BP
POP BP
RET
_atributo ENDP
_cursor PROC NEAR
PUSH BP
MOV BP,SP
MOV BX,[BP+4] ; recupera la primera
variable
MOV CX,[BP+6] ; recupera la segunda
variable
MOV FILA,BL
MOV COL, CL
MOV AH,02H
; petición
MOV BH,00
; numero de pagina 0
MOV DH,FILA
MOV DL,COL
INT 10H
MOV AX,0
MOV SP,BP
POP BP
RET
_cursor ENDP
_CODIGO ENDS
END
Código fuente del fichero en ensamblador: pinchar
aquí
Para poder compilar el programa total se deberá crear un proyecto en C, incluyendo los dos ficheros anteriores.
Nota: dentro de la ventana de proyecto seleccionar el fichero *.asm,
y dentro del menú "Project", seleccionar "Local Options". En el
menú "Project File Translators" seleccionar "~Turbo Assembler".
Esto hará que el fichero *.asm sea compilado con el Turbo Ensamblador.
Utilizar el tamaño de memoria "medium" o mayor.
Compilarlo y ejecutarlo. Ver lo que hace. Ejecutarlo paso a paso, tanto
la parte en C como la parte en ensamblador.