avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-gcc-list] alloca() and stack frame


From: Jan Waclawek
Subject: [avr-gcc-list] alloca() and stack frame
Date: Fri, 14 May 2010 11:44:37 +0200

In a function using alloca(), I've noticed the following prologue:

    128e:       6f 92           push    r6
    1290:       7f 92           push    r7
[etc.]
    12a6:       df 93           push    r29
    12a8:       cf 93           push    r28
    12aa:       cd b7           in      r28, 0x3d       ; 61
    12ac:       de b7           in      r29, 0x3e       ; 62
    12ae:       2f 97           sbiw    r28, 0x0f       ; 15
    12b0:       0f b6           in      r0, 0x3f        ; 63
    12b2:       f8 94           cli
    12b4:       de bf           out     0x3e, r29       ; 62
    12b6:       0f be           out     0x3f, r0        ; 63
    12b8:       cd bf           out     0x3d, r28       ; 61
[
    12ba:       6b 83           std     Y+3, r22        ; 0x03
    12bc:       5d 83           std     Y+5, r21        ; 0x05
    12be:       4c 83           std     Y+4, r20        ; 0x04
    12c0:       70 2e           mov     r7, r16
]
    12c2:       ed b6           in      r14, 0x3d       ; 61
    12c4:       fe b6           in      r15, 0x3e       ; 62
    12c6:       ff 82           std     Y+7, r15        ; 0x07
    12c8:       ee 82           std     Y+6, r14        ; 0x06

What happens here after the push-es is, that due to heavy register usage a 
stack frame (of size 0x0f) is allocated, [then some of the passed parameters 
are moved around] and base register-pair Y is set up for the frame; then the 
stack pointer (SP) is stored to the stack frame, apparently in anticipation of 
alloca(), to be able to restore the SP automagically when the function is 
finished.

The corresponding epilogue is:

    15fc:       ee 81           ldd     r30, Y+6        ; 0x06
    15fe:       ff 81           ldd     r31, Y+7        ; 0x07
    1600:       0f b6           in      r0, 0x3f        ; 63
    1602:       f8 94           cli
    1604:       fe bf           out     0x3e, r31       ; 62
    1606:       0f be           out     0x3f, r0        ; 63
    1608:       ed bf           out     0x3d, r30       ; 61
    160a:       2f 96           adiw    r28, 0x0f       ; 15
    160c:       0f b6           in      r0, 0x3f        ; 63
    160e:       f8 94           cli
    1610:       de bf           out     0x3e, r29       ; 62
    1612:       0f be           out     0x3f, r0        ; 63
    1614:       cd bf           out     0x3d, r28       ; 61
    1616:       cf 91           pop     r28
    1618:       df 91           pop     r29
[etc.]
    162e:       7f 90           pop     r7
    1630:       6f 90           pop     r6
    1632:       08 95           ret

Things go in the reverse order as they supposed to go: first space allocated by 
alloca() is released through restoring SP from the stack frame, then stack 
frame is deallocated by adding the size to Y and storing to SP.

Now, in this case (stack frame created), one of these is redundant.

As an optimisation, I would suggest to not to store/restore SP because of 
alloca(), if stack frame is created. Besides some speed and code memory gain, 
two bytes of the precious RAM/stack is gained, too.

Does this make sense? Could some of the insiders (and others, of course) please 
comment?

Jan Waclawek




reply via email to

[Prev in Thread] Current Thread [Next in Thread]