Picproje Elektronik Sitesi

PROGRAMLAMA DİLLERİ => C/C++ => Konuyu başlatan: mr.engineer - 12 Şubat 2021, 15:29:24

Başlık: Program ve Data Memory
Gönderen: mr.engineer - 12 Şubat 2021, 15:29:24
#define constnum  111

void foo()
{
   uint8_t var = 2;
   .
   .
   .
}


İnternette benzer bir şey gördüm kafam karıştı. MCU'da yukardakini yazınca hem sabit tanımlanan, hem de değişken 'var'ın RAM ve ROM da ne kadar yer kaplayacağını sormak istiyorum.

var değişkeni ROM'da var'ın adresini (mcu 32 bitlik olsun diyelim.) yani 4 byte ve ilk değerini (yani 2) tutar. Toplamda 5 byte oluyor. RAM'de ise toplam 1 byte yer tutar.

constnum sabiti ise kodda kullanıldığı yerde 111 ile değiştirilir, ve sadece program memory'de 1 byte yer tutar. Data memory'de yer tutmaz.

Ben bu şekilde biliyordum. Bir yanlış veya eksik var mı?

Not: 111 sayısının bir byte mı daha fazla mı yer tutacağından emin değilim. 111 sayısı tek byte'a sığıyor ama gerçekte bir byte mı kaplıyor? Mesela sonuna 111L  'L' koyarsak iş değişiyor galiba
Başlık: Ynt: Program ve Data Memory
Gönderen: Tagli - 12 Şubat 2021, 16:12:02
Fonksiyon içindeki değişkenler normalde stack içinde oluşturulur ve yok edilir. Yani belirli bir alanı sürekli olarak işgal etmezler. Ama sıfırdan farklı ilk değere sabit olanlar için söz konusu değerin bir yerde saklanıp oraya yüklenmesi gerek. Değerin ne olduğuna veya işlemciye göre bu değer bir komutun içine gömülebileceği gibi, ROM içinde önceden kayıt edilmiş olduğu bir yerden de çekilip yüklenebilir.

PIC'lerde kullanılan XC8 gibi derleyiciler, RAM'i zaten sınırlı olan bu işlemcilere bir de stack gibi belirsiz bir bellek bölgesi (ve işlemi) koyma riskine girmemek için alıştığımız anlamda bir stack kullanmayıp, compiled stack denilen bir yöntemle, fonksiyon içindeki değişkenler için derleme anında sabit bir alan ayırabilirler. Fonksiyonları reentrant olmadığı durumlarda bu yönteme başvurulabilir. Programın statik analizi sonucunda, derleyici çok sayıda farklı fonksiyonun aynı anda çalışmayacağına karar verirse, bu bölgeleri çakıştırıp alandan tasarruf da edebilir.

Değişkenlerin gerçekte ne kadar yer kaplayacakları da çok kesin değil, ya da ben net olarak bilmiyorum. Değişken 1 byte'a sığabilecek olsa bile, 32 bit bir işlemcide derleyici buna 4 byte ayırabilir. STM32'lerde bunun yapıldığına denk geldim. Ayrıca bazı değerler belki komutun içine de gömülebilir. Bu durum işlemci komut setine ve değişkenin değerine göre değişebilir. Hatta kullanım şekline göre de değişebilir.

Çok sayıda saklanması gereken bir veri yapısı ile uğraşılmadığı sürece genel olarak birkaç byte'ın peşine düşmeye gerek yok, zaman kaybı. Gerçi itiraf edeyim, zaman zaman bu hataya ben de düşüp hangi kullanım kaç byte harcıyor diye dedektifliğe soyunabiliyorum. Ama bunlar yanlış hareketler.
Başlık: Ynt: Program ve Data Memory
Gönderen: mr.engineer - 12 Şubat 2021, 16:30:36
Hocam daha karıştırdınız kafamı :)

Stack zaten RAM'e ait bir bölge değil mi? (stack, heap, static diye ayrılıyor bildiğim kadarıyla. Hepsi RAM'e ait diye biliyorum.)

Değişkenlerin gerçekte kapladıkları yer nasıl kesin değil anlamadım. RAM (veya stack) için kesin değil mi? uint8_t  1 byte yer kaplayacak. 32 bit olması neyi değiştirir?

Haaa... Aklıma geldi. Data alignment olayı vardı. Compiler padding falan yapıyordu yani bir byte 4 byte kaplayabilir doğru. (ama bu soruda bunu ignore edelim)


Benim asıl derdim flash memory zaten. Bir projeyi 16 Kbyte'a sığdırmaya çalışıyorum. O yüzden birkaç byte peşindeyim.
Başlık: Ynt: Program ve Data Memory
Gönderen: brandice5 - 12 Şubat 2021, 16:39:26
Bu konu kullanilan islemcinin komut setiyle cok alakali bir durum.

