25 Kasım 2013 Pazartesi

C++ ile Assembly Kodu Çalıştırma



                C++ ile assembly kodlarımızı çalıştırmak için 2 seçeneğimiz var. Bunlardan ilki direk C/C++ kodumuzun içine _asm yazarak assembly kodlarımızı dahil etmektir. Diğeri ise projemize eklediğimiz .asm dosyasından assembly kodlarımızı çalıştırmaktır. Öncelikle bunlardan zahmetsiz olan ilk yönteme bakalım:

1.Yöntem

                Bu işlem için yapmamız gereken tek şey kodumuzun içerisine aşağıda olduğu gibi _asm yazmak ve süslü parantez ile açıp kapamak. Sonrasında içerisine assembly kodumuzu yazarak rahatlıkla çalıştırabiliriz.

Örnek 1: Çarpımlarının 2 fazlası

#include <iostream>

using namespace std;

int asmdenal(int,int);

int main()
{
       cout<<"Alınan değer  "<<asmdenal(3,8);
}

int asmdenal(int t1,int t2)
{
       _asm
       {
             mov eax,t1;
             mov ebx,t2;
             imul eax,ebx;
             add eax,2;
             mov t2,eax;
       }
       return t2;
}

Örnek 2: a , b , c değerlerini yığın kullanarak değiştiriyor.

#include <iostream>

using namespace std;

void Asmdenal(int,int,int);

int main()
{
       Asmdenal(30,8,12);
}

void Asmdenal(int a,int b,int c)
{
       cout<<"a : " <<a<<endl<<"b : "<<b<<endl<<"c : "<<c<<endl<<endl;
       _asm
       {
             mov eax,a;
             mov ebx,b;
             mov ecx,c;
             push eax;
             push ebx;
             push ecx;
             pop eax;
             pop ebx;
             pop ecx;
             mov a,eax;
             mov b,ebx;
             mov c,ecx;
       }
       cout<<"a : " <<a<<endl<<"b : "<<b<<endl<<"c : "<<c<<endl<<endl;
}

2.Yöntem

                Bu yöntemde Visual Studio dan yeni bir boş c++ projesi oluşturuyorum. Daha sonra Solution Explorer penceremdeki projemin üzerine gelip sağ tık ile AddàNew Item kısmından C++ (cpp) dosyası oluşturuyorum.





                Hemen ardından aynı şekilde sağ tık AddàNew Item diyerek bu seferde Name kısmına “deneme.asm” yazıyorum ve asm dosyamı oluşturuyorum.



                Şimdi oluşturduğum C++(.cpp) dosyama kodlarımı yazıyorum:

#include <iostream>

using namespace std;

extern "C" int Carp(int,int,int);// deneme.asm dosyasına link oluşturur.

int main()
{
       cout<<"Carpım Sonucu : "<<Carp(2,8,9)<<endl;
}

extern "C" int Carp(int,int,int) ile asm dosyama link oluşturuyorum. Aynı zamanda 3 integer değer alan ve integer değer dönderen bir Carp fonksiyonuda tanımlamış olduk.

Şimdi de deneme.asm dosyamın içerisine aşağıdaki gibi kodlarımı yazıyorum:

.model flat,C              ;"C" ifadesi Asm dosyamızdan C/C++ dosyamıza link oluşturur.
.code

Carp proc ,\               ;Fonksiyonun başlangıcı
s1:dword,s2:dword,s3:dword ;Gelen üç değerin boyutunun ayarlanması(double word olarak)
mov eax,s1
mov ebx,s2
mov ecx,s3
imul eax,ebx
imul eax,ecx
ret                               
Carp endp
end

                Bu hali ile çalıştırırsak eğer bize aşağıdaki gibi 2 hata verecektir ve program çalışmayacaktır.



                Bu hataları vermesinin sebebi ise bizim asm dosyamızı programın derleyememesidir. Bu problemi çözmek için yine projemizin üzerine gelip sağ tık ile Build Customizations seçeneğini seçiyoruz. Burada gelen 2 seçeneğe de tik atarak Ok butonuna basalım. Biz bu işlem ile asm dosyamızı derleyecek olan masm(Microsoft Assembler) ı etkin hale getirmiş olduk. Daha sonra yine Solution Explorer da projeme eklediğim deneme.asm dosyamın üzerinde sağ tık ile Properties seçeneğini seçiyorum. Açılan pencerede Item type kısmını Microsoft Macro Assembler olarak değiştiriyorum ve uygula diyorum. Şimdi problem çözülmüş oldu. Artık derleyip sonucu görebilirsiniz!





             Özetle dikkat edilmesi gereken hususlar:
  • C/C++ dan link eklemeyi unutmamalı
  • Asm dosyasından link eklemeyi unutmamalı
  •  Masm aktif hale getirilmeli


