Bu Blogda Ara

c etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
c etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

15 Mayıs 2010 Cumartesi

Bağlı Listeler

Merhabalar,
Bu yazımda sizlere bağlı liste veri yapısından bahsedeceğim. Veri yapısı deyince kulağa egzotik gelebilir. Ama inanın bildiğiniz şeylerden farklı bir şey anlatmayacağım. "Bildiklerimizi bir araya getirerek bilmediğimiz bir yapıyı tanımlama" şeklinde anlıyorum veri yapılarını...

Nedir? Neden gerek duyulmuştur?
Bağlı liste veri yapısı hafızanın farklı bölgelerinde bulunan verileri birbirine katar şeklinde bağlayan yapıdır.Dizi vb. yapılar zaten bu işi sağlamıyor mu? şeklinde bir soru aklınıza tam bu satırda gelmiş olmalı. Evet sağlıyor ama bir yere kadar. Diziler hafızanın belirli bir noktasında ardışıl olarak gelir. Yani dizinin ilk elemanı hafızanın 100 nolu adresinde bulunuyorsa dizinin ikinci elemanı 101 nolu gözde bulunacaktır. Ayrıca diziler ilk oluşturulduğunda uzunluğu belli olmak zorundadır. Daha sonra genişleme imkanı yoktur. Ancak tekrar boyutlandırma yapılabilir ki bu iş oldukça maliyetlidir. İşte böyle dinamik genişleyen ucuz maliyetli bir yapıya ihtiyaç duyulduğu sırada keşfedilmiş olmalı bağlı listeler.

Bağlı derken?
Bağlı listenin her bir elemanı hafızada birbirine bir sonraki elemanın aderesini gösterecek bilgiye sahiptir. Biz yalnızca ilk elemanın adresini biliriz. İkinci elemana ulaşmak için önce birinci elemana gideriz, ondan bir sonraki yani ikinici elemanın adresini alırız daha sonra ikinci elemana ulaşabiliriz. Üç, dört, beş ... hafıza dolana kadar üretilebilir, ulaşım mekanizması hep aynı. Bağlı derken bu mekanizma kastediliyor.

İhtiyaca göre...
Sorunlar farklı olunca çözümler, dolayısıyla gereksinimler de farklı oluyor. Bağlı liste veri yapısı iki çeşittir. Tek yönlü ve çift yönlü. İlkinde sadece ileri yönlü haraket yapmak mümkünken ikinci tipde geri gelme de mümkündür. Siz kendi probleminize en uygun tipi seçmelisiniz.

Bırak gevezeliği de biraz kod yaz!

Tek yönlü bağlı liste, C örneği

#include <stdio.h>
#include <stdlib.h>

typedef struct _eleman
{
struct _eleman *sornakiEleman; // bir sonraki elemanı işaret eder.
int veri; // yapının sakladığı veri. istenilen tipte istenildiği kadar veri eklenebilir.
} eleman;

typedef struct
{
eleman *ilkEleman; // bağlı listeyi temsil eden yapı. Yalnızca ilk elemanı işaret ediyor.
} bagliListe;

bagliListe *bagliListeUret();
void elemanEkle(bagliListe*,int);
void elemanCikart(bagliListe*,int);
void listele(bagliListe*);

int main()
{
bagliListe * bl = bagliListeUret(); // yeni bir bağlı liste ürettik.
elemanEkle(bl,6); // eleman ekleyelim.
elemanEkle(bl,34);
elemanEkle(bl,987);
elemanEkle(bl,5);
elemanEkle(bl,2);
listele(bl); // listele.
system("pause");
elemanCikart(bl,3); // 3. elemanı çıkart. ( ilk eleman 0'dan başlar)
listele(bl); // tekrar listele, farkı gör.
system("pause");
}

bagliListe *bagliListeUret()
{
bagliListe* bl = (bagliListe*)malloc(sizeof(bagliListe)); // yeni bir bağlı listeyi hafızada oluşturup ilgili adresi alıyoruz.
bl->ilkEleman = NULL;
return bl;
}

