美文网首页
golang函数调用的执行逻辑

golang函数调用的执行逻辑

作者: XITEHIP | 来源:发表于2019-06-21 17:40 被阅读0次

golang中的函数调用底层是靠栈帧实现的,翻看了好多文章发现很少有从最终机器码层面进行解释的,我跟踪发现要比golang汇编复杂一些,具体为什么要有这个命令为啥这么扩容,扩容多少这都是编译器算出来的,我们不需要知道。这篇文章的目的是对函数调用的一个更深层次的认识,当然如果要学好golang中的汇编还需要去看golang汇编相关的知识讲解。从实际开发中需要明白golang汇编就好。

以下代码环境:
1,Linux version 3.10.0-957.12.2.el7.x86_64
2,go version go1.12.5 linux/amd64

以下是我做实验的代码两个数相加的一个函数。

package main
import "fmt"

func main()  {
    d := jia(1,2)
    fmt.Println(d)
}

func jia(a, b int) int {
    c := a + b
    return c
}

然后编译成可执行文件。
go build -gcflags "-N -l" -o run
这里gcflags参数是去掉编译优化,方便调试。
然后用gdb工具进行查看相应的汇编代码,如下:

图1
sub rbp,0x70(%rsp) //将rbp的值存入到old rbp处见图2。
lea 0x70(%rsp),%rbp //将old rbp位置的地址存入到rbp作为main的栈底。

movq $0x1, (%rsp) //将函数参数1放入栈中。

movq $0x2, 0x8(%rsp) //将函数参数2放入栈中。
执行完绿框处代码栈的赋值情况见下图2。(其中蓝色的框是第一次扩容的main函数栈空间。绿色的表示调用调用 call jia时候call内部又扩容了8个byte(我猜是函数返回值占8个字节)。粉色是jia函数扩容16个字节。绿色加蓝色的空间是就是jia的栈空间)


图2

刚扩容完之后栈中的数据见图3:


图3

执行到call jia指令,参数赋值到栈中,栈顶向低地址移动8byte,见下图4:


图4

去0x4872d0<main.jia>地址处查看汇编码,见图5:


图5

然后执行到图6位置:


图6
从图中可以看出将计算结果放到了rax中且赋值到了栈顶处。然后在看一下栈的整体流程图见图7:
图7

从图7可以看出函数的参数,返回值都放到了栈中,然后继续执行见下图8:


图8

调用完jia(int,int)的retq时,rsp又缩容到初次扩容的地方0xc000032718处,这样栈顶的前3个位置分别为参数和返回值。

在继续执行我发现0xc000032718处的数据依然存在,我猜这些数据不会被删除,如果再用到此空间直接覆盖就好,因为如果用完删除的话会影响性能。

以上就是函数调用的大概流程,直观感受一下就好,但是函数调用如何传参,如何获取返回,大致思路都是一样的都是借助类似栈结构及栈的收缩来实现的。

相关文章

  • golang函数调用的执行逻辑

    golang中的函数调用底层是靠栈帧实现的,翻看了好多文章发现很少有从最终机器码层面进行解释的,我跟踪发现要比go...

  • golang中defer的使用

    在golang当中,defer代码块会在函数调用链表中增加一个函数调用。这个函数调用不是普通的函数调用,而是会在函...

  • 003-golang 调用外部命令

    003-golang 调用外部命令 相关函数 exec包执行外部命令,它将os.StartProcess进行包装使...

  • 一 -35 python (函数)函数的嵌套调用

    函数的嵌套调用 一个函数里面 又调用 了 另外一个函数,这就是 函数嵌套调用 函数的执行顺序必须是先执行定义再执行...

  • 关于Golang的那些事(五) -- 函数

    函数包含连续的执行语句,可以在代码中通过调用函数来执行它们。函数能将复杂的逻辑转换为一块块的代码块,使得更具...

  • day9-函数2

    9.1 函数的调用 函数在声明时不会执行函数体,只有在调用函数的时候才会执行函数体 函数的调用过程(重点!) a....

  • day9-总结

    一.函数的调用 函数在声明的时候不会执行函数体, 只有在调用函数的时候才会执行函数体 1.函数的调用过程(重点!)...

  • day9 函数

    函数的调用 函数在声明的时候不会执行函数体,只有在调用函数的时候才会执行函数体 1.函数的调用过程(重点!) a....

  • day9-函数

    一.函数的调用 函数在声明的时候不会执行函数体只有在调用函数的时候才会执行函数体 函数的调用过程(重点!) a.物...

  • 函数基础二

    一、函数的调用 函数在声明的时候不会执行函数体,只有调用函数的时候才会执行函数体 函数的调用过程(重点!)第一步:...

网友评论

      本文标题:golang函数调用的执行逻辑

      本文链接:https://www.haomeiwen.com/subject/wryhqctx.html