【问题标题】:Operand type mismatch for in - gcc inline assemblyin - gcc 内联汇编的操作数类型不匹配
【发布时间】:2017-11-30 17:48:53
【问题描述】:

我有一些在行内汇编中使用 inb 指令的 C 代码。我听说 inb 接受大小为 8 位的操作数。 AL 和 DL 都是 8 位的,那为什么不行呢?

__asm__ __volatile__("inb %al, %dl");

它显示“in 的操作数类型不匹配”。如果重要的话,我在顶部有“.code16gcc”。 感谢所有帮助。

【问题讨论】:

  • 参数需要改变,因为 ATT 语法将 src 作为第一个操作数,dest 作为第二个操作数。同样port register 必须是DX 而不是DL。您还需要了解,如果您更改像AL 这样的寄存器,您需要告诉你破坏了 EAX 的 GCC。您还必须有某种类型的约束才能将其正确移动到某个地方。内联汇编很难做到正确,而代码项目教程让你走上了一条痛苦的道路,因为他们也不理解这一点。
  • 执行此类功能的正确方法是 uint8_t inb(uint16_t port) { uint8_t ret; asm volatile ("inb %1, %0" : "=a" (ret) : "dN" (port)); return ret; } 。我通常将这样的函数标记为静态内联,并将其放在头文件中。

标签: c gcc inline-assembly


【解决方案1】:

两件事:在 AT&T 风格的汇编中,目标操作数在最后,即使数据是 8 位,端口号也是 16 位。所以:

    inb %dx, %al

【讨论】:

  • 这将使它组装起来,但只有@MichaelPetch's code 才能使它真正可用作为 GNU C 内联汇编
猜你喜欢
  • 1970-01-01
  • 2019-02-17
  • 1970-01-01
  • 2018-02-11
  • 2012-12-10
  • 2016-05-18
  • 1970-01-01
  • 2019-07-08
  • 1970-01-01
相关资源
最近更新 更多