Práctica 3. Interfaz con el lenguaje C



Objetivos

La práctica consiste en la realización de dos tareas:

La práctica se valorará en función de la interacción entre el lenguaje C y el ensamblador, más que por un gran desarrollo en C.

No se permite el uso de código ensamblador insertado en funciones de C.

Es obligatorio el uso de paso de parámetros entre C y ensamblador.

Se recomienda dejar la implementación del formato .s19 para el final, una vez que ya esté todo funcionando para el formato binario.


Qué hay que hacer:

1.    Escribir en ensamblador un programa aparte o una librería de conexión entre la parte C y el driver. Este programa aparte o librería deberá incluir una llamada a cada función correspondiente a  cada servicio del driver (cada AH distinto).
2.    Escribir la interfaz en C (descrita en el inicio de este documento).
3.    "Linkar" el programa en C y la librería en ASM en un programa.
4.    Hacer un makefile que compile y haga el "linkado".


Ejemplo completo de programación mixta (ASM+C) paso a paso:

En muchas ocasiones se necesita el calculo a*b/c con números enteros. El problema consiste en el posible desbordamiento del a*b incluso si el resultado a*b/c cabe en un int. Por tanto, dicho calculo hay que hacerlo en ensamblador o con tipo long, que es mas costoso. Se necesita hacer una función en ensamblador, que calcula a*b/c.

1. Elegimos el prototipo de la función:
int mul_div(int a,int b,int c);
Escribimos dicho prototipo en el fichero mul_div.h
2. Necesitamos el esqueleto de esta función en ASM:
Escribimos en un fichero llamado mul_div.c:

int mul_div(int a, int b, int c) {
    return a+b-c; // notar la diferencia en el func. Es un stub
}
compilamos, generando ASM

tcc -S mul_div.c
3. Escribimos el programa en ensamblador, utilizando el esqueleto generado por tcc en el paso previo:
edit mul_div.asm

En el cuerpo del programa cambiamos las instrucciones necesarias:

mul_div proc near
    push bp
    mov bp,sp
    ...    
    mov ...,[bp+4] ; el a
    add ...,[bp+6] ; el b
    sub ...,[bp+8] ; el c
    ...
    pop bp
    ret
mul_div endp
...
cambiamos a:

mul_div proc near
    push bp
    mov bp,sp
    mov ax,[bp+4] ; el a
    cwd
    imul [bp+6] ; el b
    idiv [bp+8] ; el c
    pop bp
    ret
mul_div endp
4. Compilamos el modulo ASM con opciones 'case sensitive'
   4.1. Encontramos la opción:
   tasm
   4.2. Compilamos (los ... es la opción):
   tasm -m... mul_div.asm
5. Escribimos un programa en C (muldiv.c) que comprueba la función:
#include <stdio.h>
#include "mul_div.h"

int main() {
    for(;scanf("%d%d%d",&a,&b,&c)==3;) {
        printf("%d %d\n",mul_div(a,b,c),a*b/c);      
    }
    return 0;
}
5. Compilamos:
tcc muldiv.c

(mensaje de error por falta de la función mul_div)

tcc muldiv.c mul_div.obj

6. Comprobamos.

A>muldiv.exe

Comprobar con las entradas 2 3 2 y 512 512 10.
7. Hacer makefile:
Hemos ejecutado los comandos

 tasm /mx mul_div

con entrada mul_div.asm y salida mul_div.obj y

 tcc muldic.c mul_div.obj

con entrada muldiv.c, mul_div.obj y salida muldiv.exe.
muldiv.c contiene el ‘include’ de mul_div.h. Por tanto el makefile seria:
----------------------------------------------------------
muldiv.exe: muldiv.c mul_div.obj mul_div.h
        tcc muldiv.c mul_div.obj

mul_div.obj: mul_div.asm
         tasm /mx mul_div

----------------------------------------------------------

escribimos el makefile (edit makefile) y comprobamos:

del *.obj
make -f makefile
9. Ejercicios:

1.    Quitar todo lo no necesario en el fichero mul_div.asm.
2.    Hacer el link separado de la compilación en el ejemplo.
3.    Comprobar el programa con entrada 512 512 5 .
4.    Hacer el programa mul_div con tipo unsigned. Comprobar 512 512 5.
5.    Hacer mul_div en modelo de memoria large.


Notas de ayuda:     El Universo Digital del PC: El ensamblador y el lenguaje C. Capítulo 13  de un buen libro digital



Plazo de entrega : La presentación y evaluación de esta práctica será según consta en el calendario. El nombre de cada fichero deberá seguir las normas aplicadas para la práctica 2, enviando un único fichero comprimido tipo zip.