inline 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\njmp 1f\n1: jmp 1f\n1:" :: "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;
}

Как я могу это исправить? Что-то не так со структурой программы?

3

Решение

ОП никогда не показывал types.h но последующие комментарии только предположили, что существует одна реальная возможность, и это было uint16_t не был определен как 16-битный тип. На x86 / x86-64 такой тип может быть определен с помощью:

typedef unsigned short int uint16_t;

Ошибки возникают потому, что для выбора регистра для расширенного встроенного шаблона сборки GCC использует размер типа, переданного в ограничении, чтобы определить, должен ли выбранный регистр быть 16/32/64-битным регистром. Если размер не 16-битный, будет выбран неправильный регистр размера, и сгенерированная сборка будет иметь несоответствие операнда.

В этом случае очевидно, что ОП неправильно указал неправильный тип размера, когда создал свой uint16_t определение. Команды порта (вход, выход и т. Д.) Принимают только DX (16-битный) в качестве операнда регистра, а не EDX, или же RDX или же DL. Если сгенерированный регистр не был DX код был бы скомпилирован / собран с ошибкой, которую видел OP.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]