Hi tech C de oluşan gereksiz kodlar.

Başlatan XX_CİHAN_XX, 20 Temmuz 2008, 21:59:20

XX_CİHAN_XX

Arkadaşlar bir deneme yaparken farkettim ve paylaşmak istedim. Bu tür şeylerle karşılaştıkça bu başlık altında yazmanın faydalı olacağını düşünüyorum.
       LCD_DATA |= ( c << 4 & 0xF0 );

Bu kodun asm karşılığı şöyle geldi.
 0772    0E23     SWAPF 0x23, W
  0773    39F0     ANDLW 0xf0
  0774    39F0     ANDLW 0xf0
  0775    0486     IORWF 0x6, F

Görüldüğü gibi bir tane ANDLW kodu gereksizdir.  8O

İyi çalışmalar.
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

arslan74


Prescaler

XX_CİHAN_XX Sanırım bir konuyu gözden kaçırmışsın. Her ne kadar söylemiş olduğun gibi "andlw 0xf0" satırlarından biri gereksiz olsa da burada kusur derleyicide değil senin yazmış olduğun kodda. Şöyle ki:
 LCD_DATA |= ( c << 4 & 0xF0 );
Operatör önceliğini dikkate alınca
 LCD_DATA |= (c << 4) & 0xF0; olur.

Derleyici (c << 4) deyimi için
0772    0E23     SWAPF 0x23, W
0773    39F0     ANDLW 0xf0

kodunu üretiyor.
& 0xF0 için de
0774    39F0     ANDLW 0xf0

ekliyor. Yazmış olduğun kodda (c << 4) zaten düşük anlamlı 4-biti sıfırladığı için "& 0xf0" gereksiz. Yani gereksiz andlw'yi aslında koda sen eklemişsin. Derleyicinin tek suçu C kodunu yorum yapmadan makine koduna çevirmesi. Optimizasyon devre dışı iken bu zaten normal bir durumdur. Eğer kodu:
 LCD_DATA |= c << 4;
şeklinde yazmış olsaydın aynı işem yapılacaktı ve derleyici gereksiz andlw satırını eklemeyecekti.

XX_CİHAN_XX

Alıntı yapılan: "Prescaler"
Derleyici (c << 4) deyimi için
0772    0E23     SWAPF 0x23, W
0773    39F0     ANDLW 0xf0
Evet kilit nokta burası. Bu dilde yeni olduğum için burayı fark etmemişim.
Aslında mantık olarak
Derleyici (c << 4) deyimi için
0772    0E23     SWAPF 0x23, W 
0773    39F0     ANDLW 0xf0

İfadesinde sadece swapf yada sadece RLF işlemi yapması gerek burdaki AND işlemini ben talep etmiyorumki. Ben sadece 4 defa sola kaydır diyorum. Asm de bu Swapf ile yada 4 kez RLF ile eşdeğer... Bence buda bir gereksiz koda giriyor  :o
Derleyici c << 1 bu komutunu anladığım kadarıyla
BCF STATUS,C
RLF  C,F
şeklinde icra ediyor ve ordaki fazlalık olan And burdan geliyor. Halbuki ben sadece sola kay diyorum. (gereksiz/istenmiyen kod)
Yanlış mı  :?:
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

arslan74

Merhaba,

Kendinizde cok güzel acıklamışsınız.

Sizin dediğiniz yöntemle yapılmış olsaydı. Söyle bir şey olurdu.

BCF STATUS,C
RLF C,F
BCF STATUS,C
RLF C,F
BCF STATUS,C
RLF C,F
BCF STATUS,C
RLF C,F
ANDLW 0xf0
IORWF 0x6, F


10 cycle sürede yapiyor.

Oysa aynı işlemi  derleyici daha az kod yazarak yapiyor.

SWAPF 0x23, W
ANDLW 0xf0
ANDLW 0xf0
IORWF 0x6, F


4 cycle sürede yapiyor.

Selamlar

Prescaler

Alıntı yapılan: "XX_CİHAN_XX"
İfadesinde sadece swapf yada sadece RLF işlemi yapması gerek burdaki AND işlemini ben talep etmiyorumki. Ben sadece 4 defa sola kaydır diyorum. Asm de bu Swapf ile yada 4 kez RLF ile eşdeğer... Bence buda bir gereksiz koda giriyor  :o
Derleyici c << 1 bu komutunu anladığım kadarıyla
BCF STATUS,C
RLF  C,F
şeklinde icra ediyor ve ordaki fazlalık olan And burdan geliyor. Halbuki ben sadece sola kay diyorum. (gereksiz/istenmiyen kod)
Yanlış mı  :?:

