MSP430 Asm'si hakkında soru

Başlatan yamak, 13 Mayıs 2014, 10:58:38

yamak

MSP430 Asm'sini öğrenmeye çalışıyorum.Daha önce de Asm ile pek kod yazmadığımdan aklıma takılan bazı noktalar.Mesela aşağıdaki kod üzerinden konuşacak olursak:
#include "msp430.h" ; #define controlled include file 
ORG 0FF00h 
myStr DB "HELLO WORLD, I AM THE MSP430!" ; the string is placed on the stack 
; the null character is automatically added after the '!' 
NAME main ; module name 
PUBLIC main ; make the main label vissible 
; outside this module 
ORG 0FFFEh 
DC16 init ; set reset vector to 'init' label 
RSEG CSTACK ; pre-declaration of segment 
RSEG CODE ; place program in 'CODE' segment 
init: MOV #SFE(CSTACK), SP ; set up stack 
main: NOP ; main program 
MOV.W #WDTPW+WDTHOLD,&WDTCTL ; Stop watchdog timer 
BIS.B #0FFh,&P1DIR ; configure P1.x output 
MOV.W #myStr, R4 ; load the starting address of the string into the 
register R4 
CLR.B R5 ; register R5 will serve as a counter 
gnext: MOV.B @R4+, R6 ; get a new character 
CMP #0,R6 
JEQ lend ; go to the end 
CMP.B #'E',R6 
JNE gnext 
INC R5 ; increment counter 
JMP gnext 
lend: MOV.B R5,&P1OUT ; Set all P1 pins 
BIS.W #LPM4,SR ; LPM4 
NOP ; Required only for debugger 
END


ORG 0FFFEh 
DC16 init ; set reset vector to 'init' label


Satırlarında tam olarak ne yapılmak istenmiş.Küçük bir reset handler yazılmış galiba ama mantığını tam anlamadım.
Özellikle
DC16 init
kısmı kafamı karıştırdı biraz.
jmp init
yazılsaydı olmaz mıydı?

z

Mantıken

ORG 0FFFEh
DC16 Init

Init fonksiyonunun adresini 0xFFFE-0xFFFF alanına yazıyor. Burası da vektor tablosu.
Vektor tablosu içeriği MCU tarafından okunup ilgili adrese jump edilmeyi sağlayan bir tablo olduğundan jmp Init yazamazsın.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

yamak

Hocam o zaman şimdi şöyle bi soru sorayım:
16 bitlik mimaride nasıl oluyorda öyle bir komut çalıştırılıyor ki PC 16 bit genişliğindeki bir adrese dallanıyor.
Yani demek istediğim  0xFFFE-0xFFFF arasına init fonksiyonunun adresi yazılıyorsa PC 0xFFFE adresine dallandığında bu adres içindeki adresi okuyup oraya nasıl dallanıyor.Bunun olabilmesi için rom'un 32 bit genişliğinde olması gerekmez mi?Yani komut opcode vs içereceğinden dolayı.

z

Burda bahsedilen 0xFFFE-0xFFFF adesine 2 byte yerleşeceğidir.

DC16 16 bit veri yerleştir anlamına geliyordur. En tepeye de 0xFFFE dediğine göre durum dediğim gibidir.

(Bildiğimden yazmıyorum mantıken böyledir.)
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

RaMu

#4
8 bitlik işlemcimiz olsun,

goto adres1  (asmdede zaten birebir goto diye komut var, c dede var)
dedik programda ve adres1 de şöyle olsun,

goto adres2

hatta adres2 de şöyle olsun

goto adres3
adres3 ise goto adres0 olsun

adres0
işlemler
.
.
adres1  goto adres2
adres2  goto adres3
adres3  goto adres0

burada adreslerin 8 bit olması ve ardarda 2-3 adrese dallanılması bir problem teşkil etmez,
stack denen kavram yardımıyla işlem gerçekleşir,
misal biz call adres1 desek ve adres1 içinde call adres2 çağırsak sonra adres3 vs. içiçe çağırsak
yine benzer durum oluşuyor,
bu call işlemleri esnasında md. şunu yapıyor,
şuan adres0 dayız
adres0  call  adres1

şeklinde çalışsın
md. adres1 in program memorydeki adresine dallanacak bunu biliyoruz
ama geri döneceği adrese ne olacak o zaman
işte call nerede devreye girdiyse (yani adres0 ın program memorydeki adresi)
bu değer stack denen hafızaya yüklenir,
aynı şekilde çağrılan bir altprogram içerisinde yine altprogram çağrılırsa
stack geriye doğru hafızasındaki adresleri iteleyerek yeni dönüş adresini stack ın en üst bölmesine yerleştirir,

peki bu işte bir sınır varmı tabiki evet,
misal 16f877 de stack 8 level
yani en fazla içiçe 8 tane altprogram çalıştırılabilir,
buna dikkat edilmezse doğal olarak program sapıtır.

Şunuda belirteyim stack 16f877de 13 bitlik değer tutabilir
yani çağrılacak veya dönülecek adresin sadece 13 bitini stack tutabilir,

Burada uzun asm programı yazıldığında karşılaşılan problem kendini gösteriyor,
ve şu soruda akla geliyor,
beni md. (16f877) 8 bitlik, 8 bitlik adresleri hafızasında tutabiliyor,
işte bu böyle değil
stack 13 bitliktir
stack içinde 13 bitlik değer saklanabilir
md 8 bitlik olsada stack 13 bitlikdir bu böyle tasarlanmış,
buda bizim 16383 tane adresi gösterebilmemizi sağlar,
yani 13 bit saklayabilen gösterebilen stack ile 15k program hafızasına erişilebilir,

peki ben goto kullanarak 15000 adresine git oradaki kodları çalıştır nasıl diyeceğim,
bunun için pcl pch a bakmak lazım,
eğer bizim 13 bitlik stack ımız 16383 e kadar ulaşılabilir program hafızamız varsa
ve md. kodları (dallanma yoksa) baştan sona satır satır çalıştırır,
bu esnadada hangi satırdayım diye bir sayıcı çalışmak zorundaki
call veya goto komutu geldiğinde halihazırdaki adresini stack a yazabilsin
işte bu işi program counter yapar,
buda program counter low
ve program counter high olarak iki bölümden oluşur ki
kullanıcı 8 bitlik değişkenleriyle bu ikisine ayrı ayrı yazma yaparak istediği 15000 program memory adresine gidebilsin,
burada zaten bize program counter high PCH yetiyor,
fotoya bakarsak;

1) Asm kodun opcode şeklinde makine diline dönüştüğünde md. program memory nin hangi adresinde bulunduğu,
yani kodun md. program hafızasındaki yeri,
2) Asm kodun memorydeki adresini ne işlev gördüğünü birleştip intelhex16 formatına çevrilmiş
programlayıcının anlayıp mdye yazabileceği hale dönüştürülmüş şekli,
3)Asm komut ve karşısında komuta göre adres değişken gibi bulanan arguman,
4) Kullandığımız arayüzde burası kaçıncı satır belirten kolaylık kısmı,
5) 6) Komut ve argumanının programcının yazdığı en kolay anlayabileceğimiz hali

Burada 123 ile 456 aslında aynı ifadedir
fakat 123 makina diline yakın hali.

Burada satır 190: da call delay_250ms ile bekleme altprogramı çağrılmış,
123 den bakılınca delay_250ms in 0x8a adresinde olduğu görülüyor,
ve 202: ye bakarsak gerçektende 0x8a da olduğunu görüyoruz,

İşte burada kısa bir program var ve sıkıntı çıkmıyor,
aslında delay_250ms 0x008e adresinde
ama 0x508e adresine kadar uzamış gitmiş olsaydı sadece
delay_250ms
yazınca program 0x008e adresi gibi bir değere gidebilecekti
buda programın hatalı çalışmasına sebep olacaktı,
burada page kavramı devreye giriyor,
şunada dikkat etmek lazım
goto veya call komutunun karşısına 8 bitlik birşeymi yazılabilir
yoksa daha büyük birşeyde yazılabiliyormu,
hemen datasheetten bakalım;



Görüldüğü gibi 10 bitlik değer yazabiliyoruz,
ve bu sayede yine fotoda görüldüğü gibi


4 farklı sayfadan oluşan program hafızasına
sadece PCH değerini değiştirerek erişebiliyoruz.

Bu HARVARD mimarisi,
diğer mimarileri bilmiyorum,
ama durum çok değişebiliyor.


RaMu

Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

yamak

#5
Alıntı yapılan: gerbay - 13 Mayıs 2014, 13:16:34
hocam MSP430 da 0xFFFE adresinde Reset Vektör var..

DC16 ile word tanımlama yapıyor;

org 0FFFEh  dediğinde o adresten itibaren başlayacak gelecek ASM komutları demek istiyor

DC16 Init     dediğinde ise word olarak Init metodunun adresini oraya yazacak demek..

nasıl ki Cortex lerde 0x0004 adresinde reset vektör var bunda da 0xFFFE de reset vektör var..

mesela

org 0ffffeh
DC16 0f800h


yazmış olsa MCU reset yediğinde direk 0xf800 adresinden başlar..

*Hocam asıl anlamadığım nokta 16 bitlik mimaride PC'yi 16 bit genişliğinde bi adrese nasıl dallandırıyoruz.
Zaten komutlar 16 bit değil mi?
Mesela call komutu ile 0xFF00 adresindeki bir fonksiyona dallanmak istediğimizde ne oluyor.

*Bir de hocam mesela işlemciyi resetlediğimizde aşağıdaki komuta benze bir komut çalıştırılıyor değil mi?
mov.w PC,&0FFFE


z

#6
Vektor tablosunda komut ile zıplama yapılmaz.

Donanım reset ardından tablodaki 16 bit adresi alır ve doğruca PC içine yazar. Bunun için işlemcinin bir komut yürütmesi gerekmez.

Öte yandan;

Komutlar 16 bit uzunlukta olsa bile 16 bitlik bir adrese zıplamanın 3 yolu var.

MSP de hangisi(leri) geçerli bilmiyorum.

1. Yöntem 16 bit komutu takiben 16 bit adres verisi kullanılır.

Mesela long jmp komutunun hex karşılığı 0x1000 ise ve 0xFFFF afresine jump edeceksen

0x1000
0xFFFF

bu amaca hizmet eder.

2. Yöntem ise page adreslemedir.

Bunun için işlemcinin page adres registeri bulunur.

Atıyorum her bir page 4K uzunlukta ise

Page registerine Hedef/4096  değerini yüklersin arta kalanı da 16 bitlik jump komutu içine gizlersin.

3. Yöntem zıplanacak adresi bir register içine iki 8 olarak yazmak ve ardından Jump  [Register] tipi bir komutla hedefe zımpalamaktır.


PIC işlemcilerde Reset vektör tablosu yok. MSP benzeri işlemcilerde Vektör tablosu var.



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

Erhan YILMAZ

Komut seti ile v.s. alakası yok, 6800'lardan hatırlıyorum msp430'da de benzer. İşlemci reset, nmi kesmesi gibi durumlarda(bi kaç durum daha var) Hafızanın sonlarında bulunan özel adres bölgeleri var. Örneğin reset durumunda işlemci o adrese gidip (0xfffe-0xffff) o adresdeki 16 bitlik değeri program sayacına yükler. Program oraya dallanır. Piclerde ki gibi reset anında 0x0000 adresine dallanıp ordan goto komutu komutu ile ana programa geçmeye gerek yok.

yamak

Cevap veren herkese teşekkürler.
Şimdi anladım

Erhan YILMAZ

http://courses.cs.washington.edu/courses/cse466/11au/calendar/04-Interrupts-posted.pdf Bağlantıda ki dokümanda sayfa 9'da anlatmış mevzuyu. Kesmeler içinde aynı şey geçerli.