与变量参数函数“printf”的参数传递相关的指令

时间:2017-04-03 13:16:57

标签: c printf

在程序二进制文件中,如何确定与变量参数函数“printf”的参数传递相关的指令?例如:

#include <stdio.h>
#include <string.h>

int fun(int a, int b){
    return a+b;
}

void main (int argc, char* argv[]){
    int a = 0;
    int b = 1;
    int c = 2;
    int d = 3;
    printf("a:fun(b,c):d: %d:%d:%d\n", a, fun(b,c), d);
}

组装如下:

(gdb) disas main
Dump of assembler code for function main:
   0x080483f1 <+0>: push   %ebp
   0x080483f2 <+1>: mov    %esp,%ebp
   0x080483f4 <+3>: and    $0xfffffff0,%esp
   0x080483f7 <+6>: sub    $0x20,%esp
   0x080483fa <+9>: movl   $0x0,0x10(%esp)
   0x08048402 <+17>:    movl   $0x1,0x14(%esp)
   0x0804840a <+25>:    movl   $0x2,0x18(%esp)
   0x08048412 <+33>:    movl   $0x3,0x1c(%esp)
   0x0804841a <+41>:    mov    0x18(%esp),%eax
   0x0804841e <+45>:    mov    %eax,0x4(%esp)
   0x08048422 <+49>:    mov    0x14(%esp),%eax
   0x08048426 <+53>:    mov    %eax,(%esp)
   0x08048429 <+56>:    call   0x80483e4 <fun>
=> 0x0804842e <+61>:    mov    $0x8048530,%edx
   0x08048433 <+66>:    mov    0x1c(%esp),%ecx
   0x08048437 <+70>:    mov    %ecx,0xc(%esp)
   0x0804843b <+74>:    mov    %eax,0x8(%esp)
   0x0804843f <+78>:    mov    0x10(%esp),%eax
   0x08048443 <+82>:    mov    %eax,0x4(%esp)
=> 0x08048447 <+86>:    mov    %edx,(%esp)
   0x0804844a <+89>:    call   0x8048300 <printf@plt>
   0x0804844f <+94>:    leave 
   0x08048450 <+95>:    ret  

与变量参数函数“print”的参数传递相关的指令是否是两条指令“0x0804842e&lt; + 61&gt;:mov $ 0x8048530,%edx”和“0x08048447&lt; + 86&gt;:mov%edx”之间的指令, (%ESP)”。

我测试了很多功能“printf”。在我所有测试的案例中,与参数传递相关的指令都在这两个指令之间。

1 个答案:

答案 0 :(得分:-1)

您可以通过了解C调用约定来找到它。那就是参数以相反的顺序被压入堆栈。

`0x0804842e&lt; + 61&gt;:mov $ 0x8048530,%edx //可能是字符串文字

0x08048433&lt; + 66&gt;:mov 0x1c(%esp),%ecx //将3个字面移动到%ecx

0x08048437&lt; + 70&gt;:mov%ecx,0xc(%esp)//将3移到堆栈上的参数顶部(%esp是堆栈指针)

0x0804843b&lt; + 74&gt;:mov%eax,0x8(%esp)//将fun中的返回值移到堆栈的下一个插槽中,%eax存储函数的返回值。

0x0804843f&lt; + 78&gt;:mov 0x10(%esp),%eax //将0字面移动到%eax

0x08048443&lt; + 82&gt;:mov%eax,0x4(%esp)//将%eax移入堆栈的下一个插槽

0x08048447&lt; + 86&gt;:mov%edx,(%esp)//将字符串文字移动到堆栈

0x0804844a&lt; + 89&gt;:调用0x8048300` //调用printf