Islemcilerin komut setlerinde sabit deger yuklemek icin "immediate addressing mode" denen adresleme modu ve bu modu kullanan komutlar vardir.

Ornegin Intel X86'da;

uint8_t var = 2;

satirinin calistiran code (komut) sadece 4 byte'a sigar, cunku immediate value sadece 1 byte.
Degisken 1 byte yerine 4 byte olsaydi bu sefer komut uyunlugu 8 byte olacakti.

Dedigim gibi bu islemci komut setinin adresleme modlariyla cok alakali. Mesela Intel'de "var" degiskenini adresleme icin illa 4 byte lik bir adrese ihtiyac yok, cunku sistem bir base adres uzeine indexleme yontemi ile calisiyor.

https://c9x.me/x86/html/file_module_x86_id_176.html
Başlık: Ynt: Program ve Data Memory
Gönderen: RaMu - 12 Şubat 2021, 17:04:24
#define constnum  111Bu mcu da yer kaplamaz,
define derleyici komutudur,
derleyici programı derlerken costnum yazdığın yerlere 111 yazmışsın gibi davranır.

void foo()
{
  uint8_t var = 2;
  .
  .
  .
}
var değişkeni const tanımlanmadığı için ram de tanımlanmış yani ramde yer harcar.
int8 olduğundan ramde 1 byte yer harcar.
(32 bit bir mcu kullanıyorsan 32 bit yer harcama ihtimalide var.)

Yalnız bu var değişkeni fonksiyon içinde tanımlandığı için
ramde sadece kullanıldığında yer kaplar.
Sanki karalama kağıdı gibi ramin bir kısmının kullanıldığını düşün.
foo fonksiyonu ramin misal 13 adresini kullanır işi biter veya kullanırken bu durumda başka
goo diye bir fonksiyon çalışırsa
goo fonksiyonuda 13 nolu adreste varx diye bir değişkeni tutabilir.

Static, global gibi tanımlar bu durumları anlamak için incelenebilir.

Genel düşünecek olursak:
Ramde saklanan değişkenler,

Rom (program hafızasında saklanan) değişkenler veya sabitler
(Adının ROM olduğuna bakmayın)

Derleyici sabit tanumlamaları

ve Ram değişkenlerinin geçici alanda mı tanımlı olduğu yoksa
bu ram değişkenine her zaman şu ram adresinde bir yer ayrılsın mı dendiği
şeklinde özetlenebilir.

Dahada detayı var ...

Ek:
Alıntı yapılan: mr.engineer - 12 Şubat 2021, 15:29:24var değişkeni ROM'da var'ın adresini (mcu 32 bitlik olsun diyelim.) yani 4 byte ve ilk değerini (yani 2) tutar. Toplamda 5 byte oluyor. RAM'de ise toplam 1 byte yer tutar.


Buda doğru değil.
var değişkeni program hafızasında yer kaplmaz.
Bahsettiğim gibi sadece kullanıldığında ram de 1 byte yer harcar.
Böyle binlerce değişken tanımlayıp deneyebilirsin.

Yalnız başka gizli bir durum var.
Mcu programlanırken ramdeki değişkenlere programlama esnasında değer atamak gibi bir durum genelde yoktur.
Yani var = 2;
satırı çalışabilmesi için derleyici burayı bir program parçası olarak derler
bir daha yani :)
bu satır program hafızasında yer kaplar
mcuya ve atanan değere bağlı olarak genelde bir veya iki makina kodu yer tutar.
Başlık: Ynt: Program ve Data Memory
Gönderen: Tagli - 12 Şubat 2021, 17:35:48
Alıntı yapılan: mr.engineer - 12 Şubat 2021, 16:30:36Benim asıl derdim flash memory zaten. Bir projeyi 16 Kbyte'a sığdırmaya çalışıyorum. O yüzden birkaç byte peşindeyim.
ROM (Flash) için konuşacak olursak, genel olarak bir değişkene 0'dan farklı olarak atadığın her değer ROM'da ayrıca yer kaplar. Ama derleyici zeki ise, x = 5 ile y = 5 gibi aynı değere sahip değişkenler için tek bir veri tutabilir ROM'da. 32 bitlik bir işlemcide, derleyicinin uint8_t gibi değişkenlerin arasına hizalama için padding ekleyip eklemeyeceği kullanıma göre değişebilir. Ve ayrıca @brandice5 'in de dediği gibi, bazı durumlarda ilk değer komutun içine de gömülebilir. Ben STM32'de listing dosyasına baktığımda, genelde fonksiyon sonunda sabitlerin de ham veri olarak ROM'a kaydedildiğini, fonksiyon içinde de komutların buradan verileri çekip RAM'e yazdığını görüyorum. Ama dediğim gibi, kısaca özetlenebilecek basit bir kuralı yok bu işin.
Başlık: Ynt: Program ve Data Memory
Gönderen: mr.engineer - 12 Şubat 2021, 22:44:30
@Tagli ve @RaMu ikiniz çelişmişsiniz, yoksa ben mi yanlış anladım.

