Skip to main content
added 276 characters in body
Source Link
Amomum
  • 705
  • 1
  • 7
  • 14

I'm interested, why for Cortex M3 microcontroller (stm32f103) compiler sometimes generates a NOP instruction after branch. And why it sometimes doesn't.

For example:

0x08000496 2400      MOVS     r4,#0x00
0x08000498 4625      MOV      r5,r4
0x0800049A E006      B        0x080004AA
    64: res=res+a[i];
    65: }
0x0800049C F85A0034  LDR      r0,[r10,r4,LSL #3] // No NOP after B
0x080004A0 EB100808  ADDS     r8,r0,r8
0x080004A4 1C64      ADDS     r4,r4,#1
0x080004A6 F1450500  ADC      r5,r5,#0x00
0x080004AA 1BA0      SUBS     r0,r4,r6
0x080004AC EB750007  SBCS     r0,r5,r7
0x080004B0 DBF4      BLT      0x0800049C
    66: int64_t avg=res/x;
0x080004B2 BF00      NOP      // <------------------- NOP after BLT
    69: int v=countbits1(5);
0x080004B4 2005      MOVS     r0,#0x05
0x080004B6 F7FFFFA2  BL.W     countbits1 (0x080003FE)
0x080004BA 9001      STR      r0,[sp,#0x04]     // No NOP after BL.W
    72: unsigned int b=countLeadingZeros(5);
    73:  
0x080004BC 2005      MOVS     r0,#0x05

My initial guess was that long instruction needs word-alignment but BL.W after NOP actually doesn't have it. If this NOP is related to pipeline somehow than why there are branches without nop's after them?

I'm confused.

UPDATE:

It turns out that branch may be not relevant at all. I tried to moving declaration of unused local variable int64_t avg - and NOP moved along with it. So I beleive pjc50 comment is right and this NOP is there just to let debugger put a breakpoint on this line.

I'm interested, why for Cortex M3 microcontroller (stm32f103) compiler sometimes generates a NOP instruction after branch. And why it sometimes doesn't.

For example:

0x08000496 2400      MOVS     r4,#0x00
0x08000498 4625      MOV      r5,r4
0x0800049A E006      B        0x080004AA
    64: res=res+a[i];
    65: }
0x0800049C F85A0034  LDR      r0,[r10,r4,LSL #3] // No NOP after B
0x080004A0 EB100808  ADDS     r8,r0,r8
0x080004A4 1C64      ADDS     r4,r4,#1
0x080004A6 F1450500  ADC      r5,r5,#0x00
0x080004AA 1BA0      SUBS     r0,r4,r6
0x080004AC EB750007  SBCS     r0,r5,r7
0x080004B0 DBF4      BLT      0x0800049C
    66: int64_t avg=res/x;
0x080004B2 BF00      NOP      // <------------------- NOP after BLT
    69: int v=countbits1(5);
0x080004B4 2005      MOVS     r0,#0x05
0x080004B6 F7FFFFA2  BL.W     countbits1 (0x080003FE)
0x080004BA 9001      STR      r0,[sp,#0x04]     // No NOP after BL.W
    72: unsigned int b=countLeadingZeros(5);
    73:  
0x080004BC 2005      MOVS     r0,#0x05

My initial guess was that long instruction needs word-alignment but BL.W after NOP actually doesn't have it. If this NOP is related to pipeline somehow than why there are branches without nop's after them?

I'm confused.

I'm interested, why for Cortex M3 microcontroller (stm32f103) compiler sometimes generates a NOP instruction after branch. And why it sometimes doesn't.

For example:

0x08000496 2400      MOVS     r4,#0x00
0x08000498 4625      MOV      r5,r4
0x0800049A E006      B        0x080004AA
    64: res=res+a[i];
    65: }
0x0800049C F85A0034  LDR      r0,[r10,r4,LSL #3] // No NOP after B
0x080004A0 EB100808  ADDS     r8,r0,r8
0x080004A4 1C64      ADDS     r4,r4,#1
0x080004A6 F1450500  ADC      r5,r5,#0x00
0x080004AA 1BA0      SUBS     r0,r4,r6
0x080004AC EB750007  SBCS     r0,r5,r7
0x080004B0 DBF4      BLT      0x0800049C
    66: int64_t avg=res/x;
0x080004B2 BF00      NOP      // <------------------- NOP after BLT
    69: int v=countbits1(5);
0x080004B4 2005      MOVS     r0,#0x05
0x080004B6 F7FFFFA2  BL.W     countbits1 (0x080003FE)
0x080004BA 9001      STR      r0,[sp,#0x04]     // No NOP after BL.W
    72: unsigned int b=countLeadingZeros(5);
    73:  
0x080004BC 2005      MOVS     r0,#0x05

My initial guess was that long instruction needs word-alignment but BL.W after NOP actually doesn't have it. If this NOP is related to pipeline somehow than why there are branches without nop's after them?

I'm confused.

UPDATE:

It turns out that branch may be not relevant at all. I tried to moving declaration of unused local variable int64_t avg - and NOP moved along with it. So I beleive pjc50 comment is right and this NOP is there just to let debugger put a breakpoint on this line.

Tweeted twitter.com/#!/StackElectronix/status/527324289519730688
Source Link
Amomum
  • 705
  • 1
  • 7
  • 14

NOP instruction after branch on ARMv7 Cortex M3

I'm interested, why for Cortex M3 microcontroller (stm32f103) compiler sometimes generates a NOP instruction after branch. And why it sometimes doesn't.

For example:

0x08000496 2400      MOVS     r4,#0x00
0x08000498 4625      MOV      r5,r4
0x0800049A E006      B        0x080004AA
    64: res=res+a[i];
    65: }
0x0800049C F85A0034  LDR      r0,[r10,r4,LSL #3] // No NOP after B
0x080004A0 EB100808  ADDS     r8,r0,r8
0x080004A4 1C64      ADDS     r4,r4,#1
0x080004A6 F1450500  ADC      r5,r5,#0x00
0x080004AA 1BA0      SUBS     r0,r4,r6
0x080004AC EB750007  SBCS     r0,r5,r7
0x080004B0 DBF4      BLT      0x0800049C
    66: int64_t avg=res/x;
0x080004B2 BF00      NOP      // <------------------- NOP after BLT
    69: int v=countbits1(5);
0x080004B4 2005      MOVS     r0,#0x05
0x080004B6 F7FFFFA2  BL.W     countbits1 (0x080003FE)
0x080004BA 9001      STR      r0,[sp,#0x04]     // No NOP after BL.W
    72: unsigned int b=countLeadingZeros(5);
    73:  
0x080004BC 2005      MOVS     r0,#0x05

My initial guess was that long instruction needs word-alignment but BL.W after NOP actually doesn't have it. If this NOP is related to pipeline somehow than why there are branches without nop's after them?

I'm confused.