Проблема конвертации:__asm__ __летучие__
-
21-09-2019 - |
Вопрос
Я некоторое время имел дело с Nasm в среде Linux, и эта функция работала отлично...но теперь я перехожу в среду Windows и хочу использовать Masm (с VS2008). Кажется, я не могу заставить это работать...
void outportb (unsigned short _port, unsigned short _data)
{
__asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
}
Когда я пишу что-то подобное...
void outportb (unsigned short _port, unsigned short _data)
{
asm volatile ("outb %1, %0" : : "dN" (_port), "a" (_data));
}
asm больше не распознается, и Летучий выдает ошибку с надписью «строка». Я также пытался написать _asm flaming, но получаю ошибку с надписью «синтаксическая ошибка встроенного ассемблера в «коде операции»;найден «тип данных»»
Решение
Предполагая, что вы говорите о наборе команд x86, следует запомнить несколько вещей:
- инструкция «outb» выводит один байт, что эквивалентно типу «char» или «unsigned char» в C/C++.Для вывода 16-битного слова (поскольку вы используете «короткое без знака») необходимо использовать «outw».
- при этом Intel рекомендует (и требует VS) использовать мнемонику инструкции «out», а размер порта распознается по размеру операнда.Например, «выход dx, топор" будет эквивалентно "outw", а "out dx, аль" эквивалентно "outb"
- на x86 инструкция «out» требует, чтобы порт и выходное значение были помещены в регистры (e)dx и {eax/ax/al} соответственно.Хотя Nasm может сделать это за вас (у меня нет под рукой компилятора, поэтому я не могу это подтвердить), в VS вам придется делать это так, как это делается на уровне процессора.
- нет причин указывать «летучее» ключевое слово с помощью __asm.Любые встроенные ассемблерные инструкции заставляют компилятор VS отключать кэширование чтения (для чего предназначено ключевое слово voluty)
Вот код (при условии, что вы пишете в 16-битный порт):
void outportw(unsigned short port, unsigned short data)
{
__asm mov ax, data;
__asm mov dx, port;
__asm out dx, ax;
}
если вы пишете в 8-битный порт, код должен выглядеть так:
void outportb(unsigned short port, unsigned char data)
{
__asm mov al, data;
__asm mov dx, port;
__asm out dx, al;
}
Не связан с StackOverflow