Alıntı yapılan: RaMu - 12 Şubat 2021, 17:04:24Ek:Buda doğru değil.
var değişkeni program hafızasında yer kaplmaz.
Bahsettiğim gibi sadece kullanıldığında ram de 1 byte yer harcar.
Böyle binlerce değişken tanımlayıp deneyebilirsin.




Alıntı yapılan: Tagli - 12 Şubat 2021, 17:35:48ROM (Flash) için konuşacak olursak, genel olarak bir değişkene 0'dan farklı olarak atadığın her değer ROM'da ayrıca yer kaplar.

Ben de @Tagli gibi düşünüyorum. Her değişkenin ROM'da yer kaplaması gerekir. İlk değer ataması yapılmışsa ROM'da olması gerekir fakat ilk değer ataması yapılmasa bile program memory'de yer kaplaması gerekmez mi? Mesela ben bir fonksiyonda 100 tane değişken tanımladım. Yani bunların hepsi assembly kodunda yazmıyor mu?
Fonksiyon çağrılınca bu değişkenler için sırasıyla stack'de yer ayrılacak. Yani bu 100 değişken olduğuna dair bir bilgi .hex dosyasında yok mu? En azından 100 byte yer ayrılmasa bile, 100 adet değişken tanımlanacak gibi bir bilgi yok mu? Böyle bir bilgi varsa bu da rom'da yer kapladığı anlamına gelmez mi?

NOT: Optimizasyon olmadığını varsayıyorum.
Başlık: Ynt: Program ve Data Memory
Gönderen: mufitsozen - 12 Şubat 2021, 23:31:08
Alıntı yapılan: mr.engineer - 12 Şubat 2021, 22:44:30@Tagli ve @RaMu ikiniz çelişmişsiniz, yoksa ben mi yanlış anladım.



Ben de @Tagli gibi düşünüyorum. Her değişkenin ROM'da yer kaplaması gerekir. İlk değer ataması yapılmışsa ROM'da olması gerekir fakat ilk değer ataması yapılmasa bile program memory'de yer kaplaması gerekmez mi? Mesela ben bir fonksiyonda 100 tane değişken tanımladım. Yani bunların hepsi assembly kodunda yazmıyor mu?
Fonksiyon çağrılınca bu değişkenler için sırasıyla stack'de yer ayrılacak. Yani bu 100 değişken olduğuna dair bir bilgi .hex dosyasında yok mu? En azından 100 byte yer ayrılmasa bile, 100 adet değişken tanımlanacak gibi bir bilgi yok mu? Böyle bir bilgi varsa bu da rom'da yer kapladığı anlamına gelmez mi?

NOT: Optimizasyon olmadığını varsayıyorum.

her degisken ROMda olmali derken bunu neye gore soyluyorsunuz?

Boyle bir tartismaya girmeden once kullandiginiz toolchain(compiler, linker, locator..) ve onlarin kullandigi formatlar(ornegin COFF, ELF vs), vb ile cok detayli bilginiz olmali.
Başlık: Ynt: Program ve Data Memory
Gönderen: Tagli - 13 Şubat 2021, 00:04:12
İlk değer almaları gerekmediği sürece, bir fonksiyon içinde kullanılan ve automatic storage kategorisindeki (ya da static olmayan da diyebiliriz) değişkenler için stack üzerinde yer açılması çok kolaydır. Sadece stack pointer'ı kaç byte lazımsa o kadar ileri almak yeterli. İlk değer atanmadığı sürece buradaki değişkenler daha önce orada olan artık şanslarına düşen ne varsa o çöp değeri alırlar, ki bu da pek istenen bir durum değildir. Bunlara en azından 0 atamak doğru ve çok düşük maliyetli bir karar olacaktır.

Daha önce de belirttim, bunun çok genel geçer bir kuralı yok. Durum işlemciye, derleyiciye ve derleme ayarlarına göre değişebilir. Ama çok basit bir mantık ile, x = 5; diyorsanız o 5'in ROM'da bir yerlerde olması gerek, bunun pek kaçarı yok. Eğer sığıyorsa belki bir komutun içine gömülebilir, o zaman fazladan yer kaplamaz. 0 ise zaten sorun yok, her işlemcide bir sıfırlama komutu zaten olur.

