Bu kod (kol) bağlı olarak farklı bir kod oluşturur:GCC dizi endeks değeri
void blinkRed(void)
{
for(;;)
{
bb[0x0008646B] ^= 1;
sys.Delay_ms(14);
}
}
... asm-kod folowing derlenmiş:
08000470: ldr r4, [pc, #20] ; (0x8000488 <blinkRed()+24>) // r4 = 0x422191ac
08000472: ldr r6, [pc, #24] ; (0x800048c <blinkRed()+28>)
08000474: movs r5, #14
08000476: ldr r3, [r4, #0]
08000478: eor.w r3, r3, #1
0800047c: str r3, [r4, #0]
0800047e: mov r0, r6
08000480: mov r1, r5
08000482: bl 0x80001ac <CSTM32F100C6::Delay_ms(unsigned int)>
08000486: b.n 0x8000476 <blinkRed()+6>
It is ok. Sadece dizi indeksi (-0x400
) değiştirirseniz
Ama ....
void blinkRed(void)
{
for(;;)
{
bb[0x0008606B] ^= 1;
sys.Delay_ms(14);
}
}
... bende bu yüzden optimize edilmemiş kod:
08000470: ldr r4, [pc, #24] ; (0x800048c <blinkRed()+28>) // r4 = 0x42218000
08000472: ldr r6, [pc, #28] ; (0x8000490 <blinkRed()+32>)
08000474: movs r5, #14
08000476: ldr.w r3, [r4, #428] ; 0x1ac
0800047a: eor.w r3, r3, #1
0800047e: str.w r3, [r4, #428] ; 0x1ac
08000482: mov r0, r6
08000484: mov r1, r5
08000486: bl 0x80001ac <CSTM32F100C6::Delay_ms(unsigned int)>
0800048a: b.n 0x8000476 <blinkRed()+6>
fark içinde olmasıdır ilk durumda r4
hedef adresi ile hemen yüklenir (0x422191ac
) ve daha sonra bellek 2 bayt yönergeleri ile gerçekleştirilir, ancak ikinci durumda r4
bazı ara adresi ile yüklenir (0x42218000
) ve ardından belleğe erişim, hedef adresi (0x422181ac
) ile ofset (+0x1ac
) ile 4 baytlık komutla gerçekleştirilir.
Neden derleyici böyle yapar?
kullanmak: arm-none-eabi-g++ -mcpu=cortex-m3 -mthumb -g2 -Wall -O1 -std=gnu++14 -fno-exceptions -fno-use-cxa-atexit -fstrict-volatile-bitfields -c -DSTM32F100C6T6B -DSTM32F10X_LD_VL
bb
olup: içinde MEMORY
bölüm:
BITBAND(rwx): ORIGIN = 0x42000000, LENGTH = 0x02000000
SECTIONS
bölümünde: .ld
olarak
__attribute__ ((section(".bitband"))) volatile u32 bb[0x00800000];
bu gibi tanımlanmıştır
.bitband (NOLOAD) :
SUBALIGN(0x02000000)
{
KEEP(*(.bitband))
} > BITBAND
Ummm ... bunun ilgili olup olmadığından emin değilsiniz, ancak ... optimize edilmiş sürüm de işe yarayacak mı? Belki daha hızlı yük için bazı önkoşullar vardır.Bu bilgi, optimize edicinin problemi mi, yoksa mimariyle mi ilgili olduğunu gösterir. – luk32
Her iki sürüm de çalışır. Bir örnekte mevcut olan ve diğerlerinde mevcut olmayan herhangi bir önkoşul hayal edemiyorum. İndeks adım adım değiştirdim ve dizi endeksi 0x00086020 - 0x000863FF arasındaysa ikinci sürümün derlendiğini öğrendim. Dizi dizini bu aralığın dışındaysa, ilk (en iyileştirilmiş) sürüm derlenir. – Woodoo
Ne tür ARM? Muhtemelen bir bellek hizalama sorunu. – Unimportant