zoukankan      html  css  js  c++  java
  • 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
    ", 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
    "
            .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
    
  • 相关阅读:
    Centos搭建SVN服务器
    JavaScript 对象 之创建对象 学习笔记
    ThinkPHP 学习记录
    Git 版本控制 在 WIN 下的一些使用方法
    关于 CSS 的重用性
    双飞翼布局和圣杯布局
    cocos2dx3.8 ios打包脚本编写
    如何做dragonbones的lua绑定(xcode)
    【转】如何做dragonbones的lua绑定(Android)
    【转】如何做dragonbones的lua绑定(VisualStudio)
  • 原文地址:https://www.cnblogs.com/kekukele/p/11521963.html
Copyright © 2011-2022 走看看