Difference between printf@plt and puts@plt

早过忘川 提交于 2021-02-07 03:28:12

问题


I've been learning assembly language by disassembling some C code. When I disassemble this basic C code with GDB:

#include <stdio.h>
void main(void) {
    printf("Hello World\n");
}

Among assembly code, it gives this line:

0x08048424 <+25>:   call   0x80482e0 <puts@plt>

However, when I disassemble below code which has an integer in printf function:

#include <stdio.h>
void main(void) {
    int a = 1;
    printf("Hello Word %d\n", a);
}

It gives this line:

0x0804842e <+35>:   call   0x80482e0 <printf@plt>

What is the difference between printf@plt and puts@plt?

Why disassembler does not recognize printf function without an integer parameter?


回答1:


In GCC printf and puts are built-in functions. Which means that the compiler has full knowledge of their semantics. In such cases the compiler is free to replace a call to one function with an equivalent call to another, if it thinks that it will produce better (faster and/or more compact) code.

puts is a generally more efficient function since it does not have to parse and interpret a format string.

This is exactly what happened in your case. Your first call to printf does not really need any printf-specific features. The format string you supplied to printf is trivial: it has no conversion specifiers in it. The compiler thought that your first call to printf is better served with an equivalent call to puts.

Meanwhile, your second call to printf makes non-trivial use of printf format string, i.e. it relies on printf-specific features.

(Some rather thorough research of this specific matter from 2005: http://www.ciselant.de/projects/gcc_printf/gcc_printf.html)




回答2:


I don't know about the @plt part, but printf and puts are simply two different standard library functions. printf takes a format string and zero or more other parameters, possibly of different types. puts takes just a string and prints it, followed by a newline. Consult any C reference for more information, or type

man 3 printf
man 3 puts

assuming you're on a Unix-like system with man pages installed. (man printf without the 3 will show you the printf command; you want the printf function.)

Your compiler is able to optimize the call

printf("Hello, world\n");

to the equivalent of:

puts("Hello, world");

because it knows what both functions do, so it can determine that they do exactly the same thing.

It can't optimize

printf("Hello Word %d\n", a);

because the value of a is unknown at compile time, so it doesn't print a fixed string. (It might figure it out at higher optimization levels by observing that a is never modified after its initialization).

The disassembler is merely showing you the code generated by the compiler.

(Incidentally, void main(void) is incorrect; use int main(void).)




回答3:


The puts and printf functions appear to have the same address because you are looking at stubs, and not the real functions. These stubs load an address from the procedure link table (what the @plt suffix refers to) and then call it.

I'm disassembling a program, and see that it has stubs for both printf and puts:

08048370 <printf@plt>:
 8048370:       ff 25 04 a0 04 08       jmp    *0x804a004
 8048376:       68 08 00 00 00          push   $0x8
 804837b:       e9 d0 ff ff ff          jmp    8048350 <_init+0x3c>

08048380 <puts@plt>:
 8048380:       ff 25 08 a0 04 08       jmp    *0x804a008
 8048386:       68 10 00 00 00          push   $0x10
 804838b:       e9 c0 ff ff ff          jmp    8048350 <_init+0x3c>

As you can see, the real functions are somewhere else, and these stubs are only generated for the functions that your program actually uses. If you have a program which calls only one function and then change it from printf to puts, it's not suprising that the one and only stub is at the same address. The program I just disassembled calls both printf and puts, and so has stubs for both, and consequently they have different addresses.



来源:https://stackoverflow.com/questions/39007002/difference-between-printfplt-and-putsplt

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!