zoukankan      html  css  js  c++  java
  • ARM栈帧与编译选项

    看到一篇文章《冬之焱:谈谈Linux内核的栈回溯与妙用》,来自微信公众号"Linux阅码场"。文章主要写了Linux Backtrace的方法,里面提到ARM栈时,有这么一个图:

    文章认为除了unwind模式,arm函数调用后都会压入PC,LR,SP,FP(即R15,R14,R13,R11)几个寄存器;但是,在平常ARM汇编代码中,很少能看到函数调用会压栈这么多寄存器。

    实际上,压栈哪些寄存器,很大程度上是由编译选项决定的,下面是相关验证。代码很简单,就是在main 函数中调用了zperf_main进行测试:

    1. gcc默认编译,无任何选项:

     arm-linux-gnueabi-gcc -o test test.c

    压栈了寄存器R4,R11和R14,R4为zperf_main函数中会改变的通用寄存器,R11作为FP指针使用(程序中不会改变),R14作为LR。

    2.  加编译选项 -O0

    与不加选项完全一致,说明不加选项默认就是O0优化

    3.  加编译选项 -O1 或者编译选项-O(两者一致)

     arm-linux-gnueabi-gcc -O1 -o test1 test.c

    压栈了寄存器R3-R11和R14,此时R14作为LR保存,R3-R11都是作为通用寄存器保存,R11并不作为FP,可以看到后面程序会将它作为通用寄存器使用。

    4.  加编译选项 -O2

     arm-linux-gnueabi-gcc -O2 -o test2 test.c

    压栈了寄存器R3-R10和R14,此时R14作为LR保存,R3-R10都是作为通用寄存器保存,相比O1优化了R11的保存恢复。

    5.  加编译选项 -O3

     arm-linux-gnueabi-gcc -O3 -o test3 test.c

    由于程序比较简单,编译后与O2完全一致。

    6.  加编译选项 -fomit-frame-pointer

    该选项的作用,在gcc手册中是这么描述的:

    Don't keep the frame pointer in a register for functions that don't need one. This avoids the instructions to save, set up and restore frame pointers; it also makes an extra register available in many functions. It also makes debugging impossible on some machines。

    简单来说就是通过不保存FP来优化程序性能。

    arm-linux-gnueabi-gcc -fomit-frame-pointer -o testf test.c

    与不开优化选项的程序相比,可以看到这段代码已不再保存FP。

    事实上gcc的所有级别的优化(-O1, -O2, -O3等)都会打开-fomit-frame-pointer,该选项的功能是函数调用时不保存frame指针,在ARM上就是fp,故我们无法按照APCS中的约定来回溯调用栈。但是GDB中仍然可以使用bt命令看到调用栈,为什么?得知GDB v6之后都是支持DWARF2的,也就意味着它可以不依赖fp来回溯调用栈(详见http://gcc.gnu.org/ml/gcc/2003-10/msg00322.html)。

    7.  加编译选项 -mapcs

     arm-linux-gnueabi-gcc -mapcs -o testm test.c

    这个选项使程序严格遵守ARM Procedure Call Standard(ARM过程调用标准规范)中关于arm寄存器的使用、过程调用时出栈和入栈的约定。

    可以看到,此时程序才严格按照图1的规律,每个函数调用都会压栈PC,LR,SP,FP作为寄存器栈帧进行保存。

  • 相关阅读:
    bom案例2-弹出层
    bom案例1-div拖拽
    bom-scroll
    bom-client
    bom-offset
    9. 阻塞队列
    8. 读写锁
    7. CountDownLatch、CyclicBarrier、Semaphore
    6. Callable
    5. 集合不安全
  • 原文地址:https://www.cnblogs.com/DF11G/p/9706063.html
Copyright © 2011-2022 走看看