代码之家  ›  专栏  ›  技术社区  ›  Sam

了解go工具编译和链接命令

  •  1
  • Sam  · 技术社区  · 7 年前

    我知道将高级语言代码转换为机器语言或可执行代码需要三个步骤,即编译、组装和链接。

    根据go文件 go工具编译 是否执行以下操作- It then writes a single object file named for the basename of the first source file with a .o suffix

    因此,最终的目标文件必须包含每个文件的机器语言代码(编译和组装运行后)。如果我通过 go工具编译-S 在go文件中,它显示了汇编语言go生成的。

    之后当我跑步的时候 在目标文件上,它必须链接所有必需的目标文件(如果有多个),然后生成最终的机器语言代码(基于GOOS和GOARCH)。它生成一个文件 a、 退出

    这里有几个基本问题-

    我如何知道哪些变量以及何时在堆栈和堆中分配内存?如果我为一台机器生成可执行文件并在另一台具有不同架构的机器上运行,这有关系吗?

    我的测试程序

    package main
    
    func f(a *int, b *int) *int { 
    
        var c = (*a + *b); 
        var d = c;
        return &d;
    }
    
    func main() {
        var a = 2;
        var b = 6;
    
        f(&a,&b);
    }
    

    的结果

    test.go:6: moved to heap: d
    test.go:7: &d escapes to heap
    test.go:3: f a does not escape
    test.go:3: f b does not escape
    test.go:14: main &a does not escape
    test.go:14: main &b does not escape
    
    1 回复  |  直到 7 年前
        1
  •  4
  •   Rotem jackoby    6 年前

    内存是在哪一步分配的?

    它取决于,一些在链接期间,一些在编译期间,大多数在运行时(一些在加载期间)。

    我如何知道哪些变量以及何时在堆栈和堆中分配内存?

    你根本不知道。编译器决定了这一点。如果编译器可以证明变量没有转义,它可能会将其保留在堆栈上。谷歌搜索“golang escape analysis”。如果您感兴趣,有一个标志-m使编译器输出其决策。

    如果我为一台机器生成可执行文件并在另一台具有不同架构的机器上运行,这有关系吗?

    不,只是因为这根本不起作用:可执行文件与架构相关,不会在不同的架构上运行。