反汇编c程序时的神秘printf参数

反汇编c程序时的神秘printf参数,c,assembly,stack,printf,C,Assembly,Stack,Printf,我有一个c代码: #include <stdio.h> int main(void) { int a; int b; int c; a=b=c=5; printf("Hi%d%d%dHi",a,b,c); } 然后用以下方法将其分解: objdump -M intel program -d 在main中,printf()的调用方式如下: mov DWORD PTR [esp+0x10],0x5 mov DWORD PTR

我有一个c代码:

#include <stdio.h>

int main(void)
{
    int a;
    int b;
    int c;

    a=b=c=5;

    printf("Hi%d%d%dHi",a,b,c);
}
然后用以下方法将其分解:

objdump -M intel program -d
在main中,printf()的调用方式如下:

mov    DWORD PTR [esp+0x10],0x5
mov    DWORD PTR [esp+0xc],0x5
mov    DWORD PTR [esp+0x8],0x5
mov    DWORD PTR [esp+0x4],0x8048500
mov    DWORD PTR [esp],0x1
call   8048330 <__printf_chk@plt>
我知道前4条mov指令的用途,但我就是不明白为什么“1”会被推到堆栈上。此外,此mov仅在启用优化时发生。有什么想法吗?

如果您(或编译器)定义了
\u强化\u源代码并且启用了优化,GNU C库(glibc)将使用
\u printf\u chk
而不是
printf
。函数的
\u chk
版本的行为与它所替换的函数一样,只是它应该验证参数。额外的第一个参数指示应该进行多少检查和验证

看一下,它似乎没有对编译器自动提供的内容进行任何额外的堆栈检查(因此不应该是必要的),并且参数的验证非常少。它将检查
%n
是否仅显示在只读格式字符串上,并检查如果使用了特殊的
%m$
参数说明符,则这些说明符是否用于所有参数,且没有任何间隙

mov    DWORD PTR [esp+0x10],0x5
mov    DWORD PTR [esp+0xc],0x5
mov    DWORD PTR [esp+0x8],0x5
mov    DWORD PTR [esp+0x4],0x8048500
mov    DWORD PTR [esp],0x1
call   8048330 <__printf_chk@plt>
mov    DWORD PTR [esp],0x1