0

I am trying to use inline assembly for an ARM C code. My 'main.c' code looks something like this:

...
void jump()
{
  __asm
  {
    B  0x15000
  }
}


INT32 main(void)
{
  ...
  Write val1 into register 1
  jump();
  Write val2 into register 2
  ...
}

When I run this code I expect that val1 to be written in register 1, and then jump to address 0x15000 happens and there is nothing written in register 2. But when I look at register 1 and register 2 both have been written with val1 and val2. So it seems the jump() does not take place. Am I missing something?

Update 1

As suggested in the comments, I created a minimum reproducible example which is:

void jump()
  {
    __asm
    {
      B  0x15000
    }
  }

int main(void)
{  
  int i, j, k;
  i = 1;
  jump();
  j = 2;
  k = i + j;
  return 128;
}

when I compile it with armcc --asm main.c I get this as main.s:

        ARM
        REQUIRE8
        PRESERVE8

        AREA ||.text||, CODE, READONLY, ALIGN=2

jump PROC
        BX       lr
        ENDP

main PROC
        MOV      r0,#0x80
        BX       lr
        ENDP


        AREA ||.arm_vfe_header||, DATA, READONLY, NOALLOC, ALIGN=2

        DCD      0x00000000

so it looks like the jump() is optimized out? What is that and how can I prevent it?

Update 2

I even tried adding the volatile before the function name as:

 volatile void jump()
  {
    __asm
    {
      B  0x15000
    }
  }

but it didn't help and the jump() function is optimized out.

TJ1
  • 7,578
  • 19
  • 76
  • 119
  • Use a debugger, step through assembly instructions. Or for starters at least look at the compiled assembly. – Eugene Sh. Sep 03 '21 at 16:52
  • @EugeneSh. unfortunately I don't have access to a debugger, and am a beginner. Just looking at what I am doing do you see anything wrong? – TJ1 Sep 03 '21 at 17:07
  • Create an [mcve] so we could compile it and look at the generated assemly. – Eugene Sh. Sep 03 '21 at 17:09
  • Would something like this be good enough: INT32 main(void) { void jump() { __asm { B 0x15000 } } int i, j; i = 0; j = 0; i = 1; jump(); j = 2; } – TJ1 Sep 03 '21 at 17:16
  • Do you have compiler optimizations turned on? i and j are maybe being set to 1 and 2 when initialized. – Humberto Gomes Sep 03 '21 at 17:18
  • This syntax does not seem to be accepted by ARM GCC: https://godbolt.org/z/anhGYcnMe – Eugene Sh. Sep 03 '21 at 17:21
  • @HumbertoGomes maybe compiler optimization is turned on, could that cause the jump() to be eliminated? – TJ1 Sep 03 '21 at 17:24
  • @EugeneSh. I am using armcc. – TJ1 Sep 03 '21 at 17:25
  • 1
    Then just compile it yourself and post the assembly here. armcc is proprietary and not commonly available. – Eugene Sh. Sep 03 '21 at 17:28
  • @EugeneSh. sorry I had a mistake in the code, this one shall work with ARM GCC : void jump() { __asm { B 0x15000 } } int main(void) { int i, j, k; i = 0; j = 0; i = 1; jump(); j = 2; k = i + j; return 128; } – TJ1 Sep 03 '21 at 17:46
  • @TJ1, compiler optimization wouldn't delete the jump instruction, but it may change the order things are executed. For example, you say j = 0, jump and then say j = 2. The compiler somtimes isn't very good with assembly and think that the jump() function doesn't do anything. So, it optimizes your code like this: i = 0; j = 2; jump(); This is just a possibility and may not be the case. – Humberto Gomes Sep 03 '21 at 18:14
  • GCC -O1 ignores the variables completely. If you write `return i + j` GCC transforms it into what would be `return 3`: https://godbolt.org/z/ra3TeavbW – Humberto Gomes Sep 03 '21 at 18:19
  • 1
    If you don't have a debugger, that's your number 1 problem. You should fix that. (Even if just in a simulator, not on your real hardware). Many problems in asm become a lot more obvious when you single-step and watch register values change. (Although in this case, looking at the compiler's asm output may be sufficient.) – Peter Cordes Sep 03 '21 at 18:43
  • @EugeneSh. I just did and posted the assembly, it looks like jump() is optimized out, what can I do? – TJ1 Sep 03 '21 at 18:48
  • Interesting. Which version of armcc do you use? In fact I see that the call to `jump` was optimized out as well. – Eugene Sh. Sep 03 '21 at 18:50
  • I use version 5.01 of armcc. – TJ1 Sep 03 '21 at 18:53
  • @PeterCordes that is a great comment. Would you mind look at the asm output and tell me why the jump is optimized out and what can be done? – TJ1 Sep 03 '21 at 19:00
  • I don't know how ARMCC inline asm works, or whether it has any equivalent of GNU C `asm volatile` vs. just plain `asm`. In GNU C inline, it's generally not safe to jump out of an asm statement either, but maybe ARMCC is different. – Peter Cordes Sep 03 '21 at 19:35
  • 1
    FWIW v5.01 is quite buggy. v5.06 is backwards compatible and is fixing many bugs. Also it is using same license, so better move to it.. – Eugene Sh. Sep 03 '21 at 20:16
  • 1
    I'm not surprised `volatile void jump()` did nothing. If it's not already implicit for an `asm {}` block instead of GNU C style `asm("template" :outputs : inputs : clobbers)`, you'd need to apply it to the `asm` keyword, not the function containing it. `volatile void foo()` doesn't mean "don't optimize this function". – Peter Cordes Sep 03 '21 at 20:28
  • @PeterCordes thanks for your help. I tried to put volatile after `__asm` as `__asm volatile` and it didn't do anything. Tried to add it before as `volatile __asm` and it gave me error. Any idea of how shall I do that? – TJ1 Sep 03 '21 at 20:42
  • Have you tried using the volatile keyword with the inline assembly? The compiler might decide to optimize the assembly away if you don't add it – fangenoorth Sep 03 '21 at 17:32
  • Can you please be more specific? How do I do that? – TJ1 Sep 03 '21 at 17:37
  • Well I am not familiar with the syntax of armcc, but i would guess it goes either right in front or after the __asm, [check the docs here](https://developer.arm.com/documentation/100748/0606/ddx1471430827125) – fangenoorth Sep 03 '21 at 17:42
  • I tried that if I put after it doesn't do anything and if I put before it gives me error. – TJ1 Sep 03 '21 at 20:59

0 Answers0