如何在内联汇编中使用 INT %0 和来自 C 变量的中断号?

Kon*_*eam 0 c x86 assembly gcc inline-assembly

我想调用 bios 内联我的 c 代码。我试过了,asm("int %%al"::"a" (interrupt));但 gcc 写Error: operand size mismatch for 'int'。我想知道代码是否有效。

Nat*_*dge 6

int指令必须采取其作为立即向量; 它没有从寄存器中获取数字的形式。见指令说明;请注意,第二种形式是INT imm8并且没有类似INT r8INT r/m8允许寄存器或内存操作数的东西。

如果interrupt可以评估为编译时常量,那么您可能能够做到

asm volatile("int %0" : : "i" (interrupt));
Run Code Online (Sandbox Code Playgroud)

请注意,为了让中断做一些有用的事情,您可能必须事先将各种值加载到寄存器中,然后检索返回的值。这些将需要作为同asm一块的一部分来完成,需要更多的操作数和约束。你不能把类似的东西asm("mov $0x1a, %%ah");放在前面的块中;编译器不需要在块之间保留寄存器内容。

如果直到运行时您才真正知道中断号,您的选择是组合所有 256 条可能的int指令并跳转到正确的指令,或者使用自修改代码。

  • @KonectTeam:这意味着我的第二句话中的“If”不满足 - 编译器无法在编译时确定“interrupt”的值。如果您还没有这样做,启用优化可能会有所帮助。否则,请重写您的代码所以它是一个常数,否则请看我的最后一句话。 (3认同)