Herkese hayırlı cumalar. Uzun süredir üzerinde fikir yürüttüğüm ancak bir türlü faaliyete geçirmekte sıkıntı çektiğim bir konuyu gece saatlerinde çözüme ulaştırmış bulunmaktayım lakin şunu belirtmekte fayda var derleme konusundaki çözümleri ve Assembly dilindeki cahiliyetimizi aydınlatan Grok 'a burada saygı & sevgilerimi iletiyorum. Geçmişte açmış olduğum bir konunun benzerini farklı bir dille sizlerle paylaşmak istedim. Burada gerçekleşen olay Assembly dilinde kodlanmış olan bir dosyanın DLL olarak derlenmesi ardından C# formu üzerinde tanımlanarak matematiksel 4 işlem yapması. Matematiksel işlemi yapan Assembly DLL 'si sonucu verdirmesini sağlayan ise C# form olacak. ( Geçmiş konuya gitmek için bana tıkla. )
Konumuza geçmeden önce indirmemiz gereken bazı dosyalar var bunlardan ilki NASM. Peki neden NASM?
- Nasm kodları herhangi bir yürütülebilir dosyayı IDA, X64Dbg, Ghidra gibi tersine mühendislik araçlarına yansıttığınız zaman karşınıza gelen çıktının Nasm adlı derleyicinin içerisinde barındırdığı fonksiyonlara benzemesinden dolayı.
İndirdikten sonra gelelim DLL oluşturmaya... Bunun için Nasm 'ın kurulu olduğu klasör üzerinde math.asm adlı bir dosya açıp içerisine aşağıdaki kodları gireceğiz.
Kod:
; math.asm - Windows 64-bit NASM DLL: Toplama, Çıkarma, Çarpma, Bölme
; Derleme: nasm -f win64 math.asm -o math.obj
; Bağlama: link /dll /noentry /out:math.dll math.obj /def:math.def /libpath:"C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.43.34808\lib\x64" /libpath:"C:\Program Files (x86)\Windows Kits\10\lib\10.0.22621.0\um\x64"
bits 64
global Add
global Subtract
global Multiply
global Divide
section .text
; long Add(long a, long b)
; a: rcx, b: rdx, dönüş: rax
Add:
mov rax, rcx ; a'yı rax'e al
add rax, rdx ; b'yi ekle
jo overflow_error ; Taşma varsa hata
ret ; Sonuç rax'te
; long Subtract(long a, long b)
; a: rcx, b: rdx, dönüş: rax
Subtract:
mov rax, rcx ; a'yı rax'e al
sub rax, rdx ; b'yi çıkar
jo overflow_error ; Taşma varsa hata
ret ; Sonuç rax'te
; long Multiply(long a, long b)
; a: rcx, b: rdx, dönüş: rax
Multiply:
mov rax, rcx ; a'yı rax'e al
imul rax, rdx ; b ile çarp (signed)
jo overflow_error ; Taşma varsa hata
ret ; Sonuç rax'te
; long Divide(long a, long b)
; a: rcx, b: rdx, dönüş: rax
Divide:
cmp rdx, 0 ; b sıfır mı? (sıfıra bölme kontrolü)
je divide_by_zero ; Sıfıra bölme hatası
mov rax, rcx ; a'yı rax'e al
cqo ; rax'i 128-bit'e genişlet (rdx:rax)
idiv rdx ; rax = rax / rdx (signed bölme)
jo overflow_error ; Taşma varsa hata
ret ; Sonuç rax'te
overflow_error:
mov rax, 0x8000000000000000 ; Hata kodu: -2^63 (taşma)
ret
divide_by_zero:
mov rax, 0x8000000000000001 ; Hata kodu: -2^63 + 1 (sıfıra bölme)
ret
Ardından bir adet math.def dosyası oluşturun bu bize fonksiyon başlıklarını tanımlamamızı sağlayacak olan verileri içerisine gireceğiz. Görüldüğü üzere toplama, çıkarma gibi 4 işlemin İngilizce karşılıklarına bakıyoruz.
Kod:
LIBRARY math.dll
EXPORTS
Add
Subtract
Multiply
Divide
Dosyalarımızı oluşturduktan sonra Visual Studio 'nun geliştirici komut penceresini kullanarak bir DLL oluşturacağız. Bunun için Visual Studio 'yu açalım karşımıza gelen pencereden kodsuz olarak devam et diyelim ardından yukarıda yer alan sekmelerden Araçlar --> Komut Satırı --> Geliştirici Komut İstemi diyelim.
[ GÖRSEL GÖSTERİM ]
İlk komutumuz obj uzantısını oluşumu bunun için komut istemi üzerinde;
Kod:
nasm -f win64 math.asm -o math.obj
Daha sonra DLL oluşturmak için aşağıdaki kodu girelim;
Kod:
link /dll /noentry /out:math.dll math.obj /def:math.def /libpath:"C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.43.34808\lib\x64" /libpath:"C:\Program Files (x86)\Windows Kits\10\lib\10.0.22621.0\um\x64"
Artık DLL dosyamız hazır. Şimdi C# kullanarak bir form oluşturalım & Yapılandırma Yöneticisi üzerinden Platform seçeneğimizi x64 olarak seçelim yoksa projemiz hata verir. ( Yapılandırma Yöneticisi Ayarı İçin Bana Tıkla ) Bu işlemleri yaptıktan sonra formumuza;
2 adet textbox matematiksel işlemlerin yapılması için,
1 adet buton işlemi başlatmak için,
1 adet ComboBox ekleyelim Items(Koleksiyon) kısmına şunları yazalım;
Topla
Çıkar
Çarp
Böl
Sonuçları görmek içinse 1 adet label ekleyelim.
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Runtime.InteropServices;using System.Windows.Forms;using System.Threading.Tasks;using static System.Windows.Forms.VisualStyles.VisualStyleElement;partial class altına oluşturmuş olduğumuz DLL 'i & fonksiyonlarını tanımlayalım.
C#:
[DllImport("math.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern long Add(long a, long b);
[DllImport("math.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern long Subtract(long a, long b);
[DllImport("math.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern long Multiply(long a, long b);
[DllImport("math.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern long Divide(long a, long b);
Daha sonra buton içerisine aşağıdaki kodu girelim & sonuçları gözleyelim.
C#:
if (!long.TryParse(textBox1.Text, out long a) || !long.TryParse(textBox2.Text, out long b))
{
MessageBox.Show("Lütfen geçerli sayılar girin!", "Hata", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
long result;
string operation = comboBox1.SelectedItem.ToString();
try
{
switch (operation)
{
case "Topla":
result = Add(a, b);
break;
case "Çıkar":
result = Subtract(a, b);
break;
case "Çarp":
result = Multiply(a, b);
break;
case "Böl":
result = Divide(a, b);
break;
default:
MessageBox.Show("Lütfen bir işlem seçin!", "Hata", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
label1.Text = $"Sonuç: {result}";
}
catch (DllNotFoundException)
{
MessageBox.Show("math.dll bulunamadı! DLL dosyasını proje klasörüne kopyalayın.", "Hata", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show($"Beklenmeyen hata: {ex.Message}", "Hata", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
[ GÖRSEL GÖSTERİM ]
-TEŞEKKÜRLER-
-TEŞEKKÜRLER-
Son düzenleme:



