没有推送指令

逆向工程 部件 海湾合作委员会 amd64
2021-07-08 07:51:22

如果我将一个参数传递给一个函数,它应该用汇编语言翻译成push something. 我用 C 编写了以下代码:

#include <stdio.h>

int sum(int a, int b,int c)
{
    int total;
    total = a + b + c;
    printf ("I will return now");
    return(total);
}

int media(int a, int b,int c)
{
    int total;
    total = (a + b + c)/3;
    printf ("\nI will return now\n");
    return (total);
}

int main ()
{
    int num1,num2,num3;
    char keypress[1];

    num1 = 5;
    num2 = 10;
    num3 = 15;
    printf ("\nCalling sum function\n");
    sum(num1,num2,num3);
    printf ("\nWaiting a keypress to call media function\n");
    scanf ("%c",keypress);
    media(num1,num2,num3);
    printf ("\nWaiting a keypress to end\n");
    scanf ("%c",keypress);
    return(0);
}

我编译它:gcc -S example.c它生成了一个example.s文件,我期望看到一些推送指令。这是生成的汇编代码:

    .file   "example.c"
    .section    .rodata
.LC0:
    .string "I will return now"
    .text
    .globl  sum
    .type   sum, @function
sum:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $32, %rsp
    movl    %edi, -20(%rbp)
    movl    %esi, -24(%rbp)
    movl    %edx, -28(%rbp)
    movl    -24(%rbp), %eax
    movl    -20(%rbp), %edx
    addl    %eax, %edx
    movl    -28(%rbp), %eax
    addl    %edx, %eax
    movl    %eax, -4(%rbp)
    movl    $.LC0, %edi
    movl    $0, %eax
    call    printf
    movl    -4(%rbp), %eax
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   sum, .-sum
    .section    .rodata
.LC1:
    .string "\nI will return now"
    .text
    .globl  media
    .type   media, @function
media:
.LFB1:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $32, %rsp
    movl    %edi, -20(%rbp)
    movl    %esi, -24(%rbp)
    movl    %edx, -28(%rbp)
    movl    -24(%rbp), %eax
    movl    -20(%rbp), %edx
    addl    %eax, %edx
    movl    -28(%rbp), %eax
    addl    %edx, %eax
    movl    %eax, -4(%rbp)
    movl    -4(%rbp), %ecx
    movl    $1431655766, %edx
    movl    %ecx, %eax
    imull   %edx
    movl    %ecx, %eax
    sarl    $31, %eax
    movl    %edx, %ecx
    subl    %eax, %ecx
    movl    %ecx, %eax
    movl    %eax, -4(%rbp)
    movl    $.LC1, %edi
    call    puts
    movl    -4(%rbp), %eax
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1:
    .size   media, .-media
    .section    .rodata
.LC2:
    .string "\nCalling sum function"
    .align 8
.LC3:
    .string "\nWaiting a keypress to call media function"
.LC4:
    .string "%c"
.LC5:
    .string "\nWaiting a keypress to end"
    .text
    .globl  main
    .type   main, @function
main:
.LFB2:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movl    $5, -4(%rbp)
    movl    $10, -8(%rbp)
    movl    $15, -12(%rbp)
    movl    $.LC2, %edi
    call    puts
    movl    -12(%rbp), %edx
    movl    -8(%rbp), %ecx
    movl    -4(%rbp), %eax
    movl    %ecx, %esi
    movl    %eax, %edi
    call    sum
    movl    $.LC3, %edi
    call    puts
    leaq    -13(%rbp), %rax
    movq    %rax, %rsi
    movl    $.LC4, %edi
    movl    $0, %eax
    call    __isoc99_scanf
    movl    -12(%rbp), %edx
    movl    -8(%rbp), %ecx
    movl    -4(%rbp), %eax
    movl    %ecx, %esi
    movl    %eax, %edi
    call    media
    movl    $.LC5, %edi
    call    puts
    leaq    -13(%rbp), %rax
    movq    %rax, %rsi
    movl    $.LC4, %edi
    movl    $0, %eax
    call    __isoc99_scanf
    movl    $0, %eax
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE2:
    .size   main, .-main
    .ident  "GCC: (Debian 4.7.2-5) 4.7.2"
    .section    .note.GNU-stack,"",@progbits

当然,我遗漏了一些东西,因为我只看到了两条pushq说明。

我的问题是我错过了什么?

3个回答

如果我将一个参数传递给一个函数,它应该用汇编语言翻译成推一些东西

对于某些 32 位调用约定来说确实如此,但您的程序是 64 位程序,因此遵循System V Application Binary Interface for AMD64

来自https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI

System V AMD64 ABI 的调用约定在 Solaris、Linux、FreeBSD、Mac OS X 和其他类 UNIX 或符合 POSIX 的操作系统上遵循。前六个整数或指针参数在寄存器RDI、RSI、RDX、RCX、R8 和 R9中传递,而 XMM0、XMM1、XMM2、XMM3、XMM4、XMM5、XMM6 和 XMM7 用于浮点参数。对于系统调用,使用 R10 代替 RCX。

如果你想要汇编代码而不使用来自 C 代码的推送指令,那么总是有 C 原型#inline。

-我认为您必须阅读更多有关使用 x86-64 和 x32 模式传递参数的信息。

-正如@jason Geffner 所说,通过 32 位注入 aguments 是通过堆叠 em 来执行的,而通过 64 位则不同,它们存储在寄存器中(特别是 rsi,rdi)

-此链接更多地说明了在 64 位处理器中引入的 printf 参数机制。

  • 有关 printf 命令用法的更多示例:

X86-64加工

x32 及以下