【问题标题】:Compiler warnings when implementing outl实现 outl 时的编译器警告
【发布时间】:2017-09-27 18:08:49
【问题描述】:

对于一个类项目,我正在实现一个内核级网络驱动程序,它利用向端口写入各种值。我为outboutw 创建了宏,它们都可以正常工作,但outl 继续发出编译器警告。定义如下:

#define outl(data, port)                \
do {                                    \
    asm volatile("outl  %l1, (%w0)"     \
        :                               \
        : "d" (port), "a" (data)        \
        : "memory", "cc" );             \
} while(0)

编译器给出错误:invalid 'asm': '%l' operand isn't a label

如果我这样定义它:

#define outl(data, port)                \
do {                                    \
    asm volatile("outl  %1, %0"         \
        :                               \
        : "dN" (port), "a" (data)       \
        : "memory", "cc" );             \
} while(0)

我从汇编器那里收到这条消息:Warning: using '%eax' instead of '%ax' due to 'l' suffix

我做错了什么?消除这两个警告的正确语法是什么?

【问题讨论】:

  • 您使用的是 C 和 C++ 中的哪一个?请删除您不使用的语言的标签。
  • 如何调用outl 宏?您的调用中data 的类型是什么?
  • 你希望%l1 做什么?
  • 如果您不回答您在 cmets 中收到的问题,您的问题很可能会因为“不清楚您在问什么”而被关闭,因为您拒绝澄清。
  • %l1 用于标签。你可能是指%k1k是请求32位的注册表单。

标签: c assembly osdev


【解决方案1】:

Michael Petch 给出了正确答案。我所在的班级实际上已经给了我们第一个示例,但显然他们从未实际测试过。

我希望 %l1 指定值是 32 位,就像 %b1 用于 4 位和 %w1 用于 16 位一样。解决方案是%k1

【讨论】:

  • 实际上,如果操作数的类型正确,则不需要k修饰符。 k 修饰符有些危险,例如,如果值在 al 中,它会盲目地使用 eax,即使 eax 的其余部分包含垃圾。而是首先确保操作数具有正确的类型(例如,使用显式强制转换)。
  • @fuz :我建议(在我在 OP 问题下的评论中)创建函数 static inline 是有原因的(我会进一步添加 __attribute__((always_inline)) 并将函数在标题中。至少你可以让它检查类型并尽可能提升类型。正如你所说,你也可以将data显式转换为uint32_t
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多