user4755019
user4755019

Reputation:

Inline assembler syntax error

I was getting some strange error when I was developing my operating system. I was making an IO driver using outb and inb. My outb function is as follows:

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

I get this error in Visual Studio:

C2400: inline assembler syntax error in 'opcode'; found '('

Does anyone know why I'm getting this error? How do I fix this error? Any suggestions?

Upvotes: 3

Views: 5324

Answers (1)

Michael Petch
Michael Petch

Reputation: 47593

Visual Studio's VC++ doesn't support GNU assembler templates available in GCC. Since you define port as a 16-bit unsigned integer you need to use the the form of OUT that takes a 16-bit port number. You need to place the 16-bit port number in DX. You also have to treat the variable names in the inline assembly as pointers since you are using standard CDECL calling convention for your functions. Sample code:

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

The function inb could be done with something like:

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

This could be simplified by removing the variable data, and storing the character read into the variable port and then doing return (uint8_t)port;. So this would also work:

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;
}

More on using VC++ inline assembly can be found in the Microsoft Developer Network(MSDN) documentation

Upvotes: 2

Related Questions