返回介绍

3. 调用

发布于 2024-10-12 21:58:09 字数 3198 浏览 0 评论 0 收藏 0

函数调用示例。有关 调用约定 ,请参考下节。

typedef struct {
    long long x;
    long long y;
} data_t;

data_t test (data_t d, long long x, long long y)
{
    d.x += x;
    d.y += y;
    return d;
}

int main (void) 
{
    data_t d = { 1, 2 };
    d = test(d, 10, 11);

    printf("%lld\n", d.x);
    return 0;
}
$ gcc -g -O0 -o test main.c
$ objdump -d -M intel ./test

0000000000401185 <main>:
  401189: push   rbp
  40118a: mov    rbp,rsp                    ; -10 +=========+ rsp
  40118d: sub    rsp,0x10                   ;     | d.x = 1 |
                                            ; -8  +=========+
  401191: mov    QWORD PTR [rbp-0x10],0x1   ;     | d.y = 2 |
  401199: mov    QWORD PTR [rbp-0x8] ,0x2   ; -0  +=========+ rbp
                                            
  4011a1: mov    rsi,QWORD PTR [rbp-0x10]   ; d.x -> rsi -> rdi = 1
  4011a5: mov    rax,QWORD PTR [rbp-0x8]    ; d.y -> rax -> rsi = 2
  4011a9: mov    ecx,0xb                    ; 0xa        -> rdx = 10
  4011ae: mov    edx,0xa                    ; 0xb        -> rcx = 11
  4011b3: mov    rdi,rsi                    ;
  4011b6: mov    rsi,rax                    ; 按调用规范用寄存器传递参数。
  4011b9: call   401136 <test>              ; 第一个参数 d 用两个寄存器。
  
  4011be: mov    QWORD PTR [rbp-0x10],rax   ; 返回值也用 2 个寄存器传递。
  4011c2: mov    QWORD PTR [rbp-0x8] ,rdx   ; d.x = rax; d.y = rdx;
0000000000401136 <test>:
  40113a: push   rbp
  40113b: mov    rbp,rsp
  
  40113e: mov    rax,rsi                    ; -20 +=========+
  401141: mov    r8,rdi                     ;     | y = 11  |
  401144: mov    rsi,r8                     ; -18 +=========+
  401147: mov    rdi,r9                     ;     | x = 10  |
  40114a: mov    rdi,rax                    ; -10 +=========+
  40114d: mov    QWORD PTR [rbp-0x10],rsi   ;     | d.x = 1 |
  401151: mov    QWORD PTR [rbp-0x8] ,rdi   ; -8  +=========+
  401155: mov    QWORD PTR [rbp-0x18],rdx   ;     | d.y = 2 |
  401159: mov    QWORD PTR [rbp-0x20],rcx   ; -0  +=========+
  
  40115d: mov    rdx,QWORD PTR [rbp-0x10]   ; d.x += x;
  401161: mov    rax,QWORD PTR [rbp-0x18]   ;
  401165: add    rax,rdx                    ;
  401168: mov    QWORD PTR [rbp-0x10],rax   ;
  
  40116c: mov    rdx,QWORD PTR [rbp-0x8]    ; d.y += y; 
  401170: mov    rax,QWORD PTR [rbp-0x20]   ;
  401174: add    rax,rdx                    ;
  401177: mov    QWORD PTR [rbp-0x8],rax    ;
  
  40117b: mov    rax,QWORD PTR [rbp-0x10]   ; ret.x = d.x -> rax;
  40117f: mov    rdx,QWORD PTR [rbp-0x8]    ; ret.y = d.y -> rdx;
  
  401183: pop    rbp
  401184: ret    

编译器:函数属性

可使用 GCC 函数属性( __attribute__ )帮助编译器优化调用。

  • deprecated : 将被放弃,不建议使用。
  • noinline : 阻止内联。
  • optimize : 优化级别(0: 不优化)。
  • nonnull : 指针实参不能为空(参数索引从 1 开始,逗号分隔多个)。
__attribute__(( noinline, optimize(2) )) int add (int x, int y)
{
    int z = x + y;
    return z;
}

GCC: Declaring Attributes of Functions

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文