Есть ли ограничения для ссылки на верхнюю половину регистра во встроенной сборке gcc?

В моем коде C есть встроенная сборка, вызывающая службу PCI BIOS. Теперь проблема в том, что один из результатов возвращается в регистре %ah, но я не могу найти константу для ссылки на этот регистр.

Я хочу написать следующее:

asm("lcall *%[call_addr]" : "something here"(status) :);

а переменная status содержит значение регистра %ah.

Если я использую "=a"(status) и добавлю mov %%ah, %%al инструкцию, она будет работать. Но это кажется некрасивым.

Какие-либо предложения?


person hpsMouse    schedule 05.04.2011    source источник


Ответы (1)


Я не думаю, что есть способ указать %ah в ограничении - бэкэнд GCC x86 знает, что подрегистры содержат определенные части значений, но на самом деле не рассматривает их как независимые объекты.

Ваш подход сработает; другой вариант - сдвинуть status вниз за пределы встроенного ассемблера. например это:

unsigned int foo(void)
{
  unsigned int status;

  asm("movb $0x12, %%ah; movb $0x34, %%al" : "=a"(status) : );
  return (status >> 8) & 0xff;
}

... реализует (status >> 8) & 0xff как одну инструкцию movzbl %ah, %eax.

Третий вариант - использовать небольшую конструкцию:

unsigned int bar(void)
{
  struct { uint8_t al; uint8_t ah; } status;

  asm("movb $0x12, %%ah; movb $0x34, %%al" : "=a"(status) : );
  return status.ah;
}

Я не уверен, лучше это или нет - это кажется немного более самодокументированным, но использование небольшой структуры с ограничением регистра выглядит менее очевидным. Однако он генерирует тот же код, что и foo() выше.

(Отказ от ответственности: генерация кода тестировалась только с gcc 4.3.2; результаты могут отличаться в других версиях.)

person Matthew Slattery    schedule 05.04.2011
comment
Спасибо за вашу помощь. Я пробовал оба ваших решения перед этой публикацией. Для вашего третьего варианта я использовал объединение, которое, думаю, будет лучше. Распространенная проблема этих обходных путей заключается в том, что они требуют дополнительного кода, что делает функцию-оболочку довольно длинной. Я думаю, мне нужно сохранить мой текущий метод, прежде чем будет найден лучший. - person hpsMouse; 08.04.2011