Conversione problema: __asm__ __volatile__
-
21-09-2019 - |
Domanda
Ho avuto a che fare con Nasm su un ambiente Linux per un certo tempo e questa funzione funzionato grande ... ma ora sto passare a un ambiente Windows e voglio usare MASM (con VS2008) I cant sembrano ottenere questo a il lavoro ...
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 a scrivere _asm volatili ma ottengo un errore che dice "inline assembler errore di sintassi nella 'opcode'; trovato 'il tipo di dati'"
Soluzione
Supponendo che si sta parlando di comando set x86, qui ci sono alcune cose da ricordare:
- l'istruzione "outb" uscite un byte, che sarebbe equivalente al tipo "char" o "char senza segno" in C / C ++. Per l'emissione a 16 bit (dal momento che si sta utilizzando "unsigned short") parola si ha la necessità di utilizzare "OUTW"
- detto questo, si raccomanda da Intel (e richiesto da VS) che si utilizza il mnemonico istruzione "fuori" e la dimensione del porto è riconosciuto dalla dimensione operando. Per esempio "fuori dx, ax " sarebbe equivalente per "OUTW", mentre "dx fuori, al " equivale a "outb"
- sul x86 "out" istruzione richiede la porta e il valore outputting ad essere immessi in (e) dx e {eax / ax / al} registra rispettivamente. Mentre Nasm potrebbe farlo per voi (non ho il compilatore a portata di mano, quindi non posso confermare che), in VS bisogna farlo nel modo in cui viene fatto a livello di CPU.
- non c'è motivo di specificare parola chiave "volatile" con __asm. Le eventuali istruzioni di montaggio in linea causano VS compilatore per disabilitare la cache di lettura (ciò che è 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;
}