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的地址)。

 

posted @ 2019-07-27 23:22  坚持,每天进步一点点  阅读(280)  评论(0编辑  收藏  举报