arslan74'ün de açıkladığı gibi 4-bit ötelemeyi tek tek yapmak iyi bir yol değil. 8-bit PIC işlemcilerinde 4-bit sola öteleme için en hızlı ve az yer kaplayan yöntem önce swap yapmak (ki bu 4-bit döndürmeye eşdeğer) ve ardından düşük anlamlı 4-bit'i sıfırlamaktır.

c << 4

için swapf _c,F yetmez, çünkü düşük anlamlı 4-bite yüksek anlamlı 4-bit yüklendi. Ötelemenin gereği olarak düşük anlamlı 4-biti sıfırlamak gerekiyor:

swapf _c,W  (döndürme sonucu akümülatörde)
andlw 0xf0 (akümülatördeki değerin düşük 4-bitini sıfırla)

İşin esprisi şurada ki öteleme işleminde düşük anlamlı bitlerin sıfırlanması talebi zaten var  :) . Bu iki satır da (c << 4) işleminin yapılması için gerekiyor. C programlama dilinde sol taraf değeri olmayan yani kendisine değer atanmayan ifadeler derleyici tarafından geçici değişkenlerde tutulur. Derleyici de (c << 4) ifadesini akümülatörde açıyor, böylece daha sonra sol taraf değerine yüklemeyi de kolaylaştırıyor.

İyi çalışmalar.

XX_CİHAN_XX

Arkadaşlar anlatmak istediklerinizin farkındayım. swapf in ve  sola öteleme işlemlerinin ne olduğunu biliyorum ve kısa yoldan işi bitirmek için swapf kullanıldıgınında farkındayım. Ancak benim anlatmak istediğim olay başka.
Alıntı yapılan: "Prescaler"
(c << 4)
İşin esprisi şurada ki öteleme işleminde düşük anlamlı bitlerin sıfırlanması talebi zaten var  
Bence olmaması gerek. Benim takıntım burdan doğuyor.
"<<" Bunun anlamı "sola kay" değilmidir ?
Sola kaymanın asm deki karşılığı "RLF" değilmidir.
(c << 4) burada c registerini 4 sefer sola ötele anlamı yok mu ?
Bunu swapf c,f  diyebilirsin ancak bu bile bana göre doğru değildir.
Dogrusu bana göre sadece şu şekilde olmalı
RLF c,F
RLF c,F
RLF c,F
RLF c,F
Ancak C ye göre dogrusu bu

BCF STATUS,C
RLF C,F
BCF STATUS,C
RLF C,F
BCF STATUS,C
RLF C,F
BCF STATUS,C
RLF C,F

Ve tabi arslan74 hocamın da dedeiği gibi kestirmeden swaplayıp maskelemek şu durumda mümkün. Bunun zaten farkındayım ancak bana göre dogrusu sadece kaydırmak yani << = RLF şeklinde yukarıda belirttiğim gibi olması gerekmezmiydi.
Son bir soru(Açık) daha:
Diyelimki ben Kaydırmak istiyorum ancak Carry nin kaybolmadan kaydırılmasını istiyorum. Yani sadece RLF yapmak istiyorum. Bunu yapmak için asm kodu mu yazcam illa  :?:

Ek olarak:
Bugun derleyicinin bir anormalliğini daha tespit ettim belkide benim bir hatamdır diye paylaşmak istiyorum:
Programın başında aşağıdaki gibi global değişkenler açtım:
unsigned char i,  sayac=60, count=15;

Bu durumda program başladığında sayac reginde 60, count reginde 15 olması gerekmez mi ?
Ancak beni tam 1 saat uğraştıran hatanın sebebi derleyicinin counta 15 yüklemeyi atlaması oldu. 8O
Main de yukarıda yazmasına rağmen tekrardan count=15; yazınca sorun çözüldü. Bu hata derleyicinin mi benim mi  :?:
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

arslan74

Alıntı Yap
"<<" Bunun anlamı "sola kay" değilmidir ?
Sola kaymanın asm deki karşılığı "RLF" değilmidir.
(c << 4) burada c registerini 4 sefer sola ötele anlamı yok mu ?

"<<" anlamı RLF değil.

"<<" C ait bir anahtar sözcük. Bunun doğrudan ASM karşılığı olmak zorunda değil. Nitekim bu anahtar sözcük için PIC'in doğrudan ASM kodu yok. PIC18 serisinin komut sayısı daha fazla. Ondan iki tür öteleme işlemi var. carry ile ve carry siz öteleme işlemi var. 8086 mimarisinde de aynı komutlar var. Ama onlarda "<<" ve ">>" işlemini tek bir kod ile yapamiyorlar.



Alıntı Yap
Son bir soru(Açık) daha:
Diyelimki ben Kaydırmak istiyorum ancak Carry nin kaybolmadan kaydırılmasını istiyorum. Yani sadece RLF yapmak istiyorum. Bunu yapmak için asm kodu mu yazcam illa Question

