Cortex-M0 Assembly Alt Program Kullanma Sorunu

Başlatan Erhan YILMAZ, 28 Haziran 2016, 18:03:46

Erhan YILMAZ

Almanca klavye kullandigim icin Türkce karakterleri yazamiyorum öncelikle belirteyim.

Sorunum ise; Bildiginiz/Bilmediginiz gibi bi süredir arm cortex-m0 assembly ile hobi olarak ugrasiyorum. Gecenlerde bir alt program icinde alt program cagirmam gerekti. Fakat ikinci alt programi cagirinca ilk alt programdan geri donüs adresi siliniyordu. Yani alt program cagirirken islemci geri dönüs adreslerii stacke otomatik olarak itmiyor. Bunu alt programin basinda sizin yapmaniz gerekiyor. Acikcasi cok sacma geldi. Yoksa ben mi bir seyleri yalis yapiyorum? En basit piclerde bile bu islem otomatik yapilirken cortexlerde neden yok? Bilen, eden, kullanan, basina gelen var mi?

z

Hız açısından böyle yapmışlar.

Eğer alt rutine girip geri çıkacaksan işlemci geri dönüş adresini ramdaki stack alanına değil LR registerine atıyor. Eğer alt rutin içinden alt rutine gideceksen bu kez geri ilk geri dönüş adresini sen stacka atıyorsun.

Tek alt programın çağrıldığı durumlar için hız getirisi var. Fakat alt alta çağırmalarda işlemci geri dönüş adresini hard olarak da yapsa sen soft olarak da yapsan sonuçta hız açısından değişen bir şey olmuyor.

Dolayısı ile adamlar mantıklı bir iş yapmışlar.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Erhan YILMAZ

Anladim hocam dogru diyorsunuzda ben varsayilan olarak geri donus adreslerini otomatik stacke ittigini dusunerek kodu ona gore yazdim. Sonra debug yaparken durumun farkina vardim. Cok mantiki oldugunu dusunmuyorum. Bu sefer ben ihtiyatli davranarak butun alt programlarin basinda LRyi stacke itecegim. Belki simdi icerde al program cagirmadim ama ilerde cagiririm. Derleyiciler ne yapiyor acaba arka planda? Bence onlarda riske atmayip stacke itiyorlardir. Hatta kesme alt programi icin bunu yapiyolar. Örnek bir programi debug yaparken fark etmistim.

z

Derleyici alt program altından bir başka alt programı çağran tipte bir kodu derliyorsa LR'yi stacka atar aksi takdirde atmaz. Bilgisayar açısından sorun yok. O üşenmeden kontrol eder ve ona göre derler.

Elle yazımda ben gerekmiyorsa stacka atmıyorum. Sonradan alt program altından alt program çağırdıysam ve geri dönüş adresini stacka atmadıysam zaten debug asamasında hemen sorunu yakalıyorsun.

Başka işlemcileri unutup sadece ARM ile çalışırsan böyle tersliklere alışıyorsun.

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

Erhan YILMAZ

Anladim hocam. En son MSP430un asmsini kurcalamistim. Oda güzeldi aslinda. ARM standart oldugu icin onunla hasir nesir olayim dedim. Elimde de stm32f0 olunca mecbur cortex-m0 denemeler yapiyorum. Aslinda m3, m4 lere gecmeden m0+ ile ugrasmak isterim. Bakalim hayirlisi, alisiyoruz yavas yavas.

mufitsozen

#5
Alıntı yapılan: Erhan YILMAZ - 28 Haziran 2016, 18:49:48
Anladim hocam. En son MSP430un asmsini kurcalamistim. Oda güzeldi aslinda. ARM standart oldugu icin onunla hasir nesir olayim dedim. Elimde de stm32f0 olunca mecbur cortex-m0 denemeler yapiyorum. Aslinda m3, m4 lere gecmeden m0+ ile ugrasmak isterim. Bakalim hayirlisi, alisiyoruz yavas yavas.

Assembler ile program yazarken,degisik dil / derleyicilerle beraber calisma ortamini saglamasi acisindan "calling convention" denilen bir takim kurallara uyulur uyulmasi tavsiye edilir. Bu sayede yazdiginiz ASM altyordamlari ornegin C dilinden cagrilabilir vs. ARM ozelinde bunun ile ilgili dokuman  "Procedure Call Standard use by the Application Binary Interface (ABI) for the ARM architecture." diye geciyor ve bendeki dokumanin numarasi "ARM IHI 0042F, current through ABI release 2.10"

Bu dokumandan kisaca ozetlemek gerekirse (wikipedia'dan alinti yaptim)
Alıntı YapARM (A32)

The standard 32-bit ARM calling convention allocates the 16 ARM registers as:

    r15 is the program counter.
    r14 is the link register. (The BL instruction, used in a subroutine call, stores the return address in this register).
    r13 is the stack pointer. (The Push/Pop instructions in "Thumb" operating mode use this register only).
    r12 is the Intra-Procedure-call scratch register.
    r4 to r11: used to hold local variables.
    r0 to r3: used to hold argument values passed to a subroutine, and also hold results returned from a subroutine.

If the type of value returned is too large to fit in r0 to r3, or whose size cannot be determined statically at compile time, then the caller must allocate space for that value at run time, and pass a pointer to that space in r0.

Subroutines must preserve the contents of r4 to r11 and the stack pointer. (Perhaps by saving them to the stack in the function prologue, then using them as scratch space, then restoring them from the stack in the function epilogue). In particular, subroutines that call other subroutines *must* save the return address in the link register r14 to the stack before calling those other subroutines. However, such subroutines do not need to return that value to r14—they merely need to load that value into r15, the program counter, to return.

The ARM calling convention mandates using a full-descending stack.[10]

This calling convention causes a "typical" ARM subroutine to

    In the prologue, push r4 to r11 to the stack, and push the return address in r14, to the stack. (This can be done with a single STM instruction).
    copy any passed arguments (in r0 to r3) to the local scratch registers (r4 to r11).
    allocate other local variables to the remaining local scratch registers (r4 to r11).
    do calculations and call other subroutines as necessary using BL, assuming r0 to r3, r12 and r14 will not be preserved.
    put the result in r0
    In the epilogue, pull r4 to r11 from the stack, and pull the return address to the program counter r15. (This can be done with a single LDM instruction).

altyordama gidildiginde bir "prologue" kodu isletilir ve register degerleri saklanir (genellikle stackte bir frame konur, (bir tek STM komutu ile bu islem yapilabilir,) altyordamdan doner iken ise bir "epilogue" kodu isletilir ve orijinal register degerleri geri yuklenir (buda genellikle stackden yapilir ve bir tek LDM komutu ile yapilabilir)

Altyordamlarinizi bu "convention"lara uygun yapmaniz sizin yazdiginiz ASM kodunun daha problemsiz ve tasinabilir olmasini saglar.

Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.