未将Printf参数压入堆栈 [英] Printf arguments not pushed on the stack

查看:67
本文介绍了未将Printf参数压入堆栈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试了解堆栈机制.

I'm in the process of trying to understand the stack mechanisms.

从我所见的理论来看,在调用函数之前,其参数已被压入堆栈.

From the theory I have seen, before a function is called, its arguments are pushed onto the stack.

但是,在下面的代码中调用printf时,没有一个被推送:

However when calling printf in the code below, none of them are pushed:

#include<stdio.h>

int main(){

    char *s = " test string";
    printf("Print this: %s and this %s \n", s, s);
    return 1;
}

我已经在printf指令的gdb中插入了一个中断,并且在显示堆栈时,这3个参数都没有被压入堆栈.

I've put a break in gdb to the printf instruction, and when displaying the stack, none of the 3 arguments are pushed onto the stack.

唯一被压入堆栈的是字符串地址s,如下面的反汇编代码所示:

The only thing pushed to the stack is the string address s as can be seen in the disassembled code below:

   0x000000000040052c <+0>: push   %rbp
   0x000000000040052d <+1>: mov    %rsp,%rbp
   0x0000000000400530 <+4>: sub    $0x10,%rsp
   0x0000000000400534 <+8>: movq   $0x400604,-0x8(%rbp) // variable pushed on the stack
   0x000000000040053c <+16>:    mov    -0x8(%rbp),%rdx
   0x0000000000400540 <+20>:    mov    -0x8(%rbp),%rax
   0x0000000000400544 <+24>:    mov    %rax,%rsi
   0x0000000000400547 <+27>:    mov    $0x400611,%edi
   0x000000000040054c <+32>:    mov    $0x0,%eax
   0x0000000000400551 <+37>:    callq  0x400410 <printf@plt>
   0x0000000000400556 <+42>:    mov    $0x1,%eax
   0x000000000040055b <+47>:    leaveq 

实际上,到目前为止,反汇编代码中出现的唯一参数是将"Print this:%s and this%s \ n"放入%edi ...

Actually, the only argument appearing so far in the disassembled code is when "Print this: %s and this %s \n" is put in %edi...

   0x0000000000400547 <+27>:    mov    $0x400611,%edi

所以我的问题是:为什么我的三个参数都看不到3个推式指令?

uname -a:3.8.0-31-generic#46-Ubuntu SMP Tue Sep 10 20:03:44 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

uname -a: 3.8.0-31-generic #46-Ubuntu SMP Tue Sep 10 20:03:44 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

推荐答案

在64位Linux x86-64系统上,应用程序二进制接口)不会将参数压入堆栈,而是使用一些寄存器(此调用约定稍快一些).

On 64 bits Linux x86-64 systems, the x86-64 ABI (x86-64 Application Binary Interface) does not push arguments on stack, but uses some registers (this calling convention is slightly faster).

如果您传递许多参数-例如一打-其中一些被压入堆栈.

在阅读x86-64 ABI规范之前,请先阅读 x86调用约定上的Wiki页.

Perhaps read first the wikipage on x86 calling conventions before reading the x86-64 ABI specifications.

对于像 printf 这样的可变函数,细节有些吓人.

For variadic functions like printf details are a bit scary.

这篇关于未将Printf参数压入堆栈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