void elemanEkle(bagliListe* bl,int veri)
{
eleman *e = (eleman*)malloc(sizeof(eleman)); // yeni bir eleman oluşturalım.
e->sornakiEleman = NULL;
e->veri = veri;
eleman *son = NULL; // katarın son elemanı.
son = (eleman *)bl->ilkEleman; // başlangıç elemanını bağlı listeden alalım.
if (son==NULL) // listemiz boş mu?
{
bl->ilkEleman = e;
return;
}
while(son!=NULL) // değilse özyinelemeli olarak son elemana erişmeye çalış.
{
if (son->sornakiEleman==NULL)
break;
son = (eleman*)son->sornakiEleman; // düğümler arası atlama.
}
son->sornakiEleman = e; // nihayet son düğümün işaretçisine kendi adresimizi yazıyoruz.
}

void listele(bagliListe* bl)
{
eleman *e = NULL;
e=(eleman *)bl->ilkEleman;
int i=0;
while(e!=NULL) // özyinelemeli listeleme fonksiyonu.
{
printf("%i. eleman verisi = %i\n",i++,e->veri);
e = (eleman*) e->sornakiEleman;
}
}

void elemanCikart(bagliListe * bl, int sira)
{
eleman *e = NULL;
e=(eleman *)bl->ilkEleman;
eleman *onceki = NULL;
int i=0;
if (e==NULL) // listemiz boş mu?
{
printf("Liste bos oldugu icin cikartma yapilamiyor!\n");
return;
}
while(e!=NULL)
{
if (i==sira)
break;
i++;
onceki = e;
e = (eleman*) e->sornakiEleman;
}
onceki->sornakiEleman = e->sornakiEleman; // silmek istediğimiz elemanın bir önceki düğümü ile bir sonraki düğümü birbirine bağlıyoruz. Böylelikle aradan çekilerek silinmiş izlenimi oluşturuluyor.
free(e); // hafıza sızıntısını önlemek için serbert bıraktığımız elemanı hafızadan silmeyi unutmayalım.

}


