Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does %P stand for in gcc inline assembly

Tags:

assembly

In Linux kernel linux/arch/x86/boot/main.c, I found a piece of inline asm code:

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

This code snippet is pretty simple, but %P1 confused me. I checked some assembly language tutorials, but found nothing about this.

So, can anyone give me some pieces of clue about this?

like image 935
Douglas Su Avatar asked May 30 '16 19:05

Douglas Su


People also ask

What is __ asm __ in C?

The __asm keyword invokes the inline assembler and can appear wherever a C or C++ statement is legal. It cannot appear by itself. It must be followed by an assembly instruction, a group of instructions enclosed in braces, or, at the very least, an empty pair of braces.

What is inline assembly code?

In computer programming, an inline assembler is a feature of some compilers that allows low-level code written in assembly language to be embedded within a program, among code that otherwise has been compiled from a higher-level language such as C or Ada.

What is r in inline assembly?

The “r” in the operand constraint string indicates that the operand must be located in a register. The “=” indicates that the operand is written. Each output operand must have “=” in its constraint.

What is asm function in C?

The asm statement allows you to include assembly instructions directly within C code. This may help you to maximize performance in time-sensitive code or to access assembly instructions that are not readily available to C programs. Note that extended asm statements must be inside a function.


1 Answers

The P output modifier is unofficially documented in a comment in gcc/config/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.

The upper-case P modifier probably isn't what is wanted here, but when not compiling PIC (Position Independent Code), then it acts like the lower-case p modifier. The intent to prevent the compiler from emitting the operand using the format normally used for immediate values, which wouldn't work here. As David Wohlferd said it would be a better idea to use the c modifier, which is documented and is meant specifically to handle immediate values. Mind you this code was probably written before the c modifier was documented, as for a long time none of the modifiers were documented.

Given that the inline assembly statement is only executed once at boot time, performance doesn't matter, so I wouldn't have bothered trying to be smart by using LEA. You can avoid the operand modifiers completely with something simple like:

 char *stack_pointer;
 asm ("mov %%esp, %0" : "=r" (stack_pointer));
 stack_end = stack_pointer - STACK_SIZE;
like image 147
Ross Ridge Avatar answered Nov 15 '22 13:11

Ross Ridge