Consistant code

I tried to small program to see the code produced by the compiler.

This is the C code:
unsigned char loop;

while (1) {

P3 = 0xFF;

for(loop=0xff; loop>0; loop--) {}

P3 = 0x00;

for(loop=0xff; loop>0; loop--) {}

}

This is the disassembly:

25: unsigned char loop;

26:

27: while (1) {

28:

29: P3 = 0xFF;

C:0x0800 75B0FF MOV P3(0xB0),#0xFF

30: for(loop=0xff; loop>0; loop--) {}

C:0x0803 7FFF MOV R7,#0xFF

C:0x0805 DFFE DJNZ R7,C:0805

31: P3 = 0x00;

C:0x0807 E4 CLR A

C:0x0808 F5B0 MOV P3(0xB0),A

32: for(loop=0xff; loop>0; loop--) {}

C:0x080A 7FFF MOV R7,#0xFF

C:0x080C EF MOV A,R7

C:0x080D D3 SETB C

C:0x080E 9400 SUBB A,#0x00

C:0x0810 40EE JC main(C:0800)

C:0x0812 1F DEC R7

C:0x0813 80F7 SJMP C:080C

C:0x0815 787F MOV R0,#0x7F

C:0x0817 E4 CLR A

C:0x0818 F6 MOV @R0,A

C:0x0819 D8FD DJNZ R0,C:0818

C:0x081B 758107 MOV SP(0x81),#0x07

C:0x081E 020800 LJMP main(C:0800)

Why is the second timing loop so different than the first ??

What can I do so both are the same ???

Thank you

Donald

Parents
  • I have a few questions too. Here is an example where the ARM compiler changes low level assembly code. I was merging in some optimized assembler code generated by a Forth compiler, this went fine until I realized that it was running 20-30% slower than expected. I eventually realized that the ARM compiler was ignoring the assembly code instructions and using its own code versions. Here is an example followed by two resulting code outputs using different optimization settings. Can someone explain this. I would have thought any assembly code should just be assembled and not altered?

    Also the compiler seems to ignore the __inline command and still makes one code section and inserts call-returns. So the question is there a way to force the __inline to really do it?

    I found that I had to use the __inline for any assembly code put in a .h (header) file. If I didn't I got "error L6200E: symbol Delay multiply defined by main.o and xcee.o" - Why is this? I think multiply means multiple?
    . .

    #pragma arm
    __inline void Delay(uint32_t loops)
    {
    __asm {
    loop1:  SUBS loops, loops, #1    // 1 cycle
                    BNE loop1        // 3 cycles true, 1 cycle false
          }
    }
    #pragma thumb
    #endif
    

    optimization (level=3) correct.

       116: loop1:  SUBS loops, loops, #1     // 1 cycle
       117:                 BNE loop1         // 3 cycles true, 1 cycle false
       118:       }
    0x00000464  E2500001  SUBS      R0,R0,#0x00000001
    0x00000468  1AFFFFFD  BNE       Delay4(0x00000464)
       119: }
    0x0000046C  E12FFF1E  BX        R14
    0x00000470  4778      BX        PC
    

    optimization (level=0) adds two extra instructions

       116: loop1:  SUBS loops, loops, #1     // 1 cycle
    0x00000464  E1A00000  NOP
    0x00000468  E2500001  SUBS      R0,R0,#0x00000001
    0x0000046C  0A000000  BEQ       0x00000474
       117:                 BNE loop1                 // 3 cycles true, 1 cycle false
       118:       }
    0x00000470  EAFFFFFC  B         0x00000468
       119: }
    0x00000474  E12FFF1E  BX        R14
    0x00000478  4778      BX        PC
    

Reply
  • I have a few questions too. Here is an example where the ARM compiler changes low level assembly code. I was merging in some optimized assembler code generated by a Forth compiler, this went fine until I realized that it was running 20-30% slower than expected. I eventually realized that the ARM compiler was ignoring the assembly code instructions and using its own code versions. Here is an example followed by two resulting code outputs using different optimization settings. Can someone explain this. I would have thought any assembly code should just be assembled and not altered?

    Also the compiler seems to ignore the __inline command and still makes one code section and inserts call-returns. So the question is there a way to force the __inline to really do it?

    I found that I had to use the __inline for any assembly code put in a .h (header) file. If I didn't I got "error L6200E: symbol Delay multiply defined by main.o and xcee.o" - Why is this? I think multiply means multiple?
    . .

    #pragma arm
    __inline void Delay(uint32_t loops)
    {
    __asm {
    loop1:  SUBS loops, loops, #1    // 1 cycle
                    BNE loop1        // 3 cycles true, 1 cycle false
          }
    }
    #pragma thumb
    #endif
    

    optimization (level=3) correct.

       116: loop1:  SUBS loops, loops, #1     // 1 cycle
       117:                 BNE loop1         // 3 cycles true, 1 cycle false
       118:       }
    0x00000464  E2500001  SUBS      R0,R0,#0x00000001
    0x00000468  1AFFFFFD  BNE       Delay4(0x00000464)
       119: }
    0x0000046C  E12FFF1E  BX        R14
    0x00000470  4778      BX        PC
    

    optimization (level=0) adds two extra instructions

       116: loop1:  SUBS loops, loops, #1     // 1 cycle
    0x00000464  E1A00000  NOP
    0x00000468  E2500001  SUBS      R0,R0,#0x00000001
    0x0000046C  0A000000  BEQ       0x00000474
       117:                 BNE loop1                 // 3 cycles true, 1 cycle false
       118:       }
    0x00000470  EAFFFFFC  B         0x00000468
       119: }
    0x00000474  E12FFF1E  BX        R14
    0x00000478  4778      BX        PC
    

Children
More questions in this forum