Diğer yüksek seviyeli dillerde (Java, C# vb.) bu veri yapısını yapmak çok daha kolay. Mantıktan yola çıkarak o dillerde de sorunsuz bir şekilde bağlı liste veri yapısını oluşturabileceğinize inanıyorum.
Görüşmek üzere...

27 Nisan 2010 Salı

Dynamic-Link Library (DLL) / Giriş

DLL dosyaları Microsoft'un Windows ve OS/2 işletim sistemleri için gerçeklediği kütüphane paylaşım konsepti olarak tanımlanabilir. Bu kütüphaneler genellikle DLL, OCX ya da DRV uzuntasındadır.

DLL dosyaları aynen EXE dosyaları gibi kod, veri ve kaynak bölümlerine (ve bunların herhangi bir kombinasyonunda) olabilir.

Windows işletim sisteminin ilk sürümlerinde tüm programlar tek bir bellek bölgesinde koşturuluyordu. İşletim sistemi düzeyindeki tüm işlemler MS-DOS tarafından gerçekleştirilirken yüksek seviyeli hizmetler Windows DLL leri tarafından sağlanıyordu. Çizim API'leri yani GDI.EXE, kullanıcı arayüzü işlemleri USER32.EXE adlı kütüphane dosyasında gerçeklenmiştir.


Günümüzde daha farklı bir yaklaşım kullanılmaktadır. Sistem tarafından sunulan kütüphaneler uygulamalara ayrı ayrı yüklenmektedir. Korumalı modda olduğu için bir program başka bir programın hafıza alanına doğrudan bir müdehalede bulunamıyor.

Assembly dilinde basit bir mesaj gösteren DLL uygulaması şu şekilde olabilir:


.386 ; intel x86 architecture
.model flat,stdcall ; use flat memory management
option casemap:none ; ignore letter case

include \masm32\include\windows.inc
include \masm32\include\user32.inc ; for MessageBox func.
include \masm32\include\kernel32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

.data
message db "Test message...",0 ; content of our simple message

.code
DllEntry proc hInstance:HINSTANCE, reason:WORD, reserved1:WORD ; DLL entry point function
mov eax,TRUE
ret
DllEntry Endp

SimpleMessage proc
invoke MessageBox,NULL,addr message,NULL,MB_OK ; win32 MessageBox func.
ret
SimpleMessage Endp

End DllEntry




Bu programı derlemek için birde def dosyası oluşturmalıyız. Bu dosyada 2 satır bilgi gerekiyor. Birinci satırda kütüphanenin ismini ikinci satırda ise kütüphaneden dışarı aktarılacak yani diğer programların hizmetine sunuculacak olan fonksiyonların isimleri.

örnek olarak

LIBRARY Simple
EXPORTS SimpleMessage


Projemizi derlemek için komut satırına bazı komutlar girmemiz gerekecek. Bu işlemin otomasyonu için şöyle bir batch dosya oluşturabiliriz.


c:\masm32\bin\ml.exe /c /coff /Cp "%CD%\Simple.asm"
c:\masm32\bin\link.exe /DLL /DEF:"%CD%\Simple.def" /SUBSYSTEM:WINDOWS /LIBPATH:c:\masm32\lib "%CD%\Simple.obj"


Not: Bu uygulamayı derleyebilmeniz için sisteminizde Masm32 derleyicisi yüklü durumda olmalıdır. http://www.masm32.com/

Şimdi oluşturduğumuz bu DLL dosyasını başka bir programdan çağıralım. Bunun için çağırı yapacak programımızı derlerken DLL dosyamızın yapısını bildirmek üzere bir .lib dosyası vereceğiz. Bu dosya DLL projemizi derlerken derleyici tarafından otomatik olarak oluşturulmaktadır.

Kısa basit bir örnek:

.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib Simple.lib ; lib file of Simple.dll to inform linker
includelib \masm32\lib\kernel32.lib

SimpleMessage PROTO ; name of the function in DLL

.code
start:
invoke SimpleMessage ; invoke the function in DLL
invoke ExitProcess,NULL ; terminate process
end start




Şimdi benzer bir çağırı programını C++ dilinde dinamik çağırma yöntemiyle yapalım.


#include <stdio.h>
#include <windows.h>

typedef void (WINAPI *SimpleMessage)(); // type defination to call dll function.

int main(int argc, char **argv)
{
HINSTANCE hDLL = LoadLibrary(L"simple.dll"); // loads our DLL into application memory section.
SimpleMessage sm = (SimpleMessage)GetProcAddress(hDLL,"SimpleMessage"); // gets address of our function in the dll.
if (!sm) // function address validation.
{
printf("Couldn't load library!\n");
}
else
{
sm(); // simple call.
}
return 0;
}



C# tarafında işler çok daha kolay:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace SimpleCall
{
class Program
{
[DllImport("simple.dll")]
static extern void SimpleMessage();

static void Main(string[] args)
{
SimpleMessage();
}
}
}


Java tarafında direk bir erişim şekli mevcut değil. Bunun yerine bazı 3. parti kütüphaneleri kullabiliriz. Bunlar JNI (Java Native Interface) tabanlı kütüphaneler. Biz bu örnekte JNA (Java Native Access) kullanacağız.

Bu kütüphanenin açıklamasını daha önceki bir yazımda (Bkz: http://rbellek.blogspot.com/2010/04/java-native-access-basit-ornek.html) bahsettiğim için burada yüzeysel geçiyorum.

Örnek uygulama:


//Main.java
package simple;

import com.sun.jna.Native;

public class Main {

public static void main(String[] args)
{
Simple simpleDLL = (Simple)Native.loadLibrary("e:\\Simple.dll", Simple.class);
simpleDLL.SimpleMessage();
}
}



//Simple.java
package simple;

import com.sun.jna.Library;

public interface Simple extends Library {
void SimpleMessage();
}



DLL dosyasının aynı EXE dosyaları gibi bir giriş noktları mevcuttur. Bu noktanın adı DllEntry adlı bir fonksiyondur. Ve giriş parametreleri olarak şu 4 değerden birini almaktadır.

DLL_PROCESS_ATTACH
DLL_PROCESS_DETACH
DLL_THREAD_ATTACH
DLL_THREAD_DETACH

Basit bir toplama kütüphanesi:


.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

.data
AppName db "Simple 2",0
HelloMsg db "Hello, you're calling a function in this DLL",0
LoadMsg db "The DLL is loaded",0
UnloadMsg db "The DLL is unloaded",0
ThreadCreated db "A thread is created in this process",0
ThreadDestroyed db "A thread is destroyed in this process",0

.code
DllEntry proc hInstance:HINSTANCE, reason:DWORD, reserved1:DWORD
.if reason==DLL_PROCESS_ATTACH
invoke MessageBox,NULL,addr LoadMsg,addr AppName,MB_OK
.elseif reason==DLL_PROCESS_DETACH
invoke MessageBox,NULL,addr UnloadMsg,addr AppName,MB_OK
.elseif reason==DLL_THREAD_ATTACH
invoke MessageBox,NULL,addr ThreadCreated,addr AppName,MB_OK
.else ; DLL_THREAD_DETACH
invoke MessageBox,NULL,addr ThreadDestroyed,addr AppName,MB_OK
.endif
mov eax,TRUE
ret
DllEntry Endp

Addition proc param1:DWORD, param2:DWORD
mov ebx,param1
mov eax,param2
add eax,ebx
ret
Addition endp
End DllEntry




Bu toplama fonksiyonunu (parametreli) çağıran C++ uygulaması:


#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

typedef int (WINAPI* Addition)(int,int); // two DWORD (32-bit integer) in parameters
// WINAPI same as __stdcall
// __stdcall gives order of parameters in stack
int main(int argc, char **argv)
{
HINSTANCE hDLL = LoadLibrary(L"calculator.dll");
Addition addition = (Addition)GetProcAddress(hDLL,"Addition");
if (!addition)
{
printf("Couldn't load library!");
}
else
{
printf("5 + 9 = %i",addition(5,9)); // simple two parameter call
}
return EXIT_SUCCESS;
}



Şimdilik basit bir girişle yetiniyorum. Umarım devamında detaylandırabilirim...

4 Nisan 2010 Pazar

Java Native Access Basit Örnek

Java ile program geliştirmek çok rahat ve güvenilir olabilir. Fakat diğer tüm yorumlamaya dayalı diller gibi(C# vs.) Java'da doğrudan makine diline çevrilen programlama dilleri kadar hızlı değildir. Hız söz konusu değilse tabiki hiç bir sorun yok. Fakat bizim için hız önemli olduğunda ne yapacağız?
a)Java vb. dilleri bırak, C/C++ ya da Delphi gibi dilleri kullan.
b)Kullandığın dillerden vazgeçme gerekli bölgeyi soyutla.

Ben b şıkkını seçiyorum :) Peki b şıkkında anlatamak istediğim nedir?

