在我的C代码中,有一些内联汇编调用PCI BIOS服务。现在问题是其中一个结果在%ah
寄存器中返回,但我找不到一个constrant来引用该寄存器。
我想要写的如下:
asm("lcall *%[call_addr]" : "something here"(status) :);
并且变量status
包含%ah
寄存器的值。
如果我使用"=a"(status)
并添加mov %%ah, %%al
指令,它将会有效。但它看起来很难看。
有什么建议吗?
答案 0 :(得分:0)
我认为没有办法在约束中指定%ah
- GCC x86后端知道子寄存器包含值的特定部分,但并不真正将它们视为独立实体。 / p>
你的方法会奏效;另一个选择是将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测试代码生成;其他版本的结果可能会有所不同。)