%P在gcc内联汇编中代表什么?

Dou*_* Su 9 assembly

在Linux内核中linux/arch/x86/boot/main.c,我发现了一段内联asm代码:

asm("leal %P1(%%esp),%0"
        : "=r" (stack_end) : "i" (-STACK_SIZE));
Run Code Online (Sandbox Code Playgroud)

这段代码非常简单,但%P1让我很困惑.我检查了一些汇编语言教程,但没有发现这一点.

那么,有人能给我一些关于此的线索吗?

Ros*_*dge 5

P输出修饰符非官方记录在评论GCC /配置/ I386 / i386.md

;; The special asm out single letter directives following a '%' are:
...
;; P -- if PIC, print an @PLT suffix.
;; p -- print raw symbol name.
Run Code Online (Sandbox Code Playgroud)

大写P修饰符可能不是这里想要的,但是当不编译 PIC(位置无关代码)时,它就像小写p修饰符一样。防止编译器使用通常用于立即值的格式发出操作数的意图,这在这里不起作用。正如 David Wohlferd 所说,使用c修饰符是一个更好的主意,该修饰符已记录在案,专门用于处理直接值。请注意,这段代码可能是在c修改器被记录之前编写的,因为很长一段时间没有任何修改器被记录下来。

鉴于内联汇编语句仅在启动时执行一次,性能并不重要,因此我不会费心尝试使用 LEA 来变得聪明。您可以使用以下简单的方法完全避免操作数修饰符:

 char *stack_pointer;
 asm ("mov %%esp, %0" : "=r" (stack_pointer));
 stack_end = stack_pointer - STACK_SIZE;
Run Code Online (Sandbox Code Playgroud)