Örneğin bir program geliştreceğiz. Bu programda çok ağır matematiksek işlemler var. Bunları Java ile yaptığımız zaman istediğimiz sürede istediğimiz verimlilikte sonuçlar alamıyoruz. Öyle ise bize sıkıntı çıkartan kısmı alıp, C/C++, Delphi ya da bir başka donanıma yakın olan bir dil ile yazıyoruz. Bu yazdığımız bölümü DLL olarak oluşturuyoruz. Artık tek yapmamız gereken Java projemizden bu DLL içerisindeki gerekli fonksiyonları zamanı geldiğinde çağırmak.

Bunu yapmamız için Sun Microsystems tarafından yazılmış bir kütüphane mevcut. JNA (Java Native Access). Bu kütüphane ile sabit disk üzerideki (başka bir dil ile yazılmış) DLL dosyalarındaki fonksiyınları çağırabiliyoruz.

Şimdi yamamız gereken temel adımlardan bahsedeyim.

1) Bir java projesi oluşturalım.
2) https://jna.dev.java.net/ adresinden JAR dosyasını sabit diskimize indirelim.
3) İndirdiğimiz kütüphaneyi projemize ekleyelim.
(NetBeans 6.8 için ekleme)
Libraries (sağ tık) -> Add JAR/Folder...


4) Projemizde bir interface oluşturarak kullanacağımız fonksiyonların tanımlamasını yapmalım.
5) İhtiyacımız olan fonksiyonu çağıralım. :)

Örnek bir kod parçası:

import com.sun.jna.*;

public class testMessage {

public interface Simple extends Library
{
public void TestMessage();
}

public static void main(String[] args)
{
Simple dll = (Simple)Native.loadLibrary("Simple.dll", Simple.class);
dll.TestMessage();
}

}


Bu kadar basit. JNA ile yalnızca Windows değil MacOS X, Linux ve Unix platformlarında da çalışabilirsiniz. Yanlız hata kontrolünü çok iyi tutmak gerekiyor. Lakin benim bir kaç denememde JVM (java.exe) çökmesi gibi durumlarla karşılaştım. Çünkü direk düşük seviye işlemleri yapılıyor. Java için son olarak birde JNI (Java Native Interface) var. Kendi yazdığımız C programlarına direk erişim için. Onu kısmet olursa başka bir zaman anlatmayı düşünüyorum.

