Ошибка синтаксиса встроенного ассемблера

Я получал какую-то странную ошибку при разработке своей операционной системы. Я делал драйвер ввода-вывода, используя outb а также inb, мой outb Функция выглядит следующим образом:

static inline void outb(uint16_t port, uint8_t val)
{
    __asm("outb %0, %w1"  //<--Error
        :
        : "a"(val), "Nd"(port));
}

Я получаю эту ошибку в Visual Studio:

C2400: ошибка синтаксиса встроенного ассемблера в 'код операции'; найденный '('

Кто-нибудь знает, почему я получаю эту ошибку? Как я могу исправить эту ошибку? Какие-либо предложения?

1 ответ

Решение

Visual Studio VC++ не поддерживает шаблоны ассемблера GNU, доступные в GCC. Поскольку вы определяете port в качестве 16-разрядного целого числа без знака необходимо использовать форму OUT, которая принимает 16-разрядный номер порта. Вам нужно разместить 16-битный номер порта в DX. Вы также должны обрабатывать имена переменных во встроенной сборке как указатели, поскольку вы используете стандартное соглашение о вызовахCDECL для своих функций. Образец кода:

static inline void outb(uint16_t port, uint8_t val) {
    __asm
    {
        mov dx, port
        mov al, val
        out dx, al
    } 
}

Функцияinbможет быть сделано с чем-то вроде:

static inline uint8_t inb(uint16_t port)
{
    uint8_t data;
    __asm
    {
        mov dx, port
        in al, dx
        mov data, al
    }
    return data;
}

Это можно упростить, удалив переменную dataи сохранение символа, прочитанного в переменнуюportа затем делатьreturn (uint8_t)port;, Так что это также будет работать:

static inline uint8_t inb(uint16_t port)
{
    __asm
    {
        mov dx, port
        in al, dx
        mov byte ptr[port], al   // Need to cast since port is 16-bit variable
    }
    return (uint8_t)port;
}

Подробнее об использовании встроенной сборки VC++ можно найти в документации Microsoft Developer Network(MSDN).

Другие вопросы по тегам