Register olarak değişken tanımlama

Başlatan fatihinanc, 27 Haziran 2010, 14:43:31

fatihinanc

Merhaba Arkadaşlar;
Bugün sabah C de register değişken tanımlayınca PIC te hangi yazmaçlara kaydediliyor merak ettim.Hi-Tide ile debug yaparken register olarak tanımladığım değişkenlerin bılunduğu satırları atlıyor.
Breakpoint de koyamıyorum.
Adresini aktarmak istediğimde ise
register değişken adresi aktarılamaz diye bir hata mesajı alıyorum.

Normalde register olarak tanımladığımız değişken
bilgisayar ortamında CPU yazmaçlarına kaydediliyor.

Acaba PIC için register char x; diye bir değişken tanımladığımızda
bu değişken nereye kaydoluyor? hangi yazmaç kullanılıyor bu iş için?

Edit : x86 için yazdığım şu kodda herhangi bir hata almıyorum.

        char *a;
        register char deg=3;
        a=°


Fakat aynı kodu Hi-Tech derleyemiyor.
register değişken adresi aktarılamaz hatasını veriyor.

Kainat dediğimiz kitap, yazıldığı dil ve harfler öğrenilmedikçe anlaşılamaz.  (Galileo Galilei)

fatihinanc

Forumda kimse birşey yazmamış.Neyse ben iki gün boyunca edinidiğim bilgilerden biraz bahsedeyim.

char *a;
        register char deg=3;
        a=°


Bu kodda eski derleyici (GCC) ile hata almıyordum. Dün yeni sürümünü yükledim o da hata verdi.
Yani doğru olanı yaptı.
Eski derleyicide değişkenin adresini görmek istediğimde adres gösteriliyordu. fakat register char deg olarak tanımladığım değişkeni bir de char deg olarak tanımlayınca ve adresini görünce işler değişti.

Sonuç, derleyici her ikisi için de aynı adresi gösteriyordu ki bu olmaması gereken bir durum.
Borland derleyicisi de aynı şeyi yaptı. O da hata vermedi.
Neden kaynaklanıyor bilmiyorum ama derleyici o satırdaki register deyimini işlemcide bir yük olmamasına ve sadece bir tane register değişken tanımlamama rağmen görmezden geliyordu.

Peki register deyimi derleyici tarafından nasıl işleniyor onu inceleyelim şimdi.

Derleyici, register anahtar sözcğü ile karşılaştığı zaman yazmaçların o anki durumuna göre atama yapıyor.
Evet register int diye tanımladığımız değişken int diye tanımadığımız değişkene göre daha hızlı işliyor.
Ama bunun da bir sınırı var. Yani fazla sayıda register değişken tanımlayamıyorsunuz. O yüzden derleyici derleme esnasında register deyimini dikkate almıyor. Normal bir değişkenmiş gibi tanımlama yapıyor.Ve bunun için de herhangi bir uyarı ve hata mesajı vermiyor.

Eğer aksi bir durum söz konusu değilse  o an genel olarak kullanılabilen hangi yazmaç müsaitse değişken ona atanıyor. Zaten maksimum 2 byte lık bir atama yapabiliyoruz bu alana ki mantıklı olanı da bu.Register long olarak tanımladığımız değişkenler de(Bellekte 2 byte ve daha üstü herhangi bir tür bu alana dahildir) otomatik otomatik olarak derleyici tarafından long olarak işleniyor.Tabi bu durum işlemciden işlemciye değişebilir.

Sonuç : register olarak tanımladığımız değişkenin adresini görememe sebebimiz ya hangi yazmacın kullanılacağının belli olmaması ya da o kısımın adres erişimine izin verilmemesi.

Bunun hakkında tam kesin bir sonuca ulaşamadım ama ulaşınca buraya yazarım.

İnşaallah yanlış bir bilgi vermemişimdir. Forumdaki üstadlar eğer yanlışım varsa düzeltin lütfen.

Hayırlı Günler...
Kainat dediğimiz kitap, yazıldığı dil ve harfler öğrenilmedikçe anlaşılamaz.  (Galileo Galilei)

Tagli

PIC'te C kullanmadığım için konu hakkında bilgim yok ama durum beni de meraklandırdı. PIC'in hafızasında (16 serisi için konuşursak) hafıza alanlarına erişim aynı miktarda zaman alır, yani RAM diyebileceğimiz alan için. Bildiğim kadarıyla bilgisayarda "register" yazıldığında derleyiciye "bu değişkeni sık sık kullanacağım, mümkünse bunu bir register'da sakla" demiş oluruz. Çünkü bilgisayar, register'larına RAM'e eriştiğinden çok daha hızlı erişebilir. Yine de derleyicinin istediğimizi yapıp yapmayacağı belirsizdir.