C# tarafında da aynı olayın mümkün olduğunu söyleyebilirim. Orada işler biraz daha basit. Herhangi bir kütüphane kullanmanıza gerek yok. Yapı şu şekilde:

[DllImport("Simple.dll")]
static extern int TestMessage();

static void Main(string[] args)
{
TestMessage();
}


Sonuç olarak Java, C# vb. dillerin görsellik, güvenilirlik ve diğer mükemmel özelliklerini alıp, hantallık gibi diğer kötü özelliklerini bu sistemle değiştirmiş oluyoruz. Her sistemin güzel özelliğini bir araya getirerek çok kaliteli ürünler ortaya çıkarmak mümkün.

Winapi: WinExec

Merhaba bu yazımda WinExec fonksiyonunu inceliyeceğiz.

Teknik detaylara geçmeden önce özetle bu fonksiyonun görevinden bahsedeyim. Bu fonksiyon ile yeni bir uygulamayı başlatabiliyoruz. Başlattığımız uygulama fonksiyonu çağıran uygulama ile aynı yetkilere sahip oluyor.

Fonksiyonun yapısı:

UINT WINAPI WinExec(
__in LPCSTR lpCmdLine,
__in UINT uCmdShow
);


2 adet parametre alıyor. Bunlardan birincisi çalıştıracağımız uygulamanın sabit disk üzerindeki tam adresini ifade ediyor.

typedef __nullterminated CONST CHAR *LPCSTR, *PCSTR;

İkinci parametre ise açacağımızın uygulamanın başlama durumunu belirtmektedir. Örnek olarak simge durumunda, tam ekran ya da görünmez olarak başlatabiliriz.


#define SW_HIDE 0 // gizli
#define SW_SHOWNORMAL 1 // normal
#define SW_NORMAL 1
#define SW_SHOWMINIMIZED 2 // simge durumunda
#define SW_SHOWMAXIMIZED 3 // tam ekran
#define SW_MAXIMIZE 3
#define SW_SHOWNOACTIVATE 4 // normal gösterim ile aynı, tek farkı aktif olmaması
#define SW_SHOW 5 // gösterir (pencere gizli bile olsa)
#define SW_MINIMIZE 6 // simge durumuna getirir
#define SW_SHOWMINNOACTIVE 7 // simge durumuyla aynı, tek farkı aktif değil
#define SW_SHOWNA 8 // gösterir, aktif değil
#define SW_RESTORE 9 // simge durumundan kurtarır
#define SW_SHOWDEFAULT 10 // uygulamanın orijinal açılış değeri (CreateProcess'te kullanılan...)
#define SW_FORCEMINIMIZE 11 // simge durumuna zorlar (uygulama yanıt vermese bile)
#define SW_MAX 11 // tam ekrana zorlar (uygulama yanıt vermese bile)


Bu fonksiyonu kullanabilmek için C/C++ uygulamanıza WinBase.h (Windows.h içerisinde mevcut) başlık dosyasını eklemeniz gereklidir. WinApi kernel32.dll içerisindedir.

Windows 2000 Professional ve üzeri bir işletim sisteminde çalıştırılabilir.

Olası hata kodları ve açıklamaları:

0 Sistem kaynakları ya da hafızası yetersiz.

ERROR_BAD_FORMAT .exe dosyası geçersiz.

ERROR_FILE_NOT_FOUND Belirtilen dosya bulunamadı.

ERROR_PATH_NOT_FOUND Belirtilen yol bulunmadı.


Hemen basit bir uygulama yapalım.

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>


int main(int argc, char **argv)
{
long hata = WinExec("notepad.exe",SW_NORMAL);

switch(hata)
{
case 0: printf("Sistem kaynakları ya da hafızası yetersiz.\n"); break;
case ERROR_BAD_FORMAT: printf(".exe dosyası geçersiz.\n"); break;
case ERROR_FILE_NOT_FOUND: printf("Belirtilen dosya bulunamadı.\n"); break;
case ERROR_PATH_NOT_FOUND: printf("Belirtilen yol bulunmadı.\n"); break;
default: printf("Uygulama başarıyla çalıştırıldı.\n");
}

system("pause");
return 0;
}


