zoukankan      html  css  js  c++  java
  • 指针与引用(gcc如何实现引用的)

       首先,变量名在编译成汇编语言的时候,会被翻译成地址。

     例如 :

    1 void square() {
    2     int var = 0;
    3 }

       会被翻译成 :

    1 square():
    2         push    rbp
    3         mov     rbp, rsp
    4         mov     DWORD PTR [rbp-4], 0
    5         nop
    6         pop     rbp
    7         ret

       rbp - 4 在这里就是变量名 var 翻译而成的,而 DWORD PTR [rbp - 4]就是变量值。

       而指针类型的变量名也会翻译成地址,但是这个指针变量值也是一个地址。

    1 void square() {
    2     int var = 0;
    3     int * pointer = &var;
    4 }

       会被翻译成 :

    1 square():
    2         push    rbp
    3         mov     rbp, rsp
    4         mov     DWORD PTR [rbp-12], 0
    5         lea     rax, [rbp-12]
    6         mov     QWORD PTR [rbp-8], rax
    7         nop
    8         pop     rbp
    9         ret

      在这里, rbp-12就是变量名 var 翻译而成的。

      int * pointer = &var;
      被翻译成了
      lea rax, [rbp-12]
      mov QWORD PTR [rbp-8], rax
      而指针变量名pointer 被翻译成 rbp - 8。 指针变量pointer 的值是 rbp-12。

      引用与指针的区别在哪呢?

      引用与变量名一样都是地址。

      例如 :

    1 void square() {
    2     int var = 0;
    3     int &ref = var;
    4     int * pointer = &ref;
    5 }

       会被翻译成 :

     1 square():
     2         push    rbp
     3         mov     rbp, rsp
     4         mov     DWORD PTR [rbp-20], 0
     5         lea     rax, [rbp-20]
     6         mov     QWORD PTR [rbp-8], rax
     7         mov     rax, QWORD PTR [rbp-8]
     8         mov     QWORD PTR [rbp-16], rax
     9         nop
    10         pop     rbp
    11         ret

      int * pointer = &ref;

      被翻译成:

      mov rax, QWORD PTR [rbp-8]

      mov QWORD PTR [rbp-16], rax

      其中 rbp - 8是一个指针变量 &ref,而 [rbp - 8]的值是  rbp - 20, 在这里 QWORD PTR [rbp-8]其实就是引用ref也就是 rbp - 20。 而实现的具体方法就是利用指针变量 rbp-8来实现的。

      所以创建引用所需要的内存等于指针变量所需要的内存(因为在gcc中是利用指针实现引用的)。在其他平台则不一定。

    pass by reference (to const)

      如若形参列表是引用形式,那么在gcc中会传入什么呢?

      如下 : add函数。

    1 int add (const int& a, const int& b){
    2     return a + b;
    3 }
    4 
    5 void test (){
    6     add(1,2);
    7 }

      会被翻译成 :

     1 add(int const&, int const&):
     2         push    rbp
     3         mov     rbp, rsp
     4         mov     QWORD PTR [rbp-8], rdi
     5         mov     QWORD PTR [rbp-16], rsi
     6         mov     rax, QWORD PTR [rbp-8]
     7         mov     edx, DWORD PTR [rax]
     8         mov     rax, QWORD PTR [rbp-16]
     9         mov     eax, DWORD PTR [rax]
    10         add     eax, edx
    11         pop     rbp
    12         ret
    13 test():
    14         push    rbp
    15         mov     rbp, rsp
    16         sub     rsp, 16
    17         mov     DWORD PTR [rbp-8], 2
    18         mov     DWORD PTR [rbp-4], 1
    19         lea     rdx, [rbp-8]
    20         lea     rax, [rbp-4]
    21         mov     rsi, rdx
    22         mov     rdi, rax
    23         call    add(int const&, int const&)
    24         nop
    25         leave
    26         ret

      在上述汇编代码中,rsi 和 rdi 是 add 函数的实参。而汇编代码中 17,18行表示1,2两个常量分别存储在test函数栈中 rbp - 4, rbp - 8 的位置。

      汇编代码中 19,20,21,22行则利用 lea 指令将  rbp - 4, rbp - 8 的地址作为参数传入到 add 函数中去了。

      所以 pass by reference (to const) 传入的是指针。

    以上所有解释都基于 gcc 实现。

  • 相关阅读:
    线程池ThreadPoolExcecutor介绍
    java类初始化顺序
    CountDownLatch,CyclicBarrier,Semaphore的使用
    设计模式UML图
    windows10磁盘分区后,如何恢复分区,回到未分区之前
    神州战神U盘安装windows10系统,启动项制作好后,在bios中识别不到自己的u盘问题
    项目报错:Invalid bound statement (not found):
    在docker安装tomcat的时候,报错:Caused by: java.lang.IllegalArgumentException: The AJP Connector is configured with secretRequired="true
    PowerDesigner逆向生成MYSQL数据库表结构总结
    mysql导出word的表结构操作
  • 原文地址:https://www.cnblogs.com/vizdl/p/13708811.html
Copyright © 2011-2022 走看看