Alıntı yapılan: mr.engineer - 12 Şubat 2021, 22:44:30En azından 100 byte yer ayrılmasa bile, 100 adet değişken tanımlanacak gibi bir bilgi yok mu? Böyle bir bilgi varsa bu da rom'da yer kapladığı anlamına gelmez mi?
Tabi bu durumda ROM'da bir yerde 100 ya da ona benzer tek bir değer saklanır. İşlemci stack pointer'ı 100 ileri sarar. Tam yapısını bilmiyorum tabi ama buna benzer bir şey yapıyor olsa gerek.
Başlık: Ynt: Program ve Data Memory
Gönderen: RaMu - 13 Şubat 2021, 07:07:08
@mr.engineer mesajımın devamında yazıyor, çelişen bir şey yok.
@mufitsozen inde belirttiği bizimde bahsettiğimiz gibi bir çok şeye bağlı değişir bu durum,
genel bir şey söylemek zor,
en başta işlemci mimarisine göre değişir zaten ...


Bence yanlış sorular soruyorsun,
küçülmek istediğin kodu paylaş küçültelim.
Başlık: Ynt: Program ve Data Memory
Gönderen: mr.engineer - 13 Şubat 2021, 17:57:32
@RaMu Kodu küçültmeyi düşünürken kafama takıldı bunlar ama çok sorun değil 16 yerine 32kB bir MCU'da kullanabilirim, fakat compile işlemi ve sonrası hep kafamı kurcalıyor.

Alıntı yapılan: Tagli - 13 Şubat 2021, 00:04:12Tabi bu durumda ROM'da bir yerde 100 ya da ona benzer tek bir değer saklanır. İşlemci stack pointer'ı 100 ileri sarar. Tam yapısını bilmiyorum tabi ama buna benzer bir şey yapıyor olsa gerek.

sormaya çalıştığım bu. Dediğiniz gibi işlemci mimarisi, compiler vb. çeşidine göre durum değişebilir ama ROM'da yer kaplamaz cümlesini anlamıyorum. Hangi compiler ya da işlemci olursa olsun, 100 elemanlı bir array veya sadece int x; diye bir değişken tanımlanacaksa bununla ilgili bir bilgi (kaç byte olursa olsun) ROM'da olması gerekmez mi?

Hatta değişkenleri boşverin bir satıra if-else eklemek bile ROM'da yer tutmaz mı? Yani ben biraz şey gibi düşünüyorum. Bir text dosyasına ne kadar çok şey yazılırsa o kadar boyutu artar. ROM için de böyle düşünüyorum ama yanlış galiba:)

Bu konuyla ilgili önerebileceğiniz bir kitap varsa bakmak isterim bazı şeyler kafama oturmuyor ve merak ediyorum.

   
Başlık: Ynt: Program ve Data Memory
Gönderen: Tagli - 13 Şubat 2021, 18:06:50
Alıntı yapılan: mr.engineer - 13 Şubat 2021, 17:57:32100 elemanlı bir array veya sadece int x; diye bir değişken tanımlanacaksa bununla ilgili bir bilgi (kaç byte olursa olsun) ROM'da olması gerekmez mi?
Doğru, ama saklanacak veri miktarı değişken veya array boyutu ile orantılı olmak zorunda değil.

Gerçek hayattan örnek verelim: Tapuları düşün. Ufacık bir apartman dairesi de olsa, koca bir saray da olsa ikisinin de tapusu 1 sayfalık bir belgedir.

1000 elemanlı bir array olsun ve hepsini 5 yapmak istediğini düşün. 1000 tane 5'e ihtiyacın yok ki. Program içinde tek bir yerde bir 5 saklarsın, array'in tüm elemanlarına buradan kopyalarsın.
Başlık: Ynt: Program ve Data Memory
Gönderen: mr.engineer - 13 Şubat 2021, 20:09:51
Evet, anladım. Teşekkürler
Başlık: Ynt: Program ve Data Memory
Gönderen: RaMu - 14 Şubat 2021, 01:27:01
Asm çalışabilir veya mcu nun "instruction set" ini inceleyebilirsin.
Veya bahsettiklerimizi basit bir programda deneyip asm çıktısına bakabilirsin.

Alıntı yapılan: mr.engineer - 13 Şubat 2021, 17:57:32@RaMu Kodu küçültmeyi düşünürken kafama takıldı bunlar ama çok sorun değil 16 ...
...Bir text dosyasına ne kadar çok şey yazılırsa o kadar boyutu artar. ROM için de böyle düşünüyorum ama yanlış galiba:)
...
Alakasız ama yazayım,
örneğin FAT dosya sisteminde düşünürsek
dosya bir karakter de olsa 100 karakterde olsa
hafızada en az "cluster size" ayırma birimi boyutu kadar yer kaplar.
Bunu niye yazdım, sistemi tasarlayan böyle tasarlamış herşey tasarıma göre değişir.