printf @ plt和puts @ plt之间的区别

Ber*_*glu 4 c disassembly

我一直在通过反汇编一些C代码来学习汇编语言.当我用GDB反汇编这个基本的C代码时:

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

在汇编代码中,它给出了这一行:

0x08048424 <+25>:   call   0x80482e0 <puts@plt>
Run Code Online (Sandbox Code Playgroud)

但是,当我在printf函数中具有整数的代码下面进行反汇编时:

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

它给出了这一行:

0x0804842e <+35>:   call   0x80482e0 <printf@plt>
Run Code Online (Sandbox Code Playgroud)

printf @ plt和puts @ plt有什么区别?

为什么反汇编程序在没有整数参数的情况下无法识别printf函数?

AnT*_*AnT 9

在GCC printfputs是内置的功能.这意味着编译器完全了解它们的语义.在这种情况下,如果编译器认为它将产生更好(更快和/或更紧凑)的代码,则可以自由地将对一个函数的调用替换为对另一个函数的等效调用.

puts 是一个通常更有效的函数,因为它不必解析和解释格式字符串.

这正是你的情况.您第一次打电话printf并不需要任何printf特定的功能.您提供的格式字符串printf很简单:它没有转换说明符.编译器认为您的第一次调用printf更适合使用等效调用puts.

同时,你的第二次调用printf是非常简单地使用printf格式字符串,即它依赖于printf特定的功能.

(2005年对这一具体问题进行了一些相当彻底的研究:http://www.ciselant.de/projects/gcc_printf/gcc_printf.html)