linux gcc汇编语言 %p0,GCC内联汇编'Nd'约束(GCC Inline Assembly 'Nd' constraint)

GCC内联汇编'Nd'约束(GCC Inline Assembly 'Nd' constraint)

我正在用C开发一个小玩具内核。我需要从键盘获取用户输入。 到目前为止,我已使用以下代码实现了inb :

static inline uint8_t inb(uint16_t port) {

uint8_t ret;

asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));

return ret;

}

我知道"=a"约束意味着al/ax/eax将被复制到ret作为输出,但我仍然对"Nd"约束感到困惑。 任何人都能提供一些有关为什么需要这种约束的见解? 或者为什么我不能只使用像"r"或"b"这样的通用寄存器约束? 任何帮助,将不胜感激。

I'm developing a small toy kernel in C. I'm at the point where I need to get user input from the keyboard. So far, I have implemented inb using the following code:

static inline uint8_t inb(uint16_t port) {

uint8_t ret;

asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));

return ret;

}

I know that the "=a" constraint means that al/ax/eax will be copied to ret as output, but I'm still confused about the "Nd" constraint. Can anyone provide some insight on why this constraint is necessary? Or why I can't just use a general purpose register constraint like "r" or "b"? Any help would be appreciated.

原文:https://stackoverflow.com/questions/32791997

更新时间:2020-02-07 11:45

最满意答案

in指令(返回一个字节)可以采用立即8位值作为端口号,也可以采用dx寄存器中指定的端口。 有关in指令的更多信息,请参见指令参考 (Intel语法)。 使用的机器约束可以在GCC文档中找到。 如果向下滚动到x86 family您将看到:

d

The d register

ñ

Unsigned 8-bit integer constant (for in and out instructions).

The in instruction (returning a byte) can either take an immediate 8 bit value as a port number, or a port specified in the dx register. More on the in instruction can be found in the instruction reference (Intel syntax) . The machine constraints being used can be found in the GCC docs . If you scroll down to x86 family you'll see:

d

The d register

N

Unsigned 8-bit integer constant (for in and out instructions).

2015-09-26

相关问答

本地标签的声明的确是一个数字后跟一个冒号。 但是对本地标签的引用需要后缀f或b ,具体取决于您是要向前还是向后 - 即1f指向前向的下一个1:标签。 所以将标签声明为1:是正确的; 但要引用它,你需要说jmp 1f (因为你在这种情况下向前跳)。 A declaration of a local label is indeed a number followed by a colon. But a reference to a local label needs a suffix of f or

...

你的示例代码不起作用的原因是因为"p"约束在内联汇编中只是非常有限的用途。 所有内联汇编操作数都要求它们可以用汇编语言表示为操作数。 如果操作数不可表示,那么编译器通过先将其移到一个寄存器并将其替换为操作数来实现。 "p"约束会增加一个限制:操作数必须是有效地址。 问题是一个寄存器不是一个有效的地址。 寄存器可以包含地址,但寄存器本身不是有效地址。 这意味着"p"约束的操作数必须具有有效的汇编表示,并且是有效的地址。 你正试图使用堆栈中变量的地址作为操作数。 虽然这是一个有效的地址,但它不是一个有

...

我从GCC的邮件列表中得到了答案 : asm("call %P0" : : "i"(callee));

现在我只需要找出%P0实际上意味着什么,因为它似乎是一个无证的功能...... 编辑 :在查看GCC源代码后,并不清楚约束前的代码P是什么意思。 但是,除其他外,它可以防止GCC将常量值放在$前面。 这正是我在这种情况下需要的。 I got the answer from GCC's mailing list: asm("call %P0" : : "i"(callee));

Now I j

...

umul指令在两个寄存器的下半部umul两个32位(无符号整数)值,并将64位结果的下半部分放入目标寄存器。 结果的上半部分写入Y寄存器。 目标寄存器的上半部分被清除。 所以你可能想要使用它的东西是这样的: #define MULTIPLY(u, r, a, b) /* (u,r = a * b) */ \

asm("umul %2, %3, %0;" /* unsigned mul */ \

"rd %%y, %1;" /* get hi wo

...

看起来像-ftree-ter (替换-ftree-ter >正常传递中的临时表达式 - 不管那是什么)是否-ftree-ter : gcc -ftree-ter test.c # no errors

这是我如何确定的: gcc -Q --help=optimizers告诉您默认启用/禁用哪些优化(某些已启用) gcc -O -Q --help=optimizers告诉你为-O启用/禁用了哪些优化 将这些命令的输出重定向到文件并进行区分。 尝试仅在指定-O时才启用的优化,直到一个工作。 Loo

...

in指令(返回一个字节)可以采用立即8位值作为端口号,也可以采用dx寄存器中指定的端口。 有关in指令的更多信息,请参见指令参考 (Intel语法)。 使用的机器约束可以在GCC文档中找到。 如果向下滚动到x86 family您将看到: d The d register

ñ Unsigned 8-bit integer constant (for in and out instructions).

The in instruction (returning a byte) can eithe

...

_asm__volatile_( "addl %%ebx,%%eax;\n"

...语法不正确。 asm和volatile是单独的关键字。 __asm__ __volatile__( "addl %%ebx,%%eax;\n"

...编译(并执行正确的结果)。 _asm__volatile_( "addl %%ebx,%%eax;\n"

...is not correct syntax. asm and volatile are separate keywords. __asm__ __vo

...

如上所述,您的代码正确编译(我已启用优化)。 但是,我相信你可能会发现这有点好一些: #include

#include

uint64_t rotate(uint64_t x, int b)

{

__asm__ ("shl %b[shift], %[value]"

: [value] "+r"(x)

: [shift] "Jc"(b)

: "cc");

re

...

默认情况下,编译器假定在写入任何输出寄存器之前将消耗所有输入,因此允许它们使用相同的寄存器。 如果可能的话,这会导致更好的代码,但是如果这种假设是错误的,事情将会发生灾难性的失败。 “早期clobber”标记是告诉编译器在所有输入被消耗之前将写入此输出的一种方式,因此它不能与任何输入共享寄存器。 By default, the compiler assumes all inputs will be consumed before any output registers are written t

...

我已经更改了代码部分,如下所示, "vmov.f64 %P[dTmp2], d8\n"

在此之后我可以编译。 我没有验证生成的代码。 对于P约束,请查看Hardwarebug / ARM内联asm机密和此电子邮件线程 。 I've changed the code part as below, "vmov.f64 %P[dTmp2], d8\n"

after this I can compile. I didn't verify the produced code. For P constra

...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值