zoukankan      html  css  js  c++  java
  • C 语言指针 引用学习

    举个实例

     1 #include<stdio.h>
     2 int test_num;
     3 void func(int *p)
     4 {
     5     p = &test_num;
     6 }
     7 int main(void)
     8 {
     9     int *p;
    10     func(p);
    11     *p = 1000;
    12     return 0;
    13 }

    运行出core

    反汇编:

    gcc -S t3.c -o t3.s
    
        .file    "t3.c"
        .comm    test_num,4,4
        .text
        .globl    func
        .type    func, @function
    func:
    .LFB0:
        .cfi_startproc
        pushq    %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        movq    %rdi, -24(%rbp)
        movq    $test_num, -8(%rbp)
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
    .LFE0:
        .size    func, .-func
        .globl    main
        .type    main, @function
    main:
    .LFB1:
        .cfi_startproc
        pushq    %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        subq    $16, %rsp
        movq    -8(%rbp), %rax
        movq    %rax, %rdi
        call    func
        movq    -8(%rbp), %rax
        movl    $1000, (%rax)
        movl    $0, %eax
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
    .LFE1:
        .size    main, .-main
        .ident    "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.4) 4.8.4"
        .section    .note.GNU-stack,"",@progbits

    main函数在call func之前:

    
    
        movq    -8(%rbp), %rax
        movl    $1000, (%rax)

    明显的错误,把ebp的下4字节的内容移动到当前esp所指向的内容,实际上做了一个*p的副本,为func函数使用;
    调用func函数后:
      movq $test_num, -8(%rbp)
    于是,func函数操作的只是*p的副本,把副本里存放了test_num的首地址。
    ret回main函数后,变量test_num赋值为1000,main函数里的*p,是不知道的,因为,只有它的副本知道。

    更改源码:

     1 #include<stdio.h>
     2 int test_num;
     3 void func(int **p)
     4 {
     5     *p = &test_num;
     6 }
     7 int main(void)
     8 {
     9     int *p;
    10     func(&p);
    11     *p = 1000;
    12     return 0;
    13 }

    反汇编处理:

     1     .file    "t3.c"
     2     .comm    test_num,4,4
     3     .text
     4     .globl    func
     5     .type    func, @function
     6 func:
     7 .LFB0:
     8     .cfi_startproc
     9     pushq    %rbp
    10     .cfi_def_cfa_offset 16
    11     .cfi_offset 6, -16
    12     movq    %rsp, %rbp
    13     .cfi_def_cfa_register 6
    14     movq    %rdi, -8(%rbp)
    15     movq    -8(%rbp), %rax
    16     movq    $test_num, (%rax)
    17     popq    %rbp
    18     .cfi_def_cfa 7, 8
    19     ret
    20     .cfi_endproc
    21 .LFE0:
    22     .size    func, .-func
    23     .globl    main
    24     .type    main, @function
    25 main:
    26 .LFB1:
    27     .cfi_startproc
    28     pushq    %rbp
    29     .cfi_def_cfa_offset 16
    30     .cfi_offset 6, -16
    31     movq    %rsp, %rbp
    32     .cfi_def_cfa_register 6
    33     subq    $16, %rsp
    34     leaq    -8(%rbp), %rax
    35     movq    %rax, %rdi
    36     call    func
    37     movq    -8(%rbp), %rax
    38     movl    $1000, (%rax)
    39     movl    $0, %eax
    40     leave
    41     .cfi_def_cfa 7, 8
    42     ret
    43     .cfi_endproc
    44 .LFE1:
    45     .size    main, .-main
    46     .ident    "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.4) 4.8.4"
    47     .section    .note.GNU-stack,"",@progbits

    可以看到有发生变化

    也就是说,作为副本供func函数使用的不是ebp下4个字节的内容,而是内容里所指向的地址(即mian函数*p的地址)。

  • 相关阅读:
    通过USB转TTL串口下载stm32程序
    实验一:基于STM32F1的流水灯实验(库函数)
    opencv 常用头文件介绍
    OpenCV 1.0在VC6下安装与配置(附测试程序)
    在Angularjs使用中遇到的那些坑
    js和ts关于遍历的几个小总结
    angularjs的启动方式
    关于跨域和如何解决跨域问题的小结
    TypeScript(入门)
    截取字符串部分汇总
  • 原文地址:https://www.cnblogs.com/mysky007/p/11257273.html
Copyright © 2011-2022 走看看