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

时间:2016-05-30 19:21:24

标签: assembly

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

asm("leal %P1(%%esp),%0"
        : "=r" (stack_end) : "i" (-STACK_SIZE));

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

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

1 个答案:

答案 0 :(得分:4)

gcc/config/i386/i386.md的评论中非正式记录P输出修饰符:

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

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

鉴于内联汇编语句仅在引导时执行一次,性能无关紧要,因此我不会因为使用LEA而试图变得聪明。您可以完全避免使用操作数修饰符,例如:

 char *stack_pointer;
 asm ("mov %%esp, %0" : "=r" (stack_pointer));
 stack_end = stack_pointer - STACK_SIZE;