Cortex M3 işlemciler için C içinde asm fonksiyon yazma

Başlatan bunalmis, 06 Mayıs 2011, 13:24:24

z

Keil'de Cortex M3 işlemciler için C kodlarının arasında inline asm yazamıyoruz fakat doğrudan asm fonksiyon yazılabiliyormuş.
Şimdiye kadar asm fonksiyonları  asm dosya içinde yazıyordum. Şimdi bu kodları C program içine asm fonksiyon olarak yazmak istiyorum.

Fakat beceremedim.

Örneğin  fonk1 fonksiyonu, integer tipinde global değişken olan var1 i R0 reg icine okusun ve fonksiyon değeri olarak döndürsün.

R0 icine var1 i nasil okuyacağız?

int __asm Fonk1()
{
  ??????
}



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

mufitsozen

Alıntı yapılan: bunalmis - 06 Mayıs 2011, 13:24:24
Keil'de C kodlarının arasında inline asm yazamıyoruz fakat doğrudan asm fonksiyon yazılabiliyormuş.
Şimdiye kadar asm fonksiyonları  asm dosya içinde yazıyordum. Şimdi bu kodları C program içine asm fonksiyon olarak yazmak istiyorum.

Fakat beceremedim.

Örneğin  fonk1 fonksiyonu, integer tipinde global değişken olan var1 i R0 reg icine okusun ve fonksiyon değeri olarak döndürsün.

R0 icine var1 i nasil okuyacağız?

int __asm Fonk1()
{
  ??????
}

keil user guide'da verilen ornek soyle:

1- inline assembly:

int f(int x)
{
    int r0;
    __asm
    {
        ADD r0, x, 1
        EOR x, r0, x
    }
    return x;
}

==========================================

2- embedded assembly

#include <stdio.h>
__asm void my_strcpy(const char *src, char *dst)
{
loop
      LDRB  r2, [r0], #1
      STRB  r2, [r1], #1
      CMP   r2, #0
      BNE   loop
      BX    lr
}
int main(void)
{
    const char *a = "Hello world!";
    char b[20];
    my_strcpy (a, b);
    printf("Original string: '%s'\n", a);
    printf("Copied   string: '%s'\n", b);
    return 0;
}
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

z

Fakat amacım global bir değişken okumak. Fonksiyona parametre olarak Global değişken adresi de yollamak istemiyorum.


(Bu arada CM3 işlemci kullanıyorum)


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

mufitsozen

Alıntı yapılan: bunalmis - 06 Mayıs 2011, 14:02:44
Fakat amacım global bir değişken okumak. Fonksiyona parametre olarak Global değişken adresi de yollamak istemiyorum.


(Bu arada CM3 işlemci kullanıyorum)

user manual o zamanda _cpp keyword kullan der! bu keyword soylendigi kadari ile IMPORT kelimesinide otomatik yaratiyor imis!

====================================

Example 6.3.  __cpp(expr)

LDR r0, =__cpp(&some_variable)  <<<<========= Bu sizin aradiginiz degilmi?
LDR r1, =__cpp(some_function)
BL  __cpp(some_function)
MOV r0, #__cpp(some_constant_expr)


Names in the __cpp expression are looked up in the C++ context of the __asm function. Any names in the result of a __cpp expression are mangled as required and automatically have IMPORT statements generated for them.

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

z

Tesekkurler  LDR r0, =__cpp(&some_variable) işimi gördü.

Bu bilgiye nasıl ulaştınız? Keil help ile bir sıkıntım var. Bunu zamanında yazmıştım fakat cevap çıkmadı.

https://www.picproje.org/index.php/topic,31365.0.html

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

mufitsozen

#5
Alıntı yapılan: bunalmis - 06 Mayıs 2011, 16:06:30
Tesekkurler  LDR r0, =__cpp(&some_variable) işimi gördü.

Bu bilgiye nasıl ulaştınız? Keil help ile bir sıkıntım var. Bunu zamanında yazmıştım fakat cevap çıkmadı.

https://www.picproje.org/index.php/topic,31365.0.html

