告诉编译器以不同的方式翻译某条指令?

时间:2016-05-02 13:25:06

标签: c gcc arm embedded

我正在使用 armcc arm-gcc 来编译我的ARM968处理器项目。<登记/> 从函数调用返回时,返回的指令如下:

Pop {ri-rj, pc}

所有推送的寄存器都弹出在同一条指令中。我想将上面的说明改为这样的:

Pop {ri-rj}
Pop {pc}

使用Pop时,是否可以指示汇编程序或编译器遵守上述任何ARM工具链中的规则?

2 个答案:

答案 0 :(得分:4)

根据问题的确切性质,以及您是否严格依赖于少数新指令,可能编译ARMv4T的另一种可能性。在ARMv5T之前,ldm进入PC并不是互通,因此编译器不会为v4T目标发出这种形式的返回指令。对于一些简单的测试代码,使用-march=armv5t进行编译会生成一个堆栈帧:

   8:   e92d4070        push    {r4, r5, r6, lr}
...
  4c:   d8bd8070        pople   {r4, r5, r6, pc}

而用-march=armv4t编译相同的东西使用相同的序言,但使用间接返回序列(上面是循环内部的条件返回,现在它也移出到函数的末尾):< / p>

  48:   da000006        ble     68 <func+0x68>
...
  68:   e8bd4070        pop     {r4, r5, r6, lr}
  6c:   e12fff1e        bx      lr

当然,这是否与两个单独的pop有相同的效果取决于系统中的底层错误 - 如果它类似于ldm的数据提取和指令提取之间的时间。跳跃本身,那么这可能是相当的;可以想象它可能是一个完全不同的东西,比如一个破坏的内存系统将AHB突发截断到一定大小以上,所以它是单个ldm中传输的寄存器数量就是问题,但在这种情况下我也希望看到像memcpy这样的问题并不容易解决。

答案 1 :(得分:0)

你可以告诉gcc在生成汇编程序后停止处理。您可以手动或使用sed编辑汇编程序文件。然后将汇编程序文件从binutils传递给as,将其汇总到目标文件中。

$ cat test.c
#include <stdio.h>

int main(int argc, char *argv[])
{
        printf ("hello world\n");

        return 0;
}
$ gcc test.c -o test.s -S
cat test.s
        .file   "test.c"
        .section        .rodata
.LC0:
        .string "hello world"
        .text
        .globl  main
        .type   main, @function
main:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        subq    $16, %rsp
        movl    %edi, -4(%rbp)
        movq    %rsi, -16(%rbp)
        movl    $.LC0, %edi
        call    puts
        movl    $0, %eax
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE0:
        .size   main, .-main
        .ident  "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4"
        .section        .note.GNU-stack,"",@progbits
$ as test.s -o test.o