2009-09-06 7 views
5

Mam do czynienia z Nasm na środowisku Linux przez jakiś czas i ta funkcja działała świetnie ... ale teraz przełączam się do środowiska Windows i chcę użyć Masm (z VS2008) Nie mogę wydają się uzyskać to do pracy ...Konwersja problemu: __asm__ __volatile__

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

Kiedy piszę coś takiego ...

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

ASM ma bardziej rozpoznawana i lotny zgłasza błąd mówiąc „ciąg”, ja też próbowałem pisząc _azmilnym ale dostaję błąd mówiąc "błąd składni asemblera inline w 'opcode'; znaleziono 'dane typ "«

Odpowiedz

8

Zakładając mówisz x86 zestaw poleceń, oto kilka rzeczy do zapamiętania:

  1. procedur¹ «OUTB» wyjść jeden bajt, który byłby odpowiednikiem typu «char» lub» unsigned char "w C/C++. Aby wyprowadzić 16-bitowe (ponieważ używasz "unsigned short") słowo należy użyć "outw"
  2. powiedziawszy, że jest zalecane przez Intel (i wymagane przez VS), że używasz instrukcji mnemonik " out ", a wielkość portu jest rozpoznawana na podstawie wielkości operandu. Na przykład „out dx, ax” byłoby odpowiednikiem dla „outw”, podczas gdy „out dx, al” jest równoznaczne z „OUTB”
  3. na x86 „out” instrukcja wymaga portu i wartość wyprowadzanie do umieszczenia odpowiednio w rejestrach (e) dx i {eax/ax/al}. Podczas gdy Nasm może zrobić to za ciebie (nie mam kompilatora pod ręką, więc nie mogę tego potwierdzić), w VS musisz to zrobić tak, jak to się robi na poziomie procesora.
  4. nie ma powodu, aby określać słowo kluczowe "volatile" za pomocą __asm. Wszelkie instrukcje montażu inline powodować VS kompilatora, aby wyłączyć buforowanie odczytu (co jest kluczowe dla lotny)

Oto kod (zakładając, że piszesz do portu 16-bitowy):

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

w przypadku piszemy do portu 8-bitowego, kod powinien wyglądać tak:

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

Również: możesz użyć __asm ​​{instrukcje tutaj} dla jaśniejszej składni, a może warto wspomnieć, że wbudowany asm nie będzie działa na x64, więc dla tej architektury będzie musiał napisać asm cod e w samodzielnym kodzie. –

+0

Ok teraz ma sens trochę, najmniej nie dostaję błędów .. więc co jest równoważne inportb? Wiem, że piszesz "w" zamiast "na zewnątrz" i prawdopodobnie zmieniasz siekierę na prawą? Czy może jest to bardziej skomplikowane? – Fredrick

+0

Spróbuj, to nie powinno boleć. Pamiętaj, że VS używa polecenia {operation} {destination}, {source}, więc dla odczytania portu będzie to: __asm ​​w al, dx; , a następnie musisz zapisać wynik w swojej zmiennej: __asm ​​mov data, al; i zwróć go z funkcji: dane zwracane; – Rom