zoukankan      html  css  js  c++  java
  • 386-64系统函数调用ABI规范

    一、了解该规范的作用

    在看C/C++文件对应的反汇编代码中,比较关键的就是找到函数的传入参数,而这个本身并没有神秘之处,完全是ABI已经明确规定过的。这里再次整理下,方便之后查阅。

    二、文档

    一个比较全的文档

    《System V Application Binary Interface AMD64 Architecture Processor Supplement Draft Version 0.99.7

    其中对于函数参数传递说明为3.2.3 Parameter Passing
    Passing Once arguments are classified, the registers get assigned (in left-to-right order) for passing as follows:
    1. If the class is MEMORY, pass the argument on the stack.
    2. If the class is INTEGER, the next available register of the sequence %rdi,%rsi, %rdx, %rcx, %r8 and %r9 is used.
    3. If the class is SSE, the next available vector register is used, the registers are taken in the order from %xmm0 to %xmm7.
    4. If the class is SSEUP, the eightbyte is passed in the next available eightbyte chunk of the last used vector register.
    5. If the class is X87, X87UP or COMPLEX_X87, it is passed in memory
    这里通常来说,就是整数(bool、指针、整数)按照%rdi,%rsi, %rdx, %rcx, %r8 and %r9的方式优先使用寄存器,浮点数按照%xmm0 to %xmm7使用寄存器,不能通过寄存器存储的通过栈传递
    对于C++来说,由于this指针作为成员函数的隐藏指针,所以归入“整数”类型,也意味着在类成员函数调用中,第一个通用寄存器rdi存储的是this指针。

    三、例子

    tsecer@harry: cat funccall.cpp
    int pr(...);
    struct S
    {
    int x, y;

    S foo(int x, int y, float f, double d, S s)
    {
    S rs;
    rs.x = pr(this->x, this->y, x, y, f, d ,s);
    return rs;
    }
    };

    void foo()
    {
    S s;
    s.foo(1, 2, 1., .1, s);
    }
    tsecer@harry: g++ -S funccall.cpp -fverbose-asm
    tsecer@harry: cat funccall.s
    .file "funccall.cpp"
    # GNU C++ (GCC) version 4.8.5 20150623 (Red Hat 4.8.5-4) (x86_64-redhat-linux)
    # compiled by GNU C version 4.8.5 20150623 (Red Hat 4.8.5-4), GMP version 5.1.1, MPFR version 3.1.1, MPC version 1.0.1
    # warning: GMP header version 5.1.1 differs from library version 6.0.0.
    # GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
    # 传递的选项: -D_GNU_SOURCE funccall.cpp -mtune=generic
    # -march=x86-64 -fverbose-asm
    # 启用的选项: -faggressive-loop-optimizations
    # -fasynchronous-unwind-tables -fauto-inc-dec -fbranch-count-reg -fcommon
    # -fdelete-null-pointer-checks -fdwarf2-cfi-asm -fearly-inlining
    # -feliminate-unused-debug-types -fexceptions -ffunction-cse -fgcse-lm
    # -fgnu-runtime -fgnu-unique -fident -finline-atomics -fira-hoist-pressure
    # -fira-share-save-slots -fira-share-spill-slots -fivopts
    # -fkeep-static-consts -fleading-underscore -fmath-errno
    # -fmerge-debug-strings -fmove-loop-invariants -fpeephole
    # -fprefetch-loop-arrays -freg-struct-return
    # -fsched-critical-path-heuristic -fsched-dep-count-heuristic
    # -fsched-group-heuristic -fsched-interblock -fsched-last-insn-heuristic
    # -fsched-rank-heuristic -fsched-spec -fsched-spec-insn-heuristic
    # -fsched-stalled-insns-dep -fshow-column -fsigned-zeros
    # -fsplit-ivs-in-unroller -fstrict-volatile-bitfields -fsync-libcalls
    # -ftrapping-math -ftree-coalesce-vars -ftree-cselim -ftree-forwprop
    # -ftree-loop-if-convert -ftree-loop-im -ftree-loop-ivcanon
    # -ftree-loop-optimize -ftree-parallelize-loops= -ftree-phiprop -ftree-pta
    # -ftree-reassoc -ftree-scev-cprop -ftree-slp-vectorize
    # -ftree-vect-loop-version -funit-at-a-time -funwind-tables -fverbose-asm
    # -fzero-initialized-in-bss -m128bit-long-double -m64 -m80387
    # -maccumulate-outgoing-args -malign-stringops -mfancy-math-387
    # -mfp-ret-in-387 -mfxsr -mglibc -mieee-fp -mlong-double-80 -mmmx -mno-sse4
    # -mpush-args -mred-zone -msse -msse2 -mtls-direct-seg-refs

    .section .text._ZN1S3fooEiifdS_,"axG",@progbits,_ZN1S3fooEiifdS_,comdat
    .align 2
    .weak _ZN1S3fooEiifdS_
    .type _ZN1S3fooEiifdS_, @function
    _ZN1S3fooEiifdS_:
    .LFB0:
    .cfi_startproc
    pushq %rbp #
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq %rsp, %rbp #,
    .cfi_def_cfa_register 6
    subq $64, %rsp #,
    movq %rdi, -24(%rbp) # this, this
    movl %esi, -28(%rbp) # x, x
    movl %edx, -32(%rbp) # y, y
    movss %xmm0, -36(%rbp) # f, f
    movsd %xmm1, -48(%rbp) # d, d
    movq %rcx, -64(%rbp) # s, s
    movss -36(%rbp), %xmm0 # f, D.2251
    cvtps2pd %xmm0, %xmm0 # D.2251, D.2251
    movq -24(%rbp), %rax # this, tmp65
    movl 4(%rax), %esi # this_3(D)->y, D.2252
    movq -24(%rbp), %rax # this, tmp66
    movl (%rax), %edi # this_3(D)->x, D.2252
    movq -64(%rbp), %r8 # s, tmp67
    movq -48(%rbp), %rax # d, tmp68
    movl -32(%rbp), %ecx # y, tmp69
    movl -28(%rbp), %edx # x, tmp70
    movq %rax, -56(%rbp) # tmp68, %sfp
    movsd -56(%rbp), %xmm1 # %sfp,
    movl $2, %eax #,
    call _Z2prz #
    movl %eax, -16(%rbp) # D.2252, rs.x
    movq -16(%rbp), %rax # rs, D.2244
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
    .LFE0:
    .size _ZN1S3fooEiifdS_, .-_ZN1S3fooEiifdS_
    .text
    .globl _Z3foov
    .type _Z3foov, @function
    _Z3foov:
    .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 #,
    movq -16(%rbp), %rdx # s, tmp60
    movabsq $4591870180066957722, %rax #, tmp61
    leaq -16(%rbp), %rdi #, tmp62
    movq %rdx, %rcx # tmp60,
    movq %rax, -24(%rbp) # tmp61, %sfp
    movsd -24(%rbp), %xmm1 # %sfp,
    movss .LC1(%rip), %xmm0 #,
    movl $2, %edx #,
    movl $1, %esi #,
    call _ZN1S3fooEiifdS_ #
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
    .LFE1:
    .size _Z3foov, .-_Z3foov
    .section .rodata
    .align 4
    .LC1:
    .long 1065353216
    .ident "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-4)"
    .section .note.GNU-stack,"",@progbits
    tsecer@harry:

  • 相关阅读:
    C# 反射 通过类名创建类实例
    c#委托把方法当成参数
    PPT美化大师
    以Outlook样式分组和排列数据项
    使用windows服务和MSMQ和进行日志管理(解决高并发问题)
    springboot配置filter
    filter 中用spring StopWatch 监控请求执行时间
    spring计时工具类stopwatch用法
    Spring异步任务处理,@Async的配置和使用
    注解用法详解——@SuppressWarnings
  • 原文地址:https://www.cnblogs.com/tsecer/p/12053045.html
Copyright © 2011-2022 走看看