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

为什么编译器可以假设全局变量的地址适合32位[[副本]

  •  4
  • ead  · 技术社区  · 6 年前

    查看汇编程序时(请参见上的 godbolt.org

    extern int global;
    void doit(int *);
    void call_doit(){
        doit(&global);
    }
    

    32位值用于保存 global

    call_doit:
            movl    $global, %edi
            jmp     doit
    

    我知道,使用32位寄存器(即。 %edi )这里优于64位寄存器(即。 %rdi movl $global, %edi 需要5个字节 movq $global, %rdi 需要7个字节+4个额外的字节,如果你不认为 $global 适合32位)。

    lea global(%rip), %rdi 从RIP+32位相对位移创建一个64位地址,由于相关原因,编译器可以假定它在范围内。以及 movabs $global, %rdi

    但是为什么编译器可以假设全局变量的地址适合这32位呢?编译器有什么保证?


    对于局部变量,编译器使用64位寄存器来保存堆栈地址,例如:

    void doit(int *);
    void call_doit(){
        int local=0;
        doit(&local);
    }
    

    结果(请参见上的 godbolt.org ):

    call_doit:
            subq    $24, %rsp
            leaq    12(%rsp), %rdi
            movl    $0, 12(%rsp)
            call    doit
            addq    $24, %rsp
            ret
    
    0 回复  |  直到 6 年前