逆向-beginners之参数

#include

int f(int a, int b, int c)
{
    return a * b + c;
}

int main()
{
    printf("%d\n", f(1, 2, 3));    // 5
    return 0;
}

#if 0

调用方(caller)函数通过栈向被调用方(callee)函数传递参数。

/*
 * x86
 */

    
/*
 * x64
 */
    能够使用寄存器传递(前4个或前6个)参数。

    LEA 的效率比 ADD 的效率高,向寄存器赋值的速度也比MOV快。

    比较意外的是,原本位于寄存器的3个参数都被推送到了栈里。这种现象叫作"阴影空间/shadow space"。

    每个win64程序都可以(但非必须)把4个寄存器的值保存到阴影空间里。使用阴影空间有两个优点:
    1.通过栈传递参数,可避免浪费寄存器资源(有时可能会占用4个寄存器)。
    2.便于调试器在程序中断时找到函数参数。

    大型函数可能会把输入参数保存在阴影空间里,但是小型函数可能就不会使用阴影空间了。

    在使用阴影空间时,由调用方函数分配栈空间,由被调用方函数根据需要将寄存器参数转储到它们阴影空间中。

/*
 * gcc
 */
    阴影空间只是微软的概念,system V*nix里没有这种规范或约定。
    GCC只在在寄存器数量容纳不下所有参数的情况下,才会使用栈传递参数。


#endif

#if 0
/*
 * intel
 */
0000000000001149 :
    1149:    f3 0f 1e fa              endbr64
    114d:    55                       push   %rbp
    114e:    48 89 e5                 mov    %rsp,%rbp
    1151:    89 7d fc                 mov    %edi,-0x4(%rbp)  // 1
    1154:    89 75 f8                 mov    %esi,-0x8(%rbp)  // 2
    1157:    89 55 f4                 mov    %edx,-0xc(%rbp)  // 3
    115a:    8b 45 fc                 mov    -0x4(%rbp),%eax  // eax=a
    115d:    0f af 45 f8              imul   -0x8(%rbp),%eax  // eax=a*b
    1161:    89 c2                    mov    %eax,%edx        // edx=eax
    1163:    8b 45 f4                 mov    -0xc(%rbp),%eax  // eax=c
    1166:    01 d0                    add    %edx,%eax        // eax=a*b+c
    1168:    5d                       pop    %rbp
    1169:    c3                       retq   

000000000000116a

:
    116a:    f3 0f 1e fa              endbr64
    116e:    55                       push   %rbp
    116f:    48 89 e5                 mov    %rsp,%rbp
    1172:    ba 03 00 00 00           mov    $0x3,%edx        // edx=3
    1177:    be 02 00 00 00           mov    $0x2,%esi        // esi=2
    117c:    bf 01 00 00 00           mov    $0x1,%edi        // edi=1
    1181:    e8 c3 ff ff ff           callq  1149
    1186:    89 c6                    mov    %eax,%esi
    1188:    48 8d 3d 75 0e 00 00     lea    0xe75(%rip),%rdi        # 2004 <_IO_stdin_used+0x4>
    118f:    b8 00 00 00 00           mov    $0x0,%eax
    1194:    e8 b7 fe ff ff           callq  1050
    1199:    b8 00 00 00 00           mov    $0x0,%eax
    119e:    5d                       pop    %rbp
    119f:    c3                       retq  

/*
 * arm
 */
000000000040055c :
  40055c:    d10043ff     sub    sp, sp, #0x10
  400560:    b9000fe0     str    w0, [sp, #12]   // 1
  400564:    b9000be1     str    w1, [sp, #8]    // 2
  400568:    b90007e2     str    w2, [sp, #4]    // 3
  40056c:    b9400fe1     ldr    w1, [sp, #12]   // w1=1
  400570:    b9400be0     ldr    w0, [sp, #8]    // w0=2
  400574:    1b007c21     mul    w1, w1, w0      // w1=1*2
  400578:    b94007e0     ldr    w0, [sp, #4]    // w0=3
  40057c:    0b000020     add    w0, w1, w0      // w0=1*2+3
  400580:    910043ff     add    sp, sp, #0x10
  400584:    d65f03c0     ret

0000000000400588

:
  400588:    a9bf7bfd     stp    x29, x30, [sp, #-16]!
  40058c:    910003fd     mov    x29, sp
  400590:    52800062     mov    w2, #0x3                       // #3
  400594:    52800041     mov    w1, #0x2                       // #2
  400598:    52800020     mov    w0, #0x1                       // #1
  40059c:    97fffff0     bl    40055c
  4005a0:    2a0003e1     mov    w1, w0
  4005a4:    90000000     adrp    x0, 400000 <_init-0x3e8>
  4005a8:    9119c000     add    x0, x0, #0x670
  4005ac:    97ffffa9     bl    400450
  4005b0:    52800000     mov    w0, #0x0                       // #0
  4005b4:    a8c17bfd     ldp    x29, x30, [sp], #16
  4005b8:    d65f03c0     ret
  4005bc:    00000000     .inst    0x00000000 ; undefined
#endif

你可能感兴趣的:(Assembly,汇编)