C言語ポインタリファレンス学習
12391 ワード
例を挙げる
運転出core
逆アセンブリ:
main関数はcall funcの前に:
1 #include
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
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のアドレス)である.