C'yi ASM birebir benzer tutmamanız gerekir. C de anatar sözcüklerin sayısı belli ve bircok işlemcinin komut sayısı C nin anahtar sözcüklerinden katta fazladır.

Dolaysıyla ASM bir cok özelliği birebir C ile ifade edemessiniz. O yüzden ASM koduda eklme imkanı vermişler. En basidinden C de bool türü diye bir değişken veya binary modda değer yazma özelliği yok. Ama PIC ASM de bit tanımlayabilirsin ve binary modda değerler yazabilirsin. Ansi-C bunu desteklemiyor. Ama Hi-Tech fazladan bu özellikleride eklemiş. Buda bize cok kolaylık sağlıyor.

Alıntı Yap
Programın başında aşağıdaki gibi global değişkenler açtım:
Kod:

  unsigned char i,  sayac=60, count=15;

Bu durumda program başladığında sayac reginde 60, count reginde 15 olması gerekmez mi ?
Ancak beni tam 1 saat uğraştıran hatanın sebebi derleyicinin counta 15 yüklemeyi atlaması oldu. Shocked
Main de yukarıda yazmasına rağmen tekrardan count=15; yazınca sorun çözüldü. Bu hata derleyicinin mi benim mi Question

Bende kendi denedim bende düzgün çalışıyor. Mutemelen gözden kacırdığınız cok ufak bir nokta vardır. Yoksa yazdığınız şekilde çalışması lazım.

Selamlar

XX_CİHAN_XX

Arslan74 hocam detaylı açıklamalarınız için teşekkür ederim. Sanırım haklısınız. Her kodun doğrudan asm karşılığını bulmayız. Ancak şunuda söylemek gerek; sadece RLF yapmak istediğimde C kodu yazamıyacak olmam canımı sıkmıyor değil!
Yinede sorun değil tabiiki. Fakat "unsigned char i, sayac=60, count=15;" ifadesinde yaşadığım sorunu hala anlıyabilmiş değilim. Disassembly halini bile inceledim count registerine hiçbir şekilde 15 değeri yüklenmiyor. Ta ki maine tekrardan "count=15;" yazana kadar  :roll:
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

arslan74

Alıntı yapılan: "XX_CİHAN_XX"Arslan74 hocam detaylı açıklamalarınız için teşekkür ederim. Sanırım haklısınız. Her kodun doğrudan asm karşılığını bulmayız. Ancak şunuda söylemek gerek; sadece RLF yapmak istediğimde C kodu yazamıyacak olmam canımı sıkmıyor değil!
Yinede sorun değil tabiiki. Fakat "unsigned char i, sayac=60, count=15;" ifadesinde yaşadığım sorunu hala anlıyabilmiş değilim. Disassembly halini bile inceledim count registerine hiçbir şekilde 15 değeri yüklenmiyor. Ta ki maine tekrardan "count=15;" yazana kadar  :roll:

Hangi versiyon derleyici kullaniyorsunuz. Ben 8.05pl2 test ettim sorunsuz çalışıyor.

Selamlar

XX_CİHAN_XX

Hocam std 9.60pl2 kullanıyorum olmazsa versiyon değiştirecem. Yada sizinkini doğrudan kullanıp denemek isterim aslında. Rapid linki felan varsa tabi.
Saygılar, sevgiler.
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

arslan74

Alıntı yapılan: "XX_CİHAN_XX"Hocam std 9.60pl2 kullanıyorum olmazsa versiyon değiştirecem. Yada sizinkini doğrudan kullanıp denemek isterim aslında. Rapid linki felan varsa tabi.
Saygılar, sevgiler.

Ben bu siteye linki attım. bu siteden indirebilirsiniz.

Selamlar

XX_CİHAN_XX

Hocam sizin kullandığınız ve daha önce foruma linkini verdiğiniz Hi-Tech Picc 8.05PL2 versiyonunu kurdum ve yaşadığım sorun düzeldi. Teşekkürler.
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

engin_

Benim bu yazıdan çıkardığım sonuç yüksek seviyeli bir dil ile yazılmış kodun asm kodunuda mutlaka incelemek lazım. Yada derleyiciyi iyi tanımak. Burda derleyici mantıklı bir iş yaparak kodu kısaltmış iyi tamamda burda bahsi geçen değişken bir kesme programında değeri önemli birşeyi ifade ediyorsa... Ara değerleri görmeden en son değere ulaşmış olacağız her zaman. Bu da programda bir hata arayıp durmamız manasına geliyor.

XX_CİHAN_XX

Kesinlikle hocam aynen katılıyorum.
Bu nedenle sloganım şu:
Önce ASSEMBLY öğrenin!
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.