C语言二级指针底层实现

时间:2021-03-01 22:05:28

C语言中,Pointers to Pointers,即二级指针。

一级指针和二级指针的值都是指向一个内存单元:

  • 一级指针指向的内存单元存放的是源变量的值,
  • 二级指针指向的内存单元存放的是一级指针的地址。

下面,我们通过如下代码展示二级指针的底层实现:

#include <stdio.h>

int main(){
int a = 777;
int* b = &a;
int** c = &b;
*b = 888;
**c = 999;
printf("a=%d\n", a);
return 0;
}

假设:

  • 栈的基地址为0,即rbp寄存器指向0;
  • 栈的指针寄存器rsp指向地址为-32。

则,c语言语句**c = 999的底层实现过程如下图所示:

C语言二级指针底层实现

底层实现中,汇编语言首先找到c的值,通过c的值找到b的值,通过b的值找到a,并赋值999给a。

具体汇编代码如下:

         .file   "hlist.c"
.text
.section .rodata
.LC0:
.string "a=%d\n"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
movq %rsp, %rbp
subq $32, %rsp // rsp 减去 32
movq %fs:40, %rax
movq %rax, -8(%rbp)
xorl %eax, %eax
movl $777, -28(%rbp) // 地址为-28处的存储单元的值为777,即a赋值为777
leaq -28(%rbp), %rax // 将-28地址(a的地址)赋给%rax
movq %rax, -24(%rbp) // 将-28(64位,8字节)值给地址为-24的存储单元
leaq -24(%rbp), %rax // 将-24地址(b的地址)赋给%rax
movq %rax, -16(%rbp) // 将b的地址赋值给地址为-16的存储单元
movq -24(%rbp), %rax // 将b的值(a的地址)赋值给%rax
movl $888, (%rax) // a = 888
movq -16(%rbp), %rax // 将c的值(b的地址)赋值给%rax
movq (%rax), %rax // 将b的值赋值给%rax
movl $999, (%rax) // a = 999
movl -28(%rbp), %eax
movl %eax, %esi
leaq .LC0(%rip), %rdi
movl $0, %eax
call printf@PLT
movl $0, %eax
movq -8(%rbp), %rdx
xorq %fs:40, %rdx
je .L3
call __stack_chk_fail@PLT
.L3:
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0"
.section .note.GNU-stack,"",@progbits