【发布时间】:2016-02-17 03:37:58
【问题描述】:
我有这个 C 代码:
void initPIO_Port(AT91S_PIO *port)
{
port->PIO_PER=1<<PIN;
port->PIO_OER=1<<PIN;
} // initPIO_Port
int main(void)
{
initPIO_Port(PORT);
/* Loop for ever */
while (1) {
...
};
}
由 arm-gcc 翻译成 ARM 程序集:
main:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 1, uses_anonymous_args = 0
@int main(void)
@{
@ initPIO_Port(PORT);
@ while (1) {
....
@ };
@}
stmfd sp!, {fp, lr}
add fp, sp, #4
ldr r0, .L13
bl initPIO_Port
.L12:
...
b .L12
initPIO_Port:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 8
@ frame_needed = 1, uses_anonymous_args = 0
@ link register save eliminated.
@ void initPIO_Port(AT91S_PIO *port)
str fp, [sp, #-4]!
add fp, sp, #0
sub sp, sp, #12 @ why subtract 12 - we're not using sp in following code ?
str r0, [fp, #-8] @ first empty place is at fp-8? fp points to last full location on stack - is this right ?
@ why is input parameter in r0 saved on stack and then read in r3 ?
ldr r3, [fp, #-8] @ port->PIO_PER=1<<PIN;
mov r2, #2
str r2, [r3, #0]
ldr r3, [fp, #-8] @ port->PIO_OER=1<<PIN;
mov r2, #2
str r2, [r3, #16]
add sp, fp, #0 @ previous value of sp
ldmfd sp!, {fp} @ restore fp
bx lr @ return
我无法理解 fp 和 sp 寄存器的行为:
为什么我从 sp 中减去 12 然后不使用它?为什么是 12?
fp寄存器的用途到底是什么?
为什么 r0 写入堆栈并读取到 r3 ?不是都用于输入参数吗?
感谢您的帮助,
问候,
罗伯。
【问题讨论】:
-
这是没有优化的吗?
-
未优化它将为传入的参数和中间值腾出空间(并且可能根据 abi 在两个字的边界上对齐)。 fp 是帧指针,烧录一个寄存器而不是使用 sp 来引用。并不少见,某些指令集需要。在这种情况下,它还保存了 sp 的值,因此您不必在后端进行数学运算,尽管即使在这种情况下也会更便宜。尝试优化。