Bu uygulamalar 32 bit için yapılmıştır. 64 bitte çalıştırabilmek ve 64 bit registerlarını kullanabilmek için BuildàConfugration Manager i seçiyoruz ve aşağıdaki gibi Win32 yazan kısma tıklayıp New diyoruz , yeni açılan pencereden de ARM yazan kısmı x64 olarak değiştiriyoruz.  


15 Kasım 2013 Cuma

C++ Örnekleri 3 Pointers


1)

#include <stdio.h>

int main() {
    int a = 7;
    int *aptr;
  
    aptr = &a;
  
    printf("A nın değeri:%d  adresi:%p",a,&a);
    printf("\n *aptr nin değeri : %d  adresi :%p",*aptr,aptr);
    return 0;
}

2)

#include <stdio.h>

int kup(int *kupo);

int main() {
    int sayi = 5;
  
    printf("Sayının esas değeri %d\n",sayi);
    kup(&sayi);
    printf("Sayının değeri %d\n",sayi);
  
    return 0;
}

int kup(int *kupo) {
    *kupo = *kupo * *kupo * *kupo;
    return *kupo;

}

3)

//Fonksiyonları gösteren göstericiler kullanan çok amaçlı bir sıralama fonksiyonu//

#include <stdio.h>
#define boyut 10

void kab(int a[], const int b, int (*)(int c, int d));
int artan(int, int);
int azalan(int, int);

int main() {
    int secim, say, a[boyut] = {2, 6, 4, 8, 10, 12, 89, 68, 45, 37};
    printf("Artan sıralama için 1 i "
            "\nAzalan sıralama için 2 yi seçin:\n");
    scanf("%d", &secim);
    for (say = 0; say < boyut; say++)
        printf("%5d", a[say]);
    if (secim == 1) {
        kab(a, boyut, artan);
        printf("\nVeriler artan sırada :\n");
    } else {
        kab(a, boyut, azalan);
        printf("\nAzalan sırada :\n");
    }
    for (say = 0; say < boyut; say++)
        printf("%5d", a[say]);
    printf("\n");
    return 0;
}

void kab(int is[], const int b, int (*karsilastir)(int c, int d)) {
    int tur, i;
    void yer(int *, int *);
    for (tur = 0; tur < boyut - 1; tur++)
        for (i = 0; i < boyut - 1; i++)
            if ((*karsilastir)(is[i], is[i + 1]))
                yer(&is[i], &is[i + 1]);
}

void yer(int *el1, int *el2) {
    int temp;
    temp = *el1;
    *el1 = *el2;
    *el2 = temp;
}

int artan(int a, int b) {
    return b < a;
}

int azalan(int a, int b) {
    return b > a;

}

4)

#include <stdio.h>
#define boyut 10

void sira(int *a,const int b);
void deg(int *,int *);
int main() {
    int dizi[boyut] = {2,4,6,24,85,90,12,23,45,89 };
    int i;
  
    printf("Orjinal sırada:\n");
    for(i = 0;i < boyut;i++){
        printf("%5d",dizi[i]);
    }
    sira(dizi,boyut);
    printf("\nSıralı hali :\n");
    for(i = 0;i < boyut;i++) {
        printf("%5d",dizi[i]);
    }
    return 0;
}

void sira(int *a,const int b) {
  
    int tur,j;
    for(tur = 0;tur < boyut-1;tur++)
        for(j = 0;j < boyut-1;j++)
            if(a[j] > a[j+1])
                deg(&a[j],&a[j+1]);
     
}

void deg(int *el1,int *el2) {
    int temp = *el1;
    *el1 = *el2;
    *el2 = temp;

}

5)

#include <stdio.h>
#include <ctype.h>

void buyuk(char *a);

int main(){
    char string[20];
    printf("Birşeyler yazınız:");
    scanf("%s",string);
    printf("Orjinal hali : %s\n",string);
    buyuk(string);
    printf("Son hali:%s",string);
  
    return 0;
}

void buyuk(char *a){
    while(*a != '\0') {
        if(islower(*a))
            *a = toupper(*a);
            ++a;
      
    }

}

6)

#include <stdio.h>

void copy1(char *s1,const char *s2);
void copy2(char *s1,const char *s2);

int main() {
    char string1[10];
    char *string2 = "Hello";
    char string3[10];
    char string4[] = "Good bye";
  
    copy1(string1,string2);
    printf("string = %s\n",string1);
  
    copy2(string3,string4);
    printf("string3 = %s\n",string3);
  
    return 0;
}

void copy1(char *s1,const char *s2) {
    int i;
    for(i = 0;(s1[i] = s2[i]) != '\0';i++) {
        ;
    }
}

void copy2(char *s1,const char *s2) {
    for(;(*s1 = *s2) != '\0';s1++,s2++) {
        ;
    }

}