This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

What is different of the function call and return manner between  ARM Linux kernel and ARM applications?

Note: This was originally posted on 29th August 2012 at http://forums.arm.com

Hi,

When I disassamble the ARM Linux kernel for ARMv7(tegra 2),I found that a lot of function return using ldm command,just like   ldm sp,  {fp, sp, pc},but in the applications ( SPECCPU2006 for arm),the function return mostly using bx or b.Why that happened? Is the kernel Makefile used some gcc arguments that can lead the compiler to optimize the kernel?
  • Note: This was originally posted on 29th August 2012 at http://forums.arm.com

    I think it may just be the functions you looked at.

    There are several ways to return from a function in ARM/Thumb.  The most common (at least in my experience) are "BX lr" and "LDM sp!, {...., sp}".  Although the second one often gets written as "PUSH {....., pc}" depends on which tools you are using.  I suspect if you kept looking long enough you would find examples of each in both the kernel and the app.

    The "B ..." is a little more interesting.  I suspect that this is a compiler optimization called "tail calling" - again there is no reason why you this couldn't be present in both the kernel and the app.  http://en.wikipedia.org/wiki/Tail_call
  • Note: This was originally posted on 29th August 2012 at http://forums.arm.com

    Thank you very much.

    Besides that two ways you said,an uncommon way is :Mov pc,XX.  The compiler is not intelligent,so there must be reason using different ways to return.I guss it is determined by the function itself,maybe in the kernel functions there is some different declare manners.Thanks again.

    I think it may just be the functions you looked at.

    There are several ways to return from a function in ARM/Thumb.  The most common (at least in my experience) are "BX lr" and "LDM sp!, {...., sp}".  Although the second one often gets written as "PUSH {....., pc}" depends on which tools you are using.  I suspect if you kept looking long enough you would find examples of each in both the kernel and the app.

    The "B ..." is a little more interesting.  I suspect that this is a compiler optimization called "tail calling" - again there is no reason why you this couldn't be present in both the kernel and the app.  http://en.wikipedia.org/wiki/Tail_call
  • Note: This was originally posted on 29th August 2012 at http://forums.arm.com

    The reason why the compiler would use ldm instead of an instruction like bx lr or mov pc, lr is because lr was stored on the stack and needs to be restored from the stack. This will happen any time the function has to modify lr after it's called, which will occur if the function calls another function or if lr is allocated to a variable. The compiler is easily intelligent enough to distinguish between these cases.

    The difference between bx lr and mov pc, lr is that bx will switch you from ARM to Thumb mode or vice-versa depending on what the mode was when the function was called. mov can be used if it's known that the call didn't cause a mode switch, for instance if the entire program is ARM or Thumb. This might be preferable because it means the program could work on old ARM processors that don't support Thumb and therefore don't have the bx instruction.
  • Note: This was originally posted on 29th August 2012 at http://forums.arm.com

    One note....
    The rules changed in v7. Per-v7 data processing instructions couldn't cause a state (ARM/Thumb) change. So "mov pc, lr" couldn't return you a function in a different instruction set. From v7 onwards, any data processing instruction with the pc as the destination CAN change state. So  it now doesn't matter.