Stack overflow or some other weird thing after call of asm routine

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Stack overflow or some other weird thing after call of asm routine

Jump to solution
1,513 Views
gossamer69
Contributor III

I am using LPCXpresso v8.2.0 [Build 647] on Mac OS. My code is written in C++ and I am using asm routine for precise us delay. Processor is LPC54102.

For some reason after return from ASM call, my this pointer gets garbled, local member values are overwritten with some random values.

I am not sure if the problem is with ASM or some setting in IDE to enlarge stack size or ?

This code works fine on Cortex M3/M0 within the Keil IDE.  Havent tried it with M4 in Keil.

Stepping through the routine doesnt reveal anything until the "BX lr" code returns to C++ part of code, then my values are already overwritten.

void _delay_us (int a_us)

{

  asm(" CBZ R0, end");

  asm(" MOV R2, R0");

  asm("loop2:");

  asm(" MOV R1, #15");

  asm("loop:");

  asm(" NOP");

  asm(" NOP");

  asm(" NOP");

  asm(" NOP");

  asm(" SUB R1, R1, #1");

  asm(" CMP R1, #0");

  asm(" BNE loop");

  asm(" SUB R2, R2, #1");

  asm(" CMP R2, #0");

  asm(" BNE loop2");

  asm("end:");

  asm(" BX lr");

}

And any kind of delay will cause overwrite ...

For example:

  _delay_us(500);

Labels (1)
Tags (1)
0 Kudos
1 Solution
912 Views
lpcxpresso_supp
NXP Employee
NXP Employee

Try disassembling your function to see exactly what the compiler has generated:

Disassembling objects and executables

Given the way that you have written your function, the C compiler will also add function entry/exit code. My suspicion is therefore that your issue is being triggered by you writing:

asm(" BX lr");

If you remove that statement, then I suspect things will then work.

Regards,

LPCXpresso Support

View solution in original post

0 Kudos
5 Replies
912 Views
tomaskrysl
Contributor I

I would really recommend to avoid using assembly even in this case. Use normal C loop and NOP intrinsics to adjust the precise timing. If necessary modify compiler behavior with pragmas. Such code will be more portable. We do it this way. Of course you always have to check the generated code and measure its execution time (for every target and compiler).

0 Kudos
913 Views
lpcxpresso_supp
NXP Employee
NXP Employee

Try disassembling your function to see exactly what the compiler has generated:

Disassembling objects and executables

Given the way that you have written your function, the C compiler will also add function entry/exit code. My suspicion is therefore that your issue is being triggered by you writing:

asm(" BX lr");

If you remove that statement, then I suspect things will then work.

Regards,

LPCXpresso Support

0 Kudos
912 Views
gossamer69
Contributor III

That really did the trick. Thanks. I would never guess :smileyhappy:

So it branched to return address from my ASM code and then at the end of c routine it did it again but this time in some weird memory location ?

0 Kudos
912 Views
lpcxpresso_supp
NXP Employee
NXP Employee

Glad to hear this change fixed the problem for you. If you disassemble the function generated out of the compiler from your source, as I suggested before, you will see why. Your explicit return instruction caused your delay function to exit before the function exit code generated by the compiler was reached. Meaning the stack/registers were not restored before the return back to the caller. Hence the broken behaviour that you we seeing.

Regards,

LPCXpresso Support

0 Kudos
912 Views
gossamer69
Contributor III

Thank you for explaining. I will check the asm code as well.

0 Kudos