Някакви ограничения за позоваване на високата половина на регистър в gcc inline асемблиране?

В моя 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