STM32F407 Cortex M4 şamataları

Başlatan bunalmis, 16 Ekim 2011, 17:14:50

z

Alıntı yapılan: mcan - 03 Kasım 2011, 19:00:40
Ama bitbanding disindaki metodlarda mask kullanmiyormuyuz? Mecbur oku degistir yaz yolunu secmezmiyiz?Ben zaten anlamadim bu atomic yani bolunemez erisimi, anladigim su bitbanding yaparken islemin kendisinin masking `e (oku, degistir, yaz) gore hizli olmasinin yaninda ,bit banding  bitmeden interrupta bile girmiyor.Anladigim, adam diyorki rxe bitini 0 yazarak sifirlamak istiyoruz, bunun icin kopmle registeri okuyoruz ,sonra or and gerekli olan operator ile degistiryoruz ,biz bu degisim isini yaparken cts biti 1 oluyor, sonra bizim degisen yazmaci geri usartsr ye yaziyoruz biz okumaya basladigimizda cts 0 oldugundan geri yazarken de ona dokumadigimizdan yazim tamamlaninca arada 1 olan cts islem sonunda sifir oluyor.Bit banding bunun onune geciyor olarak anladim

Neden okuyup geri yazasınki? Bu çok özel bir register. Register kutucuğunda her bir bitin altına bak sade şekilde r/w yazmıyor

Diyelimki int geldi ve int rutinine girdin.

1. USART_SR registerini oku

Diyelimki CTS set olmuş bunu sıfırlamak istiyoruz.

2.  USART_SR=0x1FF

-------------

Diyelimki int geldi ve int rutinine girdin.

1. USART_SR registerini oku

Diyelimki RXNE set olmuş bunu sıfırlamak istiyoruz.

2.  USART_SR=0x3DF

Hepsi bu kadar.

Klasik anlamda değişkenlerde read modify write işlemleri yapabilirsin. Fakat

Eğer register rc_w0, rc_w1, t gibi özel yapıya sahipse bu durumda klasik anlamda modifikasyon değil ya dediğim gibi yada bitband işlem yapmalısın.

Bit banding işlemi sadece ve sadece STR yada LDR şekline tek cycle bir komut. Bu tip elamanter komutları interrupt zaten bölemez.

Alıntı yaptığın kişi yada ben bence olayın farkında değil.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

mcan

Evet,o bitlere 1 yazmak bişeyi değiştirmiyor gene 0 ise sıfır oluyor sanırım sadece hw set edebiliyor,
Bence de haklısınız ,adam örnek vermiş ancak ya örneği ben anlamadım yada yanlış örnek vermiş...

Peki Bunalmiş hocam adamın örneğini ben değiştireyim ;

Programımızda sram de her programın kullancağı bir posta kutusu olsun.Basitlik açısından 1 word olsun.

Main içinde bu posta kutusunu kontrol edelim,ayrıca bazı bitleri set ederek kesme rutininde koşan programcıklara bilgi gönderelim.

2 adet kesme rutinimiz olsun,kesmelerde bu posta kutusunda belirli bitleri set edip main de çalışan programımızı uyaralım.

Şimdi mainde programımızın bir kısmında 1. kesmeyi kontrol edip dallanalım,
2. kısmında 2. kesmeyi kontrol edip dallanalım.

Bit band kullanmıyoruz,
Alıntı Yap
Posta kutusunu okuduk (başka rem bölgesine aktardık)
Maskeleyip 1.kesmenin ile ilgili biti kontrol ettik.
Kontrol ettiğimiz biti sıfırlamak için yine maskeleme yaptik ve tam geri yerine yazacakken 2. kesme gerçekleşti

2. kesmeye girdik ,
Posta kutumuzun ilgili bitini set edip geri kaldığımız yere döndük

Kaldığımız yerde eski maskeyi posta kutusuna yazdırıyorduk,eski maskede 2. kesmenin biti set edilmemişti
Doğal olarak eski maskeyi yazmay devam ettik ve yazdık .

2. kesmeyi kontrol eden yere geldik
2.kesme görünmüyor,kaçırdık.....

Senaryoda mutlaka hata vardır ,ancak anlamak adına soruyorum. Burda yapılabilecek posta kutusunu modifiye ederken interruptları kapamak.
Ancak bit band ile interrupt kapamaya gerek kalmadan işlem gerçekleşiyor olarak anladım.Doğrumudur ?

z

Senaryo biraz karışık olmuş. Doğru anladıysam

Bir memory alanı, ana kodumuz haricinde interrupt rutini tarafından da kullanılıyorsa

Bu alana ulaşmadan önce int yasaklanmalı alana ulaşılıp işimiz bittiğinde intlara izin verilmelidir.

Bu işlemi bit banding yapacaksan hiç bir sorun yok çünkü bit bandingde sadece ve sadece 1 bit le oynanır ve bu oynama esnasında olabilecek interruptlar yapılan işlemi kesemez.

Bit manuplasyonu yapan klasik uygulamada ise (oku modifiye et yaz) eğer modifiye edilen aynı alan int rutinince de değiştiriliyorsa o zaman önce int ı yasaklayıp modifikasyon yapıp bitiminde int'a geri izin vermek gerekir.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

mcan

Alıntı yapılan: bunalmis - 03 Kasım 2011, 20:19:00
Senaryo biraz karışık olmuş. Doğru anladıysam

Bir memory alanı, ana kodumuz haricinde interrupt rutini tarafından da kullanılıyorsa

Bu alana ulaşmadan önce int yasaklanmalı alana ulaşılıp işimiz bittiğinde intlara izin verilmelidir.

Bu işlemi bit banding yapacaksan hiç bir sorun yok çünkü bit bandingde sadece ve sadece 1 bit le oynanır ve bu oynama esnasında olabilecek interruptlar yapılan işlemi kesemez.

Bit manuplasyonu yapan klasik uygulamada ise (oku modifiye et yaz) eğer modifiye edilen aynı alan int rutinince de değiştiriliyorsa o zaman önce int ı yasaklayıp modifikasyon yapıp bitiminde int'a geri izin vermek gerekir.

O zaman doğru anlamışım, ben bu bir bit uğruna yapılan işlemleri hiç sevmedim,masking banding neden koymamışlar direk komutunu,özellikle tek saat darbesinde gerçekleşmeyen işlemleri de hiç sevmem. 512 kb alan veriyorlar zaten 5-6 byte tı sadece bir biti set etmeye gidiyor .. :)

CLR

#394
Alıntı yapılan: bunalmis - 03 Kasım 2011, 13:30:54

eemkutayın istediği Bitbanding doğasına aykırı kod örneği aşağıda.

unsigned short* Bit_Adr(int Wadr,char BitNum)
{
      return((unsigned short*)(0x42000000 + ((Wadr - 0x40000000)<<5) + (BitNum<<2)));

int main()
{
unsigned short* P;       A=0;
     P=Bit_Adr((int)&GPIOD->ODR,2); // GPIOD nin 2 nolu bitinin adresini öğren gel
    *P=1;
   


eemkutay ve Gerbaydan yazmalarını rica ettiğim programları başlığa koyarlarsa, bitbanding için yapacağım özel kodlama zaten yukarıdaki tartışmaya da son noktayı vuracak nitelikte olacaktır.

Sanırım sorumu anlamamışsın veya işine gelmemiş. Diyosun ki "bit dandik" tek saykılda çalışıyor bende sana gerçek register adreslerini kullanarak hızlı çalışmasını bana ispatla dedim. Aslında amacım kullanışsız olduğunu göstermekti. Yazdığın C kodu ve asm karşılığı aşağıda. Ben hız ve verimlilik göremedim.  Altıüstü 2 tane biti set etmek için, verimli ve hızlı dediğin ve aşağıda sayısını saymaya üşendiğim asm'den mi oluşuyor.
Bu arada GpioD_Odr'nin adresini nereden aldın? Header'ı ben include etmek zorunda kaldım.

// Bu yazdığın bitbanding, bende performansını göreyim diye başka bir adres daha ekledim 

#include "stm32f10x.h"

unsigned short* Bit_Adr(int Wadr,char BitNum)
{
      return((unsigned short*)(0x42000000 + ((Wadr - 0x40000000)<<5) + (BitNum<<2)));
}  


int main()
{
	unsigned short* P; 


     P=Bit_Adr((int)&GPIOD->ODR,2); // GPIOD nin 2 nolu bitinin adresini öğren gel
    *P=1;

	P=Bit_Adr((int)&GPIOA->ODR,2); // GPIOD nin 2 nolu bitinin adresini öğren gel
    *P=1;

}


// asm karşılığı
//////////////////////////////////////////////Bu kısım yazdığın fonksiyon///////////////////////////////////
    21: { 
0x080001A4 4602      MOV      r2,r0
    22:       return((unsigned short*)(0x42000000 + ((Wadr - 0x40000000)<<5) + (BitNum<<2))); 
0x080001A6 F04F4384  MOV      r3,#0x42000000
0x080001AA EB031042  ADD      r0,r3,r2,LSL #5
0x080001AE EB000081  ADD      r0,r0,r1,LSL #2
    23: }   
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////Burası main kısmı/////////////////////////////////////////////////////////////
    26: int main() 
0x080001B2 4770      BX       lr
    27: { 
    28:         unsigned short* P;  
    29:  
    30:  
0x080001B4 B510      PUSH     {r4,lr}
    31:      P=Bit_Adr((int)&GPIOD->ODR,2); // GPIOD nin 2 nolu bitinin adresini öğren gel 
0x080001B6 4808      LDR      r0,[pc,#32]  ; @0x080001D8
0x080001B8 2102      MOVS     r1,#0x02
0x080001BA F7FFFFF3  BL.W     Bit_Adr (0x080001A4)
0x080001BE 4604      MOV      r4,r0
    32:     *P=1; 
    33:  
0x080001C0 2001      MOVS     r0,#0x01
0x080001C2 8020      STRH     r0,[r4,#0x00]
    34:         P=Bit_Adr((int)&GPIOA->ODR,2); // GPIOD nin 2 nolu bitinin adresini öğren gel 
0x080001C4 4805      LDR      r0,[pc,#20]  ; @0x080001DC
0x080001C6 2102      MOVS     r1,#0x02
0x080001C8 F7FFFFEC  BL.W     Bit_Adr (0x080001A4)
0x080001CC 4604      MOV      r4,r0
    35:     *P=1; 
    36:  
0x080001CE 2001      MOVS     r0,#0x01
0x080001D0 8020      STRH     r0,[r4,#0x00]
    37: }  

/////////////////////////////////////////////////////////////////////////////////////////


Knowledge and Experience are Power

z

eemkutay

bitbanding sana göre değil. Istedigin sartlarda sana avantaj sağlamaz. Cunku sen parametrik calisan kod istiyorsun.
Bitbanding bu amacla olusturulmamis. Istedigin programi tek cycle da isleyemeyecegini zaten basindan yazmistim. Bu yuzden sadece periperal adresler icin
bit adresinin nasil hesaplanacagini verdim. Bunu ise yarar bir programa donusturme kismini sana biraktim.

Benim soruma kodu yazdinmi?

Eger yazdiysan bitbanding avantajini hemen gosterecegim.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

#396
Silinebilir.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

#397
Tartışmanın kaynağı olan konu aşağıda.

Alıntı yapılan: eemkutay - 30 Ekim 2011, 23:06:21
Bit Banding'i keil ve iar'da denemiştim, zamanlama anlamında büyük bir avantaj getirmiyor. Maskele ile aynı sonuçları almıştım. Ama tabii belki sizi bit maskelemekten kurtarır fakat aynı şeyi güzel bir macro ile sizde yazabilirsiniz.

Şimdi olaya objektif yaklaşalım ve iki fonksiyon yazalım.

Bu fonksiyonların her biri parametre olarak register adresini, bit numarasını ve bitin alması gereken değeri istesin.

Fonksiyonlar verilen registerin verilen bit numarasındaki bitine verilen değeri atasın.

Tabiki birisi bitbanding işlemiyle, diğeri de klasik maskeleme yöntemiyle bu işi yapacak.

Bunun için aşağıdaki programı yazdım.

#include "STM32F4xx.h"
 
void SystemInit()
{
    RCC->AHB1ENR |= 0x00000008;    // GPIOD donanýmýnýn clock sinyalini uygulayalým
    GPIOD->MODER = 0x55000000;     // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
    GPIOD->OSPEEDR= 0xFFFFFFFF;   // GPIOD nin tum cikislari en yuksek hizda kullanacagiz 
}
 
void BitChg1(int Wadr,char BitNum, char BitVal)
{
      *((unsigned short*)(0x42000000 + ((Wadr - 0x40000000)<<5) + (BitNum<<2)))=BitVal;
}  
 
void BitChg2(int Wadr,char BitNum, char BitVal)
{
      *(unsigned short*)Wadr = ((*(unsigned short*)Wadr) & (~(1<<BitNum))) | (BitVal<<BitNum);
}  
  
 
int main()
{
      BitChg1((int)&GPIOD->ODR,12,1); // Bitbanding
      BitChg2((int)&GPIOD->ODR,12,1); // Maskeleme
}


Kodları derleyip fonksiyonlarımızın asm çıktılarına bakarsak;

Bitbanding için aşağıdaki asm kodları;

    10: void BitChg1(int Wadr,char BitNum, char BitVal) 
    11: { 
0x08000282 B510      PUSH          {r4,lr}
    12:       *((unsigned short*)(0x42000000 + ((Wadr - 0x40000000)<<5) + (BitNum<<2)))=BitVal; 
0x08000284 F04F4484  MOV           r4,#0x42000000
0x08000288 EB041340  ADD           r3,r4,r0,LSL #5
0x0800028C F8232021  STRH          r2,[r3,r1,LSL #2]
    13: }   
    14:
0x08000290 BD10      POP           {r4,pc}


Klasik maskeleme için ise aşağıdaki asm kodları elde ederiz.

    
    15: void BitChg2(int Wadr,char BitNum, char BitVal) 
    16: { 
0x08000292 B510      PUSH          {r4,lr}
    17:       *(unsigned short*)Wadr = ((*(unsigned short*)Wadr) & (~(1<<BitNum))) | (BitVal<<BitNum); 
0x08000294 8803      LDRH          r3,[r0,#0x00]
0x08000296 F04F0401  MOV           r4,#0x01
0x0800029A FA04F401  LSL           r4,r4,r1
0x0800029E EA230304  BIC           r3,r3,r4
0x080002A2 FA02F401  LSL           r4,r2,r1
0x080002A6 EA430304  ORR           r3,r3,r4
0x080002AA 8003      STRH          r3,[r0,#0x00]
    18: }   
0x080002AC BD10      POP           {r4,pc}


Aralarındaki farkı görmek için satır satır asm kodları sayınız. (Daha ileri gitmek isterseniz her kodun istediği clkları da hesaplayabilirsiniz.)

Üstelik Maskeleme yönteminde int enable ve int disable işlemini yapmadık. Bunu yapmadığımız takdirde bu fonksiyonun doğru çalışacağı garanti edilemez.

Bu örnek dahi bitbandingin avantajını göstermeye yetmiyorsa diyecek hiç bir şey bulamıyorum.

Öte yandan bir cycleda bir bitbanding yapmamı istiyorsanız lütfen ama lütfen sorduğum ve hala program olarak cevap vermediğiniz kod örneklerini yazınız.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

ErsinErce

#398
#include <stm32f4xx.h>

#define BITB_A(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOA->ODR) << 5) + ((b) << 2)))
#define BITB_B(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOB->ODR) << 5) + ((b) << 2)))
#define BITB_C(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOC->ODR) << 5) + ((b) << 2)))
#define BITB_D(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOD->ODR) << 5) + ((b) << 2)))
#define BITB_E(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOE->ODR) << 5) + ((b) << 2)))
void SystemInit(){

}
int main(void){
	while(1){
		BITB_A(0)=1;
		BITB_B(1)=0;
		BITB_C(2)=1;
		BITB_D(3)=0;
		BITB_A(0)=0;
		BITB_B(1)=1;
		BITB_C(2)=0;
		BITB_D(3)=1;
	}
}


Bunalmis hocam sizin kodlardan kopya çekerek yukarıdaki fonksiyonları yazdım,
Level1 ve sonrası optimizasyonlarda ilk adresleri ve 0,1 değerlerini yükleyerek 6 saykıl kaybediyor
sonra tek saykıl halinde dönmeye başlıyor, R12'e kadar önbelleği meşgul edemediğimden tam test yapamadım ama
max 3 saykıla kadar kullanabileceğimiz bir kısayol gibi gözüküyor şu anlık,

eğer işe yarar gözüküyorsa bir de siz inceleyebilir misiniz?

z

R12 ye kadar register işgal etmeye gerek yok.

Şimdi A registerinde 16 bit var. B de de C de de D de de.

Hiç ilave register kullanmadırmadan bunların her birinin her bir bitine 1 yada 0 atayabilirsin. Yeterki araya başka bir kod girme.

Zaten itirazlarının birisi bu. Araya kod girer diyorlar. Haklı olmak isterlerse haklılar.

İstediğim kodu yazacakları yok. Soru asağıdakiydi.

A[3] seklinde arrayim var.

A[0] ve A[1] in yuksek 4 biti sifirdir.

A[0]'nin dusuk bitleri, A3 A2 A1 A0
A[1]'nin dusuk bitleri, B3 B2 B1 B0  dir.

Program;

A[0] ve A[1] den alacagi bitleri A[2] icine A3 B0 A1 B2 A0 B1 A2 B3 siralamasiyla yazacaktir.

Uğraşmak istersen uğraş. Fakat bitbanding ile değil. Klasik usulle.

Bitbanding örneği ben yazdım cevap gelsin diye bekletiyorum.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

ErsinErce

#400
Alıntı yapılan: bunalmis - 04 Kasım 2011, 04:13:01
A[3] seklinde arrayim var.

A[0] ve A[1] in yuksek 4 biti sifirdir.

A[0]'nin dusuk bitleri, A3 A2 A1 A0
A[1]'nin dusuk bitleri, B3 B2 B1 B0  dir.

Program;

A[0] ve A[1] den alacagi bitleri A[2] icine A3 B0 A1 B2 A0 B1 A2 B3 siralamasiyla yazacaktir.

Uğraşmak istersen uğraş. Fakat bitbanding ile değil. Klasik usulle.

int main(void){
	union dizi{
		volatile unsigned char byte;
		struct{
			volatile unsigned A0:1;
			volatile unsigned A1:1;
			volatile unsigned A2:1;
			volatile unsigned A3:1;
			volatile unsigned A4:1;
			volatile unsigned A5:1;
			volatile unsigned A6:1;
			volatile unsigned A7:1;
		}A;
		struct{
			volatile unsigned B0:1;
			volatile unsigned B1:1;
			volatile unsigned B2:1;
			volatile unsigned B3:1;
			volatile unsigned B4:1;
			volatile unsigned B5:1;
			volatile unsigned B6:1;
			volatile unsigned B7:1;
		}B;
	};
	union dizi A[3];
	while(1){
		A[2].byte=(A[0].A.A3<<7)|(A[1].B.B0<<6)|(A[0].A.A1<<5)|(A[1].B.B2<<4)|
				  (A[0].A.A0<<3)|(A[1].B.B1<<2)|(A[0].A.A2<<1)|(A[1].B.B3);
	}
}

    37:                 A[2].byte=(A[0].A.A3<<7)|(A[1].B.B0<<6)|(A[0].A.A1<<5)|(A[1].B.B2<<4)| 
0x08000260 9800      LDR           r0,[sp,#0x00]
0x08000262 9901      LDR           r1,[sp,#0x04]
0x08000264 F3C000C0  UBFX          r0,r0,#3,#1
0x08000268 EA4F10C0  LSL           r0,r0,#7
0x0800026C F3C10100  UBFX          r1,r1,#0,#1
0x08000270 EA401081  ORR           r0,r0,r1,LSL #6
0x08000274 9900      LDR           r1,[sp,#0x00]
0x08000276 F3C10140  UBFX          r1,r1,#1,#1
0x0800027A EA401041  ORR           r0,r0,r1,LSL #5
0x0800027E 9901      LDR           r1,[sp,#0x04]
0x08000280 F3C10180  UBFX          r1,r1,#2,#1
0x08000284 EA401001  ORR           r0,r0,r1,LSL #4
0x08000288 9900      LDR           r1,[sp,#0x00]
0x0800028A F3C10100  UBFX          r1,r1,#0,#1
0x0800028E EA4000C1  ORR           r0,r0,r1,LSL #3
0x08000292 9901      LDR           r1,[sp,#0x04]
0x08000294 F3C10140  UBFX          r1,r1,#1,#1
0x08000298 EA400081  ORR           r0,r0,r1,LSL #2
0x0800029C 9900      LDR           r1,[sp,#0x00]
0x0800029E F3C10180  UBFX          r1,r1,#2,#1
0x080002A2 EA400041  ORR           r0,r0,r1,LSL #1
0x080002A6 9901      LDR           r1,[sp,#0x04]
0x080002A8 F3C101C0  UBFX          r1,r1,#3,#1
0x080002AC EA400001  ORR           r0,r0,r1
0x080002B0 F88D0008  STRB          r0,[sp,#0x08]
0x080002B4 E7D4      B             0x08000260


bu kadar sürüyor sürmüyor şimdi farkettim tamam doğruymuş uykusuzluk vurmaya başladı galiba :)

z

Kodlarin cok guzel sonuc cikartmis. Fakat bu sonuclara bakinca soruyu dogru sormadigimi farkettim. Cunku sorum sadece bit tasima seklinde olmus.
Boyle olunca da hic maskeleme yapmadan kodu yazma sansin dogmus. (Bu benim hatam)

Soruyu degistirmek istememin sebebi, bitband islemler sonucunda elde ettigim kodlarin, senin kodlarindan sadece  3 yada 4 satir daha kisa olusu.
Bu bitbanding icin ezici bir sonuc degil. Arada bariz fark olusturmak icin sorumda kucuk bir degisiklik yapacagim fakat su anda ben de cok uykusuzum yarin devam edelim.
(Yarin sorunun mevcut hali icin bendeki kodlari ya yazacagim.)


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

gambit1244

bunalmis hocam
bu tartışmaları takip etmelimiyiz? burda yazılan biçok şeyi anlayamadım çünkü
asm kodlar, bitler, bandingler havada uçuşuyor
düşük seviyedeki arkadaşlar olarak şimdilik pasmı geçiyoruz bu konuları? ileride tekrar değinecekmiyiz?
[email]tufan_ozbek@hotmail.com[/email] Yesterday is history. Tomorrow is a mystery. Today is a gift aslında bütün mesele bu.

CLR

#403
Alıntı yapılan: bunalmis - 04 Kasım 2011, 00:49:40
eemkutay

bitbanding sana göre değil. Istedigin sartlarda sana avantaj sağlamaz. Cunku sen parametrik calisan kod istiyorsun.
Bitbanding bu amacla olusturulmamis. Istedigin programi tek cycle da isleyemeyecegini zaten basindan yazmistim. Bu yuzden sadece periperal adresler icin
bit adresinin nasil hesaplanacagini verdim. Bunu ise yarar bir programa donusturme kismini sana biraktim.

Benim soruma kodu yazdinmi?

Eger yazdiysan bitbanding avantajini hemen gosterecegim.

Aşağıya yazdım , hemde low optimizasyon seviyesinde yazdım. Senin gibi 2 tane biti while içine alıp hazırlama kısımlarını while dışında bırakan level 3 optimizasyon kullanmadan. Topu topu 20 tane asm komutu yetti de arttı bile. Hemde yazdığım kodda tüm parametreler değiştirilebilir, anlaşılır , 32bit sayılarla uğraşmadan ve hızlı.

Şimdi yukarıda söylediğin gibi bana bitbanding'in avantajını hemen göster. (sözlerle değil asm ile)


// C file 
struct XBits{
  unsigned char Bit0:1;
  unsigned char Bit1:1;
  unsigned char Bit2:1;
  unsigned char Bit3:1;  
  unsigned char Bit4:1;
  unsigned char Bit5:1;
  unsigned char Bit6:1;
  unsigned char Bit7:1;
};

union RegsUni
{
  unsigned char Byte;
  struct XBits Bits;
  
};



#define Abits A[0]
#define Bbits A[1]
 
int main()
{
      union RegsUni A[3];
      
      while(1)
          {
            A[2].Byte=Abits.Bits.Bit3<<7|Abits.Bits.Bit1<<6|Abits.Bits.Bit0<<5|Abits.Bits.Bit2<<4|
                      Bbits.Bits.Bit0<<3|Bbits.Bits.Bit2<<2|Bbits.Bits.Bit1<<1|Bbits.Bits.Bit3;
           }                                         
}               



//Asm file
main:
         0x40: 0xb081         SUB       SP, SP, #0x4
            A[2].Byte=Abits.Bits.Bit3<<7|Abits.Bits.Bit1<<6|Abits.Bits.Bit0<<5|Abits.Bits.Bit2<<4|
                      Bbits.Bits.Bit0<<3|Bbits.Bits.Bit2<<2|Bbits.Bits.Bit1<<1|Bbits.Bits.Bit3;
??main_0:
         0x42: 0xf89d 0x0000  LDRB.W    R0, [SP]
         0x46: 0xb2c0         UXTB      R0, R0
         0x48: 0x08c0         LSRS      R0, R0, #3
         0x4a: 0xf89d 0x1000  LDRB.W    R1, [SP]
         0x4e: 0xf3c1 0x0140  UBFX      R1, R1, #1, #1
         0x52: 0x0189         LSLS      R1, R1, #6
         0x54: 0xea51 0x10c0  ORRS.W    R0, R1, R0, LSL #7
         0x58: 0xf89d 0x1000  LDRB.W    R1, [SP]
         0x5c: 0xf011 0x0101  ANDS.W    R1, R1, #1
         0x60: 0xea50 0x1041  ORRS.W    R0, R0, R1, LSL #5
         0x64: 0xf89d 0x1000  LDRB.W    R1, [SP]
         0x68: 0xf3c1 0x0180  UBFX      R1, R1, #2, #1
         0x6c: 0xea50 0x1001  ORRS.W    R0, R0, R1, LSL #4
         0x70: 0xf89d 0x1001  LDRB.W    R1, [SP, #0x1]
         0x74: 0xf011 0x0101  ANDS.W    R1, R1, #1
         0x78: 0xea50 0x00c1  ORRS.W    R0, R0, R1, LSL #3
         0x7c: 0xf89d 0x1001  LDRB.W    R1, [SP, #0x1]
         0x80: 0xf3c1 0x0180  UBFX      R1, R1, #2, #1
         0x84: 0xea50 0x0081  ORRS.W    R0, R0, R1, LSL #2
         0x88: 0xf89d 0x1001  LDRB.W    R1, [SP, #0x1]

         0xda: 0xe7b2         B.N       ??main_0                ; 0x42

Knowledge and Experience are Power

z

ErsinErce'ye yazdığım, soruda değişiklik yapmam gerektiğini belirttiğim mesajı okumadınız mı?

Ayrıca daha üstündeki bitbanding ve maskelemeli klasik yöntem için verdiğim karşılaştırmalı program örneklerinin de avantajı anlaman için yeterli olacağını sanıyordum.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com