2009-09-06 8 views
5

Ich habe mit Nasm auf einer Linux-Umgebung für einige Zeit und diese Funktion funktionierte toll ... aber jetzt bin ich Wechsel zu einer Windows-Umgebung und ich möchte Masm verwenden (mit VS2008) kann ich nicht scheinen zu bekommen dies funktioniert ...Konvertierungsproblem: __asm__ __volatile__

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

Wenn ich so etwas schreiben ...

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

asm ist nicht mehr erkannt und volatilen einen Fehler wirft „string“ zu sagen, habe ich auch versucht, Ich schreibe _asm volatile, aber ich bekomme einen Fehler, der sagt "Inline Assembler Syntax Fehler in 'Opcode'; gefunden 'Daten Typ ' ‚

Antwort

8

Sie sprechen x86-Befehlssatz Unter der Annahme, hier sind einige Dinge zu erinnern:

  1. die Anweisung‚outb‘gibt ein Byte, das wäre gleichbedeutend zu geben‚char‘oder‘ unsigned char "in C/C++. Für die Ausgabe eines 16-Bit-Wortes (da Sie "unsigned short" verwenden) muss man "outw"
  2. verwenden, wobei es von Intel empfohlen wird (und von VS verlangt wird), dass Sie den Befehl mnemonic verwenden " out "und die Portgröße wird anhand der Operandengröße erkannt. Zum Beispiel "out dx, ax" würde für "OUTW" äquivalent sein, während "out dx, al" ist äquivalent zu "OUTB"
  3. auf x86 erfordert die "out" Anweisung, den Port und den Ausgabewert in (e) dx- bzw. {eax/ax/al} -Register einzutragen. Während Nasm es für dich tun könnte (ich habe den Compiler nicht zur Hand, also kann ich das nicht bestätigen), musst du es in VS so machen, wie es auf der CPU-Ebene gemacht wird.
  4. gibt es keinen Grund, "flüchtige" Schlüsselwort mit __asm ​​anzugeben. Jegliche Inline-Assembler-Befehle verursachen VS Compiler Lese-Caching zu deaktivieren (was volatile Schlüsselwort ist für)

Hier ist der Code (vorausgesetzt, Sie schreiben in 16-Bit-Port):

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

bei Sie schreiben in 8-Bit-Port, sollte der Code so aussehen:

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

auch: Sie {Anweisungen hier} für klarere Syntax __asm ​​könnte, und es könnte, dass Inline-asm erwähnenswert, werden nicht arbeiten auf x64, so für diese Architektur muss asm cod schreiben e im eigenständigen Code. –

+0

Ok jetzt macht es ein bisschen Sinn, am wenigsten bekomme ich keine Fehler .. also was entspricht inportb? Ich weiß, du schreibst "in" anstatt "out" und änderst wahrscheinlich die Axt, oder? Oder ist es komplizierter? – Fredrick

+0

Probieren Sie es aus, es sollte nicht weh tun. Denken Sie daran, dass VS {operation} {destination}, {source} order verwendet, also wäre zum Lesen des Ports: __asm ​​in al, dx; und dann müssen Sie das Ergebnis in Ihrer Variablen speichern: __asm ​​mov data, al; und es von der Funktion zurückgeben: Rückgabedaten; – Rom

Verwandte Themen