assembly etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
assembly etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
22 Aralık 2010 Çarşamba
Oyun Programlama Seminerleri (5. Oturum)
About this playlist
9 videos
Total length: 1 hour, 26 minutes
Description: Sakarya Üniversitesi Bilgisayar Mühendisliği 3 Boyutlu Oyun Motoru Programlama Seminerleri 5. Oturumu
Oturum Konusu: OpenGL
Toplam Uzunluk: 01:30:30
21 Aralık 2010 Salı
Oyun Programlama Seminerleri (4. Oturum)
About this playlist
9 videos
Total length: 1 hour, 31 minutes
Description:
Sakarya Üniversitesi Bilgisayar Mühendisliği 3 Boyutlu Oyun Motoru Programlama Seminerleri 4. Oturumu
Oturum Konusu: Sayısal Sistemler ve Sistem Programlama
Toplam Uzunluk: 01:31:46
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:
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
Projemizi derlemek için komut satırına bazı komutlar girmemiz gerekecek. Bu işlemin otomasyonu için şöyle bir batch dosya oluşturabiliriz.
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:
Şimdi benzer bir çağırı programını C++ dilinde dinamik çağırma yöntemiyle yapalım.
C# tarafında işler çok daha kolay:
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:
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:
Bu toplama fonksiyonunu (parametreli) çağıran C++ uygulaması:
Şimdilik basit bir girişle yetiniyorum. Umarım devamında detaylandırabilirim...
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...
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...
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...
Etiketler:
assembly,
c,
c++,
disassembly,
dword ptr,
microsoft,
visual studio
Kaydol:
Kayıtlar (Atom)