PIC'te aklıma gelen uygulaması ise değişkenin bank değiştirme gerektirmeyen bölgede saklanıyor olması. Modelden modele değişmekle birlikte örnek vermek gerekirse 16F877A'da 16 bytle'lık bir alan bu. 18 serisindeki "Access RAM" de bu tür bir yerleşime örnek olabilir.

Alıntı yapılan: fatihinanc - 29 Haziran 2010, 17:53:18Sonuç : register olarak tanımladığımız değişkenin adresini görememe sebebimiz ya hangi yazmacın kullanılacağının belli olmaması ya da o kısımın adres erişimine izin verilmemesi.
Bildiğim kadarıyla derlemeden önce hiçbir değişkenin adresi (yani hangi register'da saklanacağı) belli değildir (kullanıcı özellikle belirtmediği sürece). Ancak yüksek optimizasyon varsa, derleyici aynı anda kullanılmayacağından emin olduğu birden fazla değişkeni aynı register'a yerleştirebilir.

Bana sanki bu register olarak tanımlama işlemi bilgisayara özgü bir özellik gibi geliyor. PIC için olan C derleyicilerinde hata verme sebebi yukarıda anlattığım durumun PIC'te uygulanabilirliğinin olmamasından kaynaklanıyor olabilir. Çünkü bilgisayar için register ve RAM farklı yerlerken, PIC'te ikisi de aynı şey. PIC'te register olarak adlandırdığımız yerler RAM gibi kullanılıyor. Zaten register sanırım işlemcinin içinde olan hafıza alanı anlamına geliyor.

Yine de bu konudaki yorumlarım, PIC için yazılmış C dilleri hakkında bilgim olmadığı için tahminden öteye gitmeyecektir...
Gökçe Tağlıoğlu

picusta

C'de register  deyimi PIC'teki  W yazmacina karsilik gelir.
Hafiza islemcinin çekirdeginde oldugu için, diger RAM hafizasi gibi bir adresi yoktur, özel komutlarla ulasilir. degiskene ulasmak için islemci adresleme islemi yapmaz bu yüzden daha hizlidir.

z

Birden fazla registeri olmayan islemcilerde C dilini kullanirken register tanimli degisken kullanimin mantigi olmaz. Herhangi bir
avantaj da getirmez. Cunku islemcinin is yapabilmesi icin registere deger aktarmasi gerekir. Bu da register tanimli degiskenin
iceriginin bozulmasi demektir. Mecburen islemci register tanimli degiskeni ramda tutmak zorunda kalir.

Yanlis hatirlamiyorsam Atmelde ramin her bir byte i  accumalator ozelligine sahip. Durum boyle olunca atmel C de
avantajli hale geliyor. Bu da ozellikle do, while, for gibi dongulerde hiz olarak kendini gosteriyor.

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

fatihinanc

Alıntı yapılan: Tagli - 30 Haziran 2010, 03:18:50

PIC için olan C derleyicilerinde hata verme sebebi yukarıda anlattığım durumun PIC'te uygulanabilirliğinin olmamasından kaynaklanıyor olabilir.

@Tagli hocam
Hem Hi-Tech de hem de GCC derleyicilerinde hata mesajı aldım.


Alıntı yapılan: picusta - 30 Haziran 2010, 11:45:56
C'de register  deyimi PIC'teki  W yazmacina karsilik gelir.
Hafiza islemcinin çekirdeginde oldugu için, diger RAM hafizasi gibi bir adresi yoktur, özel komutlarla ulasilir. degiskene ulasmak için islemci adresleme islemi yapmaz bu yüzden daha hizlidir.

@picusta nın yorumu galiba bu olayı özetlemiş.
Fakat birkaç sorum olacak.

özel komutlar derken hangi komutlarla buraya ulaşmak mümkün hocam?
Bir de değişkene ulaşmak için adresleme yapmaması durumu  genel itibariyle
Mikroişlemcilerde ve diğer Mikrodenetleyicilerde de mi aynıdır?

Alıntı yapılan: bunalmis - 30 Haziran 2010, 12:17:10
Birden fazla registeri olmayan islemcilerde C dilini kullanirken register tanimli degisken kullanimin mantigi olmaz. Herhangi bir
avantaj da getirmez. Cunku islemcinin is yapabilmesi icin registere deger aktarmasi gerekir. Bu da register tanimli degiskenin
iceriginin bozulmasi demektir. Mecburen islemci register tanimli degiskeni ramda tutmak zorunda kalir.

@bunalmis hocam;
Evet ben de bu konuyu açmadan önce böyle düşünüyordum. Hatta bu başlığı açma sebebim de budur.
Yani PIC için akümülatör olarak bildiğimiz sadece W yazmacı var.
register olarak tanımladığımız değişken de zaten böyle bir yazmaca atanacağından sizin dediğiniz gibi bunun bir artısının olmayacağını düşünmüştüm.Bu durumda PIC in de diğer işlemleri nasıl yürüttüğünü merak etmiştim.Hatta böyle bir durum değişken RAM e yedekleneceğinden dolayı çevrim süresi olarak diğerine nazaran daha da fazla sürebilir bence.



Kainat dediğimiz kitap, yazıldığı dil ve harfler öğrenilmedikçe anlaşılamaz.  (Galileo Galilei)

Tagli

PIC'in zaten sadece 1 tane W'si olduğu için ve bunu da çalışması sırasında sık sık kullanmak zorunda olduğundan burada değişken saklanması mümkün olamaz. Yanlış hatırlamıyorsam yüksek PIC modellerinde (16 bit ve 32 bit olanlarda) birden fazla W vardı. Onlarda durum farklı olabilir.

picusta'nın bahsettiği özel komutlar aslında o kadar da özel komutlar olmayıp, W üzerinde işlem yapan herhangi bir asm komutu olabilir. Zaten en basitinden a = b gibi bir kopyalama bile W'nin kullanımını gerektirir. Önce W = b, sonra a = W işlemleri uygulanır. Ayrıca ufak bir düzeltme: 18 serisi PIC'lerde W'ye hafıza alanı üzerinden de harhangi bir register gibi adresi ile erişilebiliyor. Bu, register'lar üzerinde yapmaya alışık olduğumuz bazı işlemlerin W üzerinde de yapılabilmesine olanak veriyor. Mesela kaydırma işlemi. Kaydırma komutu adresi verilen bir register üzerinde kaydırma yaptığından, 16 serisinde W'deki bir değer üzerinde kaydırma yapabilmek için öncelikle onu normal bir register'a aktarmak gerekiyordu.
Gökçe Tağlıoğlu

fatihinanc

@Tagli Hocam dediklerinizi denemek için Bugün 18F252 ile bir uygulama gerçekleştirdim.

Hi-Tech C nin

register char deg=3;
char i;

için ürettiği kodlar aşağıda.
18F ASM sinin komutlarını tam bilmiyorum.
Galiba her ikisi için de aynı işlemler yapılıyor sadece RAM deki adesleri farklı.


register char deg=3;
0x00060c <_main+2>:   movlb 00h
0x00060e <_main+4>:   movwf 0F7h
0x000610 <_main+6>:   movlw 03h
0x000612 <_main+8>:   movlb 00h
0x000614 <_main+10>:  movlb 00h
0x000616 <_main+12>:  movwf 0F3h
0x000618 <_main+14>:  movlb 00h
0x00061a <_main+16>:  movf  0F7h, w
	unsigned char i=5;
0x00061c <_main+18>:  movlb 00h
0x00061e <_main+20>:  movwf 0F7h
0x000620 <_main+22>:  movlw 05h
0x000622 <_main+24>:  movlb 00h
0x000624 <_main+26>:  movlb 00h
0x000626 <_main+28>:  movwf 0F4h
0x000628 <_main+30>:  movlb 00h
0x00062a <_main+32>:  movf  0F7h, w
Kainat dediğimiz kitap, yazıldığı dil ve harfler öğrenilmedikçe anlaşılamaz.  (Galileo Galilei)

Tagli

İkisini de aynı işlemiş. Hatta "Access RAM"e bile koymamış. İşlemlerden önce yakın bir yere W'nin yedeğini almış. Bank değiştirme kodu olan movlb'leri ise neden bu kadar çok ve arka arkaya kullandığına anlam veremedim.
Gökçe Tağlıoğlu

fatihinanc

Derleyicinin sürümünden kaynaklanıyor olabilir.
Sabah yeni sürümünü yükleyip MPLAB da denerim.

Vallahi şu ana kadar kesin bir sonuç göremedik.
16F serisinde zaten bir garip.Debug yapılmıyor.
18F serisinde de register olarak tanımlanmasına
rağmen normal bir değişkenle aynı tanımlanmış.

Bunu en iyisi registeri bol bi MCU da denemek lazım.
AVR de derleyeceğim kodu bakalım o nasıl işleyecek.
Kainat dediğimiz kitap, yazıldığı dil ve harfler öğrenilmedikçe anlaşılamaz.  (Galileo Galilei)