Keil-"support" sitesinde butun kullanim kilavuzlari var
embedded assembler vs diye arayinca cikiyor
daha sabirli iseniz, butun bolum basliklarina bakarakda ayni bilgiyi bulmak mumkun

birde tabi 35 senedir ingilizce teknik kitap vs okumakdan hizli okuma ve bilgiyi bulma aliskanligi var (maalesef ODTUde okumanin biraktigi bir aliskanlik)

Aslinda sizin probleminiz ANCI C++ ile PCde yazsaydinizda ortaya cikabilirdi, cunku C++ derleyicileri, global degisken ve fonksiyon isimlerini "mangle" eder (yani bozar) @gerbay vakti olsada bu konuda soyle dise dokunur bir yazi yazsa herkesde faydalanirdi


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

z

Bu açıklamalardan sonra;

Asm fonksiyon içinde Var1 isimli integer değişkenin içeriği lazım olduğunda aşağıdaki örnekten yararlanabiliriz.

int var1;

int __asm Fonk1()
{
       LDR  R1=__cpp(&Var1)    ; Var1 degiskeninin adresini ogrendik
       LDR  R1,[R1]                    ; Var1 degiskeninin icerigini ogrendik 
       ....
       .... 
       BX    LR 
}


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

z

CPU registerlerinin tanımlı olduğu header dosyasında aşağıdakine benzer tanımlar var.

#define ADR  (*((volatile unsigned short *) 0x12345678))

C içinde asm fonksiyon yazmak ister ve bu fonksiyonda da R0 registeri içine 0x12345678 yüklenebilmesini teminen ADR ismini kullanmak istersek nasıl bir satır yazabiliriz?

LDR R0,=ADR yada  LDR R0,=__cpp(&ADR)  yazımlar hatalı, doğrusunu yazmayı bilmiyorum.


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

mufitsozen

Alıntı yapılan: bunalmis - 06 Mayıs 2011, 18:43:40
CPU registerlerinin tanımlı olduğu header dosyasında aşağıdakine benzer tanımlar var.

#define ADR  (*((volatile unsigned short *) 0x12345678))

C içinde asm fonksiyon yazmak ister ve bu fonksiyonda da R0 registeri içine 0x12345678 yüklenebilmesini teminen ADR ismini kullanmak istersek nasıl bir satır yazabiliriz?

LDR R0,=ADR yada  LDR R0,=__cpp(&ADR)  yazımlar hatalı, doğrusunu yazmayı bilmiyorum.

ADR bir macro oldugu icin integer literal gibi yuklemeniz lazim
ADR kullanarak olmaz
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

z

Eğer yazılamayacağından eminsek yüzlerce kb lık header dosyasını degiştirmek zorunda kalacağım.

#define ADR  (*((volatile unsigned short *) 0x12345678))

tanımı, sonrasında  C satırları içinde ADR=0x01 yazarsak,  0x12345678 adresindeki 16 bitlik registere 0x0001 yazımını gerçekleştiriyor.

Var1=ADR yazdıgımızda ise 0x12345678 adresindeki 16 bitlik register okunuyor ve okunan değer Var1 içine atanıyor.

Eğer asm fonksiyondan asm komutlarla ADR registerine erişmek istersem ADR yi bir türlü kabul ettiremiyorum.

Bu durumda header dosyayı yeni baştan düzeltmem gerekecek, öyle bir tanım yapayım ki aynı tanımı hem C de hem de asm de kullanabileyim.

Örneğin

#define ADR  0x12345678

tanımı yaparsam

Var1=  (*((volatile unsigned short *) ADR kullanabilirim.

Bunu da daha anlamlı kılmak için

#define Reg (*((volatile unsigned short *)

Var1=Reg(ADR); yazmam gerekecek.

Fakat daha yakışıklı ve özellikle de header dosyadaki tanımlara dokunmadan bu soruna çözüm getirebilirsem çok iyi olacak.


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

z

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

mufitsozen

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

z

Senin hakkini da yememek lazim. __cpp yi de senin sayende ogrendik.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com