C语言二级指针底层实现
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的值找到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
C语言二级指针底层实现的更多相关文章
- C语言 二级指针内存模型①
//二级指针第一种内存模型 #include<stdio.h> #include<stdlib.h> //说明:①:类似于int a[5]={0},数组名a是一维数组a中首元素 ...
- 真正明白C语言二级指针(转载)
指针是C语言的灵魂,我想对于一级指针大家应该都很熟悉,也经常用到:比如说对于字符串的处理,函数参数的“值,结果传递”等,对于二级指针或者多级指针,我想理解起来也是比较容易的,比如二级指针就是指向指针的 ...
- C语言二级指针(指向指针的指针)
转载:http://c.biancheng.net/cpp/html/85.html 指针可以指向一份普通类型的数据,例如 int.double.char 等,也可以指向一份指针类型的数据,例如 in ...
- 真正明白c语言二级指针
指针是C语言的灵魂,我想对于一级指针大家应该都很熟悉,也经常用到:比如说对于字符串的处理,函数参数的“值,结果传递”等,对于二级指针或者多级指针,我想理解起来也是比较容易的,比如二级指针就是指向指针的 ...
- C语言 二级指针内存模型混合实战
//二级指针内存模型混合实战 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #i ...
- C语言 二级指针内存模型③
//二级指针内存模型③ #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #incl ...
- C语言 二级指针内存模型②
//二级指针第二种内存模型 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #incl ...
- c语言二级指针内存模型
第一种: 指针数组作为输入参数 char *myArray[] = {"aaaaaa", "ccccc", "bbbbbb", " ...
- C语言二级指针间接赋值
重要意义:间接赋值的意义,实现了模块的功能划分,实现了软件作品的分层,使得模块接口和信息系统得以实现. 所谓二级指针就是指向指针的指针,其声明形式如下 int *p=NULL int **p1=NUL ...
随机推荐
- Spring Cloud 如何使用Eureka注册服务 4.2.2
要使用Eureka实现服务发现,需要项目中包含Eureka的服务端发现组件以及客户端发现组件. 搭建Maven父工程 创建一个Maven父工程xcservice-springcloud,并在工程的po ...
- 原生JavaScript常用本地浏览器存储方法五(LocalStorage+userData的一个浏览器兼容类)
基于LocalStorage+globalStorage+userData实现的一个本地存储类 userData用来兼容ie6 ie7 由userData模仿Session的方法:浏览器关闭删除保存的 ...
- Java并发处理锁 Lock
在上一篇文章中我们讲到了如何使用关键字synchronized来实现同步访问.本文我们继续来探讨这个问题,从Java 5之后,在 java.util.concurrent.locks 包下提供了另外一 ...
- Linux下安装redis以及常用命令
https://blog.csdn.net/zgf19930504/article/details/51850594 安装: 1.获取redis资源 wget http://download.redi ...
- Spring之28:AliasRegistry&SimpleAliasRegistry
AliasRegistry接口定义了alias的基本操作. package org.springframework.core; public interface AliasRegistry { //对 ...
- cesium 水面、淹没 效果
水面效果 参考: http://cesiumcn.org/topic/158.html http://api.rivermap.cn/cesium/rivermap/map.html https:// ...
- todo---callback
todo---callback https://blog.csdn.net/u010158267/article/details/51426963/
- Spring MVC <mvc:annotation-driven/>的作用
一.mvc:annotation-driven的作用 Spring 3.0.x中使用了mvc:annotation-driven后,默认会帮我们注册默认处理请求,参数和返回值的类,其中最主要的两个类: ...
- STL源码剖析——空间配置器Allocator#2 一/二级空间配置器
上节学习了内存配置后的对象构造行为和内存释放前的对象析构行为,在这一节来学习内存的配置与释放. C++的内存配置基本操作是::operator new(),而释放基本操作是::operator del ...
- visual studio code编辑python文件
visual studio code 安装.通过360软件管家,查找visual studio code 下载安装即可 设置visual studio code为中文 打开进入软件,Ctrl + Sh ...