Not: Bu uygulama Microsoft Visual Studio 2008 Express Edition üzerinden test edilmiştir.

2 Nisan 2010 Cuma

C/C++ uygulamalarında Assembly komutları

Herkese merhaba,

C/C++ uygulamaları, genellikle hız ve performans gerektiren uygulamaların geliştirilmesinde kullanılan temel dillerdir. Donanıma yakın olmak isteyen bir programcı ya makine diline en yakın olan assembly ile günlerini harcayarak en hızlı ama güvenilir olmayan uygulamalar ortaya koyacaktır ya da C/C++ gibi bir programlama diliyle assembly diline yakın bir performansı daha hızlı ve bir nebze olsun daha güvenli uygulamalar geliştirecektir.

Bu yazımda sizlere Visual Studio geliştirme ortamında C/C++ uygulamaları içerinde Assembly komutlaranı nasıl kullanacağımızı göstermeye çalışacağım. Amacım Assembly dilini anlatmak değildir. Yalnızca bu komutları C/C++ uygulamalarında kullanmayı göstermektir.

Peki bir programcı buna neden gerek duyar? Hızdan ve performanstan bahsettik. Eğer çok fazla işlemi çok kısa bir sürede yapmak istiyorsak, programlarımızdan elimizden geldiğince gereksiz kodları çıkartmamız gerekcektir. Ne kadar gereksiz kodları programımızdan çıkartsakta bazı kodlar bizim isteğimizin dışında programa derleme zamanında yerleşmektedir. Bunlar derleyiciler tarafından optimize edilmiş genel amaçlı komutlardır. Eğer bir sistem ya da grafik programcısı gibi hız gerektiren bir iş yapmak istiyorsanız bu komutlarıda optimize etmelisiniz. Lafı daha fazla dolaştırmadan örneğimize geçelim.

Öncelikle herhangi bir C/C++ projesi oluşturalım. Bu konsol ya da görsel bir proje olabilir. Daha önce bahsettiğim derleyicilerin bizden habersiz programımıza eklediği kodları görmeliyiz. Bunun için Visual Studio geliştirme ortamının Disassembly özelliğini kullanacağız. Bu pencereyi programınızı debug ederken (herhangi bir satıra breakpoint koyarak) ister Alt + 8 tuş kombinasyonları ile ister Debug -> Windows -> Disassembly menüsünden açabilirsiniz. Bu pencere ile yazmış olduğunuz C/C++ uygulamasının kaynak kodlarına karşılık üretilen Assembly kodları görünmektedir.

Not: Bu proje Microsoft Visual Studio 2008 Express Edition ile oluşturulmuştur.








Şimdi kendi assembly komutlarımızı girelim. Bir C/C++ uygulamasında assembly komutları kullanmak için
__asm
{
... komutlar ...
}

şeklinde bir yapı kullanarak derleyiciyi uyarıyoruz.

Şimdi basit bir örneği inceleyelim. 32-bit Integer bir değişkene assembly ile değer atayalım.




MOV komutu ile akümülatöre 7 değerini atadık. Burada akümülatörü EAX ile ifade ederek 32-bit kelime işleyeceğimiz belirttik. Böylelikle 7 değeri 32-bit integer olarak akümülatöre atandı. Daha sonra bu değeri a değişkenine yine MOV komutu ile aktardık. Hepsi bu.

Şimdi biraz daha derine inip bir pointer (işaretçi) kullanarak bu işi nasıl yapacağımıza bakalım.




Bu örnekte akümülatöre b işaretçisinin adresini atadık. Bu atamayı yaparken DWORD PTR anahtar kelimelerini kullandık. Burada DWORD (double word - çift kelime) 32-bit uzunluğunda , PTR ise bir pointer (işaretçi) gösterdiğini belirtiyor. Derleyicimiz b işaretçisinin gösterdiği alana gidiyor ve oradaki 4 byte (32-bit) veri ile işlem yapıyor. Daha sonra bu adresin gösterdiği alana 9 değerini girerek a değişkenini dolaylı olarak değiştirmiş oluyoruz.

Böylelikle bir giriş yapmış olduk. Bir sonraki yazılarda daha derin işlemleri yaparak ışık hızında uygulamaları göstermek istiyorum.

Görüşmek üzere...