我正在使用 armcc 和 arm-gcc 来编译我的ARM968处理器项目。<登记/> 从函数调用返回时,返回的指令如下:
Pop {ri-rj, pc}
所有推送的寄存器都弹出在同一条指令中。我想将上面的说明改为这样的:
Pop {ri-rj}
Pop {pc}
使用Pop
时,是否可以指示汇编程序或编译器遵守上述任何ARM工具链中的规则?
答案 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