内联asm:'out'的操作数类型不匹配
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内联asm:'out'的操作数类型不匹配相关的知识,希望对你有一定的参考价值。
我不知道集会的深度。以下代码用于写入硬件端口。
编译器在使用内联asm的每一行中都给出操作数类型不匹配错误。当我编译时,我得到这些错误:
port.cpp: Assembler messages: port.cpp:27: Error: operand type mismatch for 'out' port.cpp:34: Error: operand type mismatch for 'in' port.cpp:51: Error: operand type mismatch for 'out' port.cpp:69: Error: operand type mismatch for 'out' port.cpp:75: Error: operand type mismatch for 'in' port.cpp:94: Error: operand type mismatch for 'out' port.cpp:100: Error: operand type mismatch for 'in'
port.h
#ifndef __PORT_H
#define __PORT_H
#include "types.h"
class Port
{
protected:
Port(uint16_t portnumber);
~Port();
uint16_t portnumber;
};
class Port8Bit : public Port
{
public:
Port8Bit(uint16_t portnumber);
~Port8Bit();
virtual uint8_t Read();
virtual void Write(uint8_t data);
};
class Port8BitSlow : public Port8Bit
{
public:
Port8BitSlow(uint16_t portnumber);
~Port8BitSlow();
virtual void Write(uint8_t data);
};
class Port16Bit : public Port
{
public:
Port16Bit(uint16_t portnumber);
~Port16Bit();
virtual uint16_t Read();
virtual void Write(uint16_t data);
};
class Port32Bit : public Port
{
public:
Port32Bit(uint16_t portnumber);
~Port32Bit();
virtual uint32_t Read();
virtual void Write(uint32_t data);
};
#endif
port.cpp
#include "port.h"
Port::Port(uint16_t portnumber)
{
this->portnumber = portnumber;
}
Port::~Port()
{
}
Port8Bit::Port8Bit(uint16_t portnumber)
: Port(portnumber)
{
}
Port8Bit::~Port8Bit()
{
}
void Port8Bit::Write(uint8_t data)
{
__asm__ volatile("outb %0, %1" :: "a" (data), "Nd" (portnumber));
}
uint8_t Port8Bit::Read()
{
uint8_t result;
__asm__ volatile("inb %1, %0" : "=a" (result) : "Nd" (portnumber));
return result;
}
Port8BitSlow::Port8BitSlow(uint16_t portnumber)
: Port8Bit(portnumber)
{
}
Port8BitSlow::~Port8BitSlow()
{
}
void Port8BitSlow::Write(uint8_t data)
{
__asm__ volatile("outb %0, %1
jmp 1f
1: jmp 1f
1:" :: "a" (data), "Nd" (portnumber));
}
Port16Bit::Port16Bit(uint16_t portnumber)
: Port(portnumber)
{
}
Port16Bit::~Port16Bit()
{
}
void Port16Bit::Write(uint16_t data)
{
__asm__ volatile("outw %0, %1" :: "a" (data), "Nd" (portnumber));
}
uint16_t Port16Bit::Read()
{
uint16_t result;
__asm__ volatile("inw %1, %0" : "=a" (result) : "Nd" (portnumber));
return result;
}
Port32Bit::Port32Bit(uint16_t portnumber)
: Port(portnumber)
{
}
Port32Bit::~Port32Bit()
{
}
void Port32Bit::Write(uint32_t data)
{
__asm__ volatile("outl %0, %1" :: "a" (data), "Nd" (portnumber));
}
uint32_t Port32Bit::Read()
{
uint32_t result;
__asm__ volatile("inl %1, %0" : "=a" (result) : "Nd" (portnumber));
return result;
}
我怎么能纠正它?程序结构有什么问题吗?
答案
OP从未显示过types.h
,但后续评论只表明存在一个真正的可能性,那就是uint16_t
没有被定义为16位类型。在x86 / x86-64上,可以使用以下命令定义此类型:
typedef unsigned short int uint16_t;
出现错误是因为为了选择扩展内联汇编模板的寄存器,GCC使用约束中传递的类型的大小来确定所选寄存器是否应该是16/32/64位寄存器。如果大小不是16位,则将选择错误大小的寄存器,并且生成的程序集将具有操作数不匹配。
在这种情况下,显然OP在创建自己的uint16_t
定义时不正确地指定了错误的大小类型。端口命令(输入,输出等)仅将DX(16位)作为寄存器操作数,而不是EDX,或RDX或DL。如果生成的寄存器不是DX,代码将编译/汇编OP看到的错误。
以上是关于内联asm:'out'的操作数类型不匹配的主要内容,如果未能解决你的问题,请参考以下文章
您如何在运行时使用 GCC 和内联 asm 检测 CPU 架构类型?
gcc写内嵌汇编报错Error: junk `(%rsp)' after register
C语言error: expected '=', ',', ';', 'asm' or '__attribute__' b