LDR ile MOV arasındaki fark nedir?

Başlatan ziyaretci, 13 Ekim 2018, 19:01:04

ziyaretci

Merhaba.

Keil'in sitesinden geliyorum, assembler da LDR ile MOV arasındaki fark nedir? Örneklere baktığımda farklı kullanımları var(parametre bazında).

Teşekkür ederim.

devrecii

#1
Mov komutu, direk komut satırında komutun yanındaki değeri hemen registere yazar , yeniden hafızaya ulaşmak zorunda kalmaz , komutla birlikde değerde alınır bu yüzden 16bit değer atanır, ldr komutu, belirtilen  hafıza adresine ulaşıp oradaki değeri 32bit alıp registere yazar ve registerler arası değer yüklemede kulanılır mov reg reg yapamaz.

mov komutu aşağı   16bite yazar , movt konutu ise yukarı 16bite yazar yani 32bit veriyi mov ve movt ile iki komutta yazdırırsın.


Zoroaster

#2
MOV komutu immediate adresleme teknigini kullanir. Registerlere dogrudan sayisal deger atar.

LDR ise registere diger registerden yada hafiza alanindan deger okur.

ARM komutlari diger islemcilerden biraz farkli.

Ornegin MOV komutu alt 16 bitte calisir demek yanlis olur.

MOV komutunda registere atayabileceginiz degeri kaydirarak da atama yapabilir. (Derleyici sizin icin bunu kendisi yapar)

Mov komutu 8 bit islemcilerde yukle anlamina gelirken ARM islemcilerde veriyi kaydirarak yukle anlamina gelir.
Buradaki kaydirma miktadina yazilimci olarak bizim karar vermemiz gerekmiyor. (Derleyici yuklemek istedigimiz degere gore kaydirma degerini kendi hesapliyor, yuklenemeyecek bir deger ise ( immediate verilerle calisirken  verinin 0..255 shift n kuralina uymasi lazim) hata verir zaten)

Dolayisi ile mov komutu 0x100 sayisini da 0x100000 sayisini da registere atayabilir.

Ote yandan registere immediate deger LDR ile de yuklenebilir. (Derleyici gercekten isleri kolaylastiriyor ve sahte komutlar uretebiliyor)

LDR R0,=0x12345678 gibi bir satir R0 registerine 0x12345678 gibi degeri yukler. Burada derleyici 0x12345678 degerini program alaninda PC in komut islemek uzere ustunden gecmeyecegi bir alana yerlestirilir. Yani data olarak yazilir.

Kod alanina ise LDR R0, [PC, #Data_Ofset]  seklinde kod yazar.

Kod isletilirken bu satira gelindiginde PC + Ofset adresindeki 0x12345678 degeri hafizadan okunmus ve R0 registerine aktarilmis olur.
Seytan deliginden kacti.

ziyaretci

@Zoroaster hocam o zaman MOV daha avantajlı hız bakımından, tabi LDR'nin değeri yüklediği adres komut işletim adresinden uzağa konmadıkça? Ama genellikle ARM'daki ASM'de hep(benim gördüğüm, genellikle diyeyim) LDR konulmuş. LDR'nin istenen veriyi daha yakın bir adrese koyma olasılığından mı? Yani bir sonraki komut işletimi adresi gibi?

Birde şunuda sormak isterim izniniz ile, mesela ORR.W R0, #0xFFFF gibi komut var. Bu W kayıtçışı R0 kayıtçısı ile eş mi? OR'lama işlemi yapıyor ama bir önceki satırda R0 'a R1 deki değerin adres içeriği atanıyor. Ardından ORR.W işlemi yapılıyor(#0xFFFF ile), ve R0 a yazılıyor.

Sabah test edeceğim ama o zaman kadar sormak istiyorum, ORR.R0 yapsam aynı şey olur mu? Olur ise neden W ile yapılsın?
  LDR R1, =TEST
	LDR		R0, [R1]			
	ORR.W 	        R0, #0xFFFF

Zoroaster

#4
Eger 16 bitlik veri yuklemesi yapacaksan mov komutu avantajli.  32 bit deger yukleyeceksen LDR mi yoksa mov32 mi daha avantajli komut isletim suresi tablosuna bakmak lazim.

ARM programlamada veri havuzlari olusturulur ve LDR R0,= tipi komutlar icin kullanilacak immediately veriler bu havuzlara yerlestirilir. Programci olarak biz bu kisma mudahale etmiyoruz. Bazen ayni veriyi farkli havuzlara da yazmak gerekebilir. ARM islemci LDR R0, [PC+x] tipi islemlerde Ileri dogru adresleme yapar ve bazen data havuzu kod alanina uzak olur. Bu durumda isletilen koda (fonksiyona) daha yakin havuzlar olusturmak gerekebilir. (neyseki bu islere biz kafa yormuyoruz, derleyici hata verirse LTORG ile yeni havuz olusturuyoruz sadece yada fonskiyonu cut paste ile havuza yakin yere tasiyoruz)
---------------------------
W wide anlamina gelir.

Risc islemcilerde immediate veri ve komut biraraya getirilerek paket olusturulur.

Eger thumb setinde komut ve veriden olusturulan paketin uzunlugu 16 bit komut icin gerekli bit uzunlugunu asarsa .w uzantisi koyarak  komutun boyunu 32 bite uzatiriz.
 
Ornegin  beq label1 komut satririnda label1 degeri komutun icine gomulemeyecek kadar buyuk ise komut beq.w label1 yazilir.

Bu komutun flash da daha cok yer kaplamasina neden olur ama istegimizi de karsilar.

Maalesef derleyici komutun genis mi dar mi olacagi konusunda yardimci olmuyor. Eger hata verirse .W ile o komutu genisletiyorum. (Halbuki islemci warning mesaji verip otomatik olarak .w uzantisi getirebilir fakat Keilin asm derleyicisi kestirip atiyor)

Cortex M3 icin ORR.W nin anlami yok gorunuyor.

CM3 de 0xFFFF ile immediate islem yapamazsin.  (0..255 shift n kuralina uymuyor)
Seytan deliginden kacti.