2009-09-06 11 views
5

He estado lidiando con Nasm en un entorno Linux durante algún tiempo y esta función funcionó muy bien ... pero ahora estoy cambiando a un entorno de Windows y quiero usar Masm (con VS2008) No puedo parecen conseguir que esto funcione ...Problema de conversión: __asm__ __volatile__

void outportb (unsigned short _port, unsigned short _data) 
{ 
    __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data)); 
} 

Cuando escribo algo como esto ...

void outportb (unsigned short _port, unsigned short _data) 
{ 
    asm volatile ("outb %1, %0" : : "dN" (_port), "a" (_data)); 
} 

asm no es más reconocido y volátil lanza un error que dice "cadena", también probé Escribir _asm volátil pero me sale un error que dice "error de sintaxis del ensamblador en línea en 'opcode'; found 'data Tipo ' '

Respuesta

8

Suponiendo que estamos hablando de conjunto de comandos x86, aquí hay algunas cosas para recordar:

  1. la instrucción '' salidas de un byte, lo que equivaldría a escribir 'outb char' o' char sin signo "en C/C++. Para emitir un mensaje de 16 bits (ya que está utilizando el término "unsigned short") se debe usar "outw"
  2. habiendo dicho eso, Intel recomienda (y requiere VS) que use la instrucción mnemónica ". out "y el tamaño del puerto se reconoce desde el tamaño del operando. Por ejemplo "fuera dx, hacha" sería equivalente para "outw", mientras que "dx a cabo, al" es equivalente a "outb"
  3. en x86 "fuera" instrucción requiere el puerto y el valor de hacer salir para ser colocado en registros (e) dx y {eax/ax/al} respectivamente. Si bien Nasm podría hacerlo por usted (no tengo el compilador a mano, entonces no puedo confirmarlo), en VS tiene que hacerlo de la manera en que se hace en el nivel de la CPU.
  4. no hay ninguna razón para especificar palabra clave "volátil" con __asm. Cualquier instrucción de ensamblador en línea causan VS compilador para deshabilitar el caché de lectura (lo que la palabra clave es volátil para)

Aquí está el código (suponiendo que se está escribiendo en el puerto de 16 bits):

void outportw(unsigned short port, unsigned short data) 
{ 
    __asm mov ax, data; 
    __asm mov dx, port; 
    __asm out dx, ax; 
} 

en el caso usted está escribiendo en el puerto de 8 bits, el código debe ser similar a lo siguiente:

void outportb(unsigned short port, unsigned char data) 
{ 
    __asm mov al, data; 
    __asm mov dx, port; 
    __asm out dx, al; 
} 
+1

también: usted podría utilizar __asm ​​{instrucciones aquí} para la sintaxis más clara, y que valdría la pena mencionar, que asm en línea no lo hará trabajar en x64, por lo que para esta arquitectura tendrá que escribir asm cod e en código independiente. –

+0

Ok, ahora tiene sentido un poco, al menos no tengo errores ... entonces ¿qué es equivalente a inportb? Sé que escribes "in" en lugar de "out" y probablemente cambies a ax a la verdad? ¿O es más complicado que eso? – Fredrick

+0

Pruébalo, no debería doler. Recuerde que VS usa {operation} {destination}, {source} orden, por lo que para leer el puerto sería: __asm ​​in al, dx; y luego necesita almacenar el resultado en su variable: __asm ​​mov data, al; y lo devuelve desde la función: datos de devolución; – Rom

Cuestiones relacionadas