Derleyici neden doğrudan LSR kullanmıyor


10

Merhaba ben zamanlama oldukça önemli bir Arduino Uno (böylece ATmega328p) kullanarak bir proje üzerinde çalışıyorum ve bu yüzden derleyici kodumu dönüştürmek hangi talimatları içine görmek istedim. Ve orada uint8_tkullanarak her yineleme üzerinde bir bit sağa biraz kaydırmak var data >>= 1ve derleyici 5 talimatları ( dataiçinde r24) tercüme gibi görünüyor :

mov     r18, r24
ldi     r19, 0x00
asr     r19
ror     r18
mov     r24, r18

Ancak talimat kümesi belgelerine bakarsanız, tam olarak bunu yapan bir talimat görüyorum: lsr r24

Bir şeyi gözden kaçırıyor muyum veya derleyici bunu neden kullanmıyor? Kayıtlar r18ve r19başka hiçbir yerde kullanılmaz.

Bir Ardunio kullanıyorum ama eğer doğruysam normal avr-gccderleyiciyi kullanıyor. Diziyi oluşturan kod (kesilmiş):

ISR(PCINT0_vect) {
    uint8_t data = 0;
    for (uint8_t i = 8; i > 0; --i) {
//        asm volatile ("lsr %0": "+w" (data));
        data >>= 1;
        if (PINB & (1 << PB0))
            data |= 0x80;
    }
    host_data = data;
}

Görebildiğim kadarıyla Ardunino IDE, 6.2.0-1.fc24 sürümü olan sistem tarafından sağlanan AVR gcc derleyicisini kullanıyor. Her ikisi de paket yöneticisi aracılığıyla kurulur, bu nedenle güncel olmalıdır.


1
Derleme C koduna karşılık gelmiyor gibi görünüyor.
Eugene Sh.

Ardunio IDE kullanarak derledim ve sonra avr-objdumpelf dosyasında kullandım… Karşılık gelen gibi değil mi?
xZise

1
@Eugene Sh .: O does C koduna denk düşmektedir. Sadece çizgiye karşılık geliyordata >>= 1;
Curd

1
Bu, "bölünme yerine vardiya kullan" ın yanlış tavsiye olduğu durumlardan biridir. / = 2 yaparsanız derleyici lsr r24 üretir; (ipucu: asm kod üretimi ile oynamak için gcc explorer deneyin)
PlasmaHH

Ne derleyicisi? Ne işlemcisi? Sorunun anlamlı olması için bunun gerekli bilgi olduğu gerçekten açık olmalıdır.
Olin Lathrop

Yanıtlar:


18

C dili spesifikasyonuna göre, boyutu herhangi bir işlemde (sizin durumunuzda ) boyutundan daha küçük olan int(belirli bir derleyiciye bağlıdır; sizin durumunuzda int16 bit genişliğindedir) herhangi bir değer işlemden önce >>bir atılır int.
Derleyicinin bu davranışına tamsayı yükseltme denir .

Derleyici de aynen bunu yaptı:

  • r19 = 0, tamsayısının desteklediği değerin MSByte değeridir data.
  • (r19, r18), bunun tamsayı ile yükseltilmiş toplam değerini temsil eder ve datadaha sonra asr r19ve tarafından bir bit sağa kaydırılır ror 18.
  • Sonuç daha sonra uint8_tdeğişkeninize geri döndürülür data:
    mov r24, r18yani r19'daki MSByte atılır.

Düzenleme:
Tabii ki complier kodu optimize edebilir .
Sorunu yeniden oluşturmaya çalışırken en azından avr-gcc sürüm 4.9.2 ile sorunun oluşmadığını gördüm. Çok verimli bir kod oluşturur, yani C-satırı data >>= 1;tek bir lsr r24komutla derlenir . Belki de çok eski bir derleyici sürümü kullanıyorsunuzdur.


2
Toplam bir atık değildir, çünkü bazen montajcı düzeyinde hata ayıklama için optimize edilmemiş koda ihtiyacınız vardır. O zaman optimize edilmemiş bir kodunuz varsa çok memnunuz.
Lor

3
Doğru hatırlıyorsam -mint8 8-tamsayılar yapmak için bayraktır. Ancak bunun istenmeyen birçok yan etkisi vardır. Üzgünüm, şu an ne olduklarını tam olarak hatırlayamıyorum, ama onlar yüzünden bayrağı hiç kullanmadım. Yıllar önce avr-gcc'yi ticari bir derleyici ile karşılaştırmak için çok zaman harcadım.
Jon

1
Doğru, C standardı tamsayıların en az 16 bit olmasını gerektiriyor, bu nedenle -mint8 kullanmak tüm kütüphaneleri bozuyor.
Jon

9
Nigel Jones, "8-bit Mikrodenetleyiciler için Verimli C Kodu" nda şöyle dedi: "... C'nin tam promosyon kuralları, muhtemelen 8-bit dünyada çalışan bizlere karşı işlenen en iğrenç suçtur" ...
Dirceu Rodrigues Jr

1
@Jonas Wielicki: problem için en iyi çözüm daha iyi bir derleyici kullanmaktır. Örneğin avr-gcc sürüm 4.9.2 ile sorunu yeniden oluşturamıyorum: C kod satırı d >>= 1;için sadece tek bir lsr r24talimat alıyorum . Belki xZise çok eski bir derleyici sürümü kullanıyor.
Lor
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.