Problema de conversão: __asm__ __volatile__
-
21-09-2019 - |
Pergunta
Eu tenho lidado com o NASM em um ambiente Linux há algum tempo e essa função funcionou muito bem ... mas agora estou mudando para um ambiente do Windows e quero usar MASM (com VS2008), não consigo fazer isso funcionar. .
void outportb (unsigned short _port, unsigned short _data)
{
__asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
}
Quando escrevo algo assim ...
void outportb (unsigned short _port, unsigned short _data)
{
asm volatile ("outb %1, %0" : : "dN" (_port), "a" (_data));
}
O ASM não é mais reconhecido e o volátil lança um erro dizendo "string", também tentei escrever _asm volátil, mas recebo um erro dizendo "erro de sintaxe do assembler embutido em 'opcode'; encontrado 'tipo de dados'" "
Solução
Supondo que você esteja falando sobre o conjunto de comandos x86, aqui estão poucas coisas para lembrar:
- A instrução "outb" produz um byte, que seria equivalente a digitar "char" ou "char não assinado" em C/C ++. Para produzir uma palavra de 16 bits (já que você está usando "curta" não assinada "), é preciso usar" Outw "
- Dito isto, é recomendado pela Intel (e exigido pelo VS) que você use a instrução mnemônica "Out" e o tamanho da porta é reconhecido pelo tamanho do operando. Por exemplo "Out DX, machado"seria equivalente a" outw ", enquanto" fora dx, al"é equivalente a" outb "
- No x86, a instrução "Out" requer que a porta e o valor de saída sejam colocados nos registros (e) dx e {eax/ax/al}, respectivamente. Embora o NASM possa fazer isso por você (eu não tenho o compilador útil, então não posso confirmar isso), no VS, você precisa fazê -lo da maneira que é feita no nível da CPU.
- Não há razão para especificar uma palavra -chave "volátil" com __ASM. Quaisquer instruções de montagem em linha fazem com que o compilador desative o cache de leitura (para que palavra -chave volátil é para)
Aqui está o código (supondo que você esteja escrevendo em porta de 16 bits):
void outportw(unsigned short port, unsigned short data)
{
__asm mov ax, data;
__asm mov dx, port;
__asm out dx, ax;
}
Caso você esteja escrevendo na porta de 8 bits, o código deve ficar assim:
void outportb(unsigned short port, unsigned char data)
{
__asm mov al, data;
__asm mov dx, port;
__asm out dx, al;
}