2009-09-06 13 views
5

Ho avuto a che fare con Nasm su un ambiente Linux per un po 'di tempo e questa funzione ha funzionato benissimo ... ma ora sto passando ad un ambiente Windows e voglio usare Masm (con VS2008) non posso sembrano ottenere questo al lavoro ...Conversione del problema: __asm__ __volatile__

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

Quando scrivo qualcosa di simile ...

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

ASM non è più riconosciuto e volatile genera un errore che dice "stringa", ho anche provato scrivendo _asm volatile ma ottengo un errore che dice "errore di sintassi assemblatore in linea in 'opcode'; dati trovati Tipo ' '

risposta

8

si Supponendo che stiamo parlando di comando set x86, qui ci sono alcune cose da ricordare:

  1. l'istruzione 'outb' uscite un byte, che sarebbe equivalente a digitare 'char' o' char non firmato "in C/C++. Per l'output di un 16 bit (dato che stai usando "unsigned short") la parola uno deve usare "outw"
  2. detto questo, è raccomandato da Intel (e richiesto da VS) che tu usi l'istruzione mnemonica " out "e la dimensione della porta viene riconosciuta dalla dimensione dell'operando. Ad esempio "fuori dx, ax" sarebbe equivalente a "outw", mentre "dx fuori, al" è equivalente a "outb"
  3. sul x86 "out" istruzione richiede la porta e il valore outputting da inserire rispettivamente nei registri (e) dx e {eax/ax/al}. Mentre Nasm potrebbe farlo per te (non ho il compilatore a portata di mano, quindi non posso confermarlo), in VS devi farlo come è fatto a livello di CPU.
  4. non vi è alcun motivo per specificare la parola chiave "volatile" con __asm. Le eventuali istruzioni di montaggio in linea causano VS compilatore per disabilitare la cache di lettura (che cosa parola chiave volatile è per)

Ecco il codice (supponendo che si sta scrivendo in porto a 16 bit):

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

nel caso in cui si sta scrivendo nella porta a 8 bit, il codice dovrebbe essere simile che:

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

Inoltre: è possibile utilizzare __asm ​​{istruzioni qui} per la sintassi più chiara, e potrebbe essere la pena ricordare, che in linea asm non lo farà lavoro su x64, quindi per questa architettura dovrò scrivere asm cod e in codice stand alone. –

+0

Ok ora ha senso un po ', meno sto ricevendo errori .. quindi cosa è equivalente a inportb? So che scrivi "in" anziché "out" e probabilmente cambi ascia a destra? O è più complicato di così? – Fredrick

+0

Provalo, non dovrebbe ferire. Ricorda che VS usa l'ordine {operation} {destination}, {source}, quindi per leggere la porta sarebbe: __asm ​​in al, dx; e quindi è necessario memorizzare il risultato nella variabile: __asm ​​mov dati, al; e restituirlo dalla funzione: dati di ritorno; – Rom