Reputation:
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
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