代码之家  ›  专栏  ›  技术社区  ›  Chan Kim

函数中的变量声明和外部变量声明中的内联汇编语句

  •  0
  • Chan Kim  · 技术社区  · 3 年前

    1. 变量声明末尾的asm语句是什么?
    2. 为什么在函数中声明extern变量?与在函数外声明相比,它有什么效果?
    extern unsigned char __heap_base;
    extern unsigned char __heap_limit;
    
    caddr_t _sbrk_r (struct _reent *r,int incr)
    {
    extern   unsigned char  __bottom_of_heap asm ("__heap_base");
    extern   unsigned char  __limit_of_heap  asm ("__heap_limit");
    register unsigned char *__stack_ptr  asm ("sp");
    ...
    }
    

    在另一个程序集文件中,\uuu heap\u base、\uu heap\u limit的定义如下(摘录)。

                    .global  __heap_base
                    .global  __heap_limit
    
    __user_thread_space:
                    .equ     __heap_base,  __user_thread_space + THREAD_AREA
                    .equ     __heap_limit, __heap_base         + HEAP_SIZE
    
    1 回复  |  直到 3 年前
        1
  •  0
  •   Peter Cordes    3 年前

    https://gcc.gnu.org/onlinedocs/gcc/Asm-Labels.html 正在为这些C变量设置asm符号名称。这使您可以设置asm名称,而不管编译器是否通常预先准备了额外的 _


    这个 register ... asm("regname") https://gcc.gnu.org/onlinedocs/gcc/Global-Register-Variables.html

    赋值给这个变量肯定会破坏一些东西,即使读取它也没有完全定义好/保证好的语义。当编译器修改SP本身以为局部变量留出空间时,请为具有大量参数的函数推送参数,或wrt。阿洛卡。例如,如果 CSE 属于 __stack_ptr alloca __stack_ptr = new_stack;


    请注意,asm关键字的这两种用法的语法本质上是相同的:这两种用法都在某种程度上告诉编译器:当您在正在生成的asm源中打印对该变量的引用时,请使用此名称(当然,它必须知道它是一个寄存器还是一个符号,尤其是在加载/存储机器上(不是CISC)。


    我假设只是为了限制这些声明的范围。

    在正常的isoc中,你可以 extern char bar; 在函数中,编译器将引用全局变量 bar gcc -Wall -Wextra -Wpedantic asm() 酒吧 作为asm符号名称: https://godbolt.org/z/j1KznMEPG. )

    (顺便说一句,a) static 函数中的var通常有一个包含函数名的asm名称,因此它不会与另一个函数中同名的静态var冲突。当然,这是 extern 静止的 ,因此使用普通的全局名称是有意义的。)