2011-12-23 9 views
8

me gustaría puerto outb función de C a D.ayuda en la conversión: __asm__ __volatile__

static __inline void outb (unsigned char value, unsigned short int port) 
{ 
    __asm__ __volatile__ ("outb %b0,%w1" 
          : 
          : 
         "a" (value), 
          "Nd" (port)); 
} 

Esta es la versión D.

extern(C) 
{ 
    void outb (ubyte value, ushort port) 
    { 
     // I couldn't figure out this part 
    } 

} 

Estos son algunos enlaces sobre el tema.

D Inline Assembler

http://dlang.org/iasm.html

GCC-Inline-Asamblea-COMO

http://ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html

Pero no sé lenguaje ensamblador, así que necesito un poco de ayuda. Cualquier ayuda sería apreciada. Gracias.

Respuesta

8

La instrucción outb solo debe llamarse como outb %al, %dx donde %al es el valor y %dx es el puerto.

D utiliza la sintaxis Intel para x86, a diferencia del ensamblador GNU que utiliza la sintaxis T de AT & de forma predeterminada. La sintaxis de Intel correspondiente sería out dx, al, y el código correspondiente en D se vería así:

void outb (ubyte value, ushort port) 
{ 
    asm { 
     mov AL, value; 
     mov DX, port; 
     out DX, AL; 
    } 
} 

Tenga en cuenta que no es necesario escribir el montaje en absoluto, porque druntime tiene la función core.bitop.outp que realizan la misma instrucción.

void outb (ubyte value, ushort port) 
{ 
    import core.bitop; 
    outp(port, value); 
} 
4

La primera cosa que es probable que el disparo hasta que la lista es el apoyo del compilador D de códigos de operación no incluye outb, según lo especificado por la función C que ya ha proporcionado. Después de algunas excavaciones, descubrí que outb es un nombre más específico para el código de operación general out. outb indica que el primer argumento del código de operación estará en un registro de bytes (en oposición a outw y outl, que indican un primer tamaño de argumento de, respectivamente, una palabra y una palabra doble), sin embargo, el compilador D usa el código de operación out para todas las operaciones, y determina qué código de operación específico escribir en función del tamaño del argumento que especifique.

Con eso fuera del camino, lo siguiente que hay que hacer es convertir la sintaxis GCC en sintaxis D. De acuerdo con el CCG-inline-Asamblea-COMO, el código que ya ha proporcionado utiliza la sintaxis de montaje extendido:

asm (assembler template 
    : output operands     /* optional */ 
    : input operands     /* optional */ 
    : list of clobbered registers  /* optional */ 
    ); 

En cuanto a su plantilla, la función especifica una instrucción de montaje (outb) con dos argumentos, el primero es una byte (%b0) y el segundo es una palabra o entero corto (%w0).

El truco sobre la lista de argumentos de entrada es la cadena que prefija cada uno de los parámetros de su función. Estos, según el CÓMO, se llaman restricciones. Básicamente, son reglas que GCC debe seguir al usar los parámetros como argumentos para las instrucciones de ensamblaje proporcionadas.La restricción "a" aplicada al parámetro value indica que el contenido de la variable debe colocarse en el registro eax, ax o al según el tamaño de la variable. La restricción en la variable port, "Nd", indica primero que el valor está en el rango de 0-255, y segundo, que el valor debe colocarse ya sea en el registro edx, dx o dl, de nuevo, según el tamaño del variable.

El compilador D no ofrece tanta ayuda con variables en bloques de ensamblaje como lo hace GCC; en el ensamblador en línea de D's, deberá mover los valores de los parámetros específicamente en los registros correspondientes. Para outb, estos registros son dx y al. Siguiente sintaxis de ensamblador en línea D's, puede mover las variables y llamar al código de operación out de la siguiente manera:

asm 
{ 
    MOV AL, value; 
    MOV DX, port; 
    OUT DX, AL; 
} 

Tenga en cuenta que, debido a GCC utiliza la sintaxis de ensamblador AT & T y D utiliza la sintaxis de ensamblador Intel, el orden de los argumentos proporcionados a OUT se invierten.