这是我的当前代码:
我的想法是接受参数
从我读过的资料来看,上述代码似乎是正确的,目标寄存器具有
如果我将标志更改为简单的
void int32hex(u32 val, char *out) {
asm("rev %[dst], %[src]" :: [dst]"=r"(val), [src]"r"(val));
binhex((u8*)&val, 4, out);
}
我的想法是接受参数
val
,使用rev
指令翻转它的字节序,然后将其传递下去。从我读过的资料来看,上述代码似乎是正确的,目标寄存器具有
=r
标志,这意味着寄存器可以被写入。然而,当通过GCC运行时,我会收到错误消息:输入操作数限制包含'='。如果我将标志更改为简单的
r
,那么它就会编译成功,但val
的值不会改变。
asm("rev %[swap], %[swap]" : [swap] "=r" (val) : "0" (val));
可能更好。您可以使用 "0" 指定符号来表示输入与给定输出相同;这样做有时会生成更好的代码,因为寄存器是相同的。另外,src/dst 很令人困惑,正如您所指出的那样。 - artless noise0
约束将强制它使用相同的寄存器用于源和目标,这可能需要额外的移动来将它们放在同一位置。使用单独的输入和输出约束允许编译器使用相同的寄存器或不同的寄存器,以哪个更好为准。在这种特定情况下,这是无关紧要的,但使用0
永远不会更好。 - Chris Dodddst
只是一个操作寄存器的标识符名称,因此无法通过任何方式进行计算。如果val
已经在特定寄存器(例如参数寄存器)中,并且下一步需要在另一个寄存器中使用(例如返回值寄存器),则0
将需要额外的移动。 - Chris Doddval
在汇编指令之前和之后具有相同的名称并不意味着它在同一位置。一个0
会造成伤害的例子是:如果你有一个函数u32 fn(int ign, u32 val) { asm(...); return val; }
,使用0
将会有3条指令(rev+mov+ret),而不使用则只有rev+ret。 - Chris Doddint32hex
和binhex
在同一个寄存器(R0)中具有val
。 “0”注释排除了rev
可以用作swap+move,这是确实的。然而,gcc 4.8.2 可以使用您的注释相同的寄存器,因此从代码生成的角度来看,它可能总是更好。 - artless noise