Assembler DLLs für BB

Übersicht BlitzBasic FAQ und Tutorials

Neue Antwort erstellen

Willi die Rübe

Betreff: Assembler DLLs für BB

BeitragSo, Aug 03, 2008 15:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Um hier auch mal etwas mehr oder weniger sinnvolles beizusteuern, hab ich mal ein kleines HowTo geschrieben, für alle die mal die Lust verspüren Assembler in ihren Projekten einzubauen.

Assemblerkentnisse sind für den richtigen Einsatz natürlich aufjeden Fall Pflicht, allerdings denke ich, dass dieses HowTo hier auch für andere interessant sein könnte. Zum Einsatz kommt hier FASM, wobei ich allerdings versuche auf die Makros verzichten, damit die Portierung in andere Assembler nicht allzuschwer sein dürfte.

Nun denn, beginnen wir mit dem Header:
Code: [AUSKLAPPEN]
format PE GUI 4.0 DLL
entry DllMain

Die erste Zeile gibt das Dateimodell für den Assembler an und in der zweiten Zeile wird der Einstiegspunkt festgelegt, in BB muss dieser DllMain lauten, sonst stützt das Programm ab. Wink

Gehen wir mal davon aus, wie benötigen keine zusätzlichen Variablen und beginnen gleich mit dem Codeblock:
Code: [AUSKLAPPEN]
section '.code' code readable executable

  DllMain:                 ; obligatorische DllMain Funktion
        mov eax,1
        ret
Kleine Information: Wenn das eax Register auf 0 ist, wird die Dll nicht gestartet.

Dann können wir unsere Funktionen zusammenbasteln. Zum Test mal eine simple Additionsfunktion:
Code: [AUSKLAPPEN]
MyAdd:
        push ebp         ;alten Basepointer im Stack speichern
        mov ebp,esp      ;neuer Basepointer = Stackpointer
        add esp,8        ;  Stackpointer um die Größe der Parameter erhöhen(2xDouble Words=8 Byte)
        pop eax          ;  Erster Parameter vom Stack in eax speichern
        pop ebx          ;  Zweiter Parameter vom Stack in ebx speichern
        add eax,ebx      ;  Register addieren; Ergebnis in eax
        mov esp,ebp      ;neuer Stackpointer = aktueller Basepointer
        pop ebp          ;alten Basepointer vom Stack wiederherstellen       
    ret
Hab es mal für alle die kein ASM beherrschen ein wenig überkommentiert.

Wichtig: Übergebene Parameter werden von BB auf den Stack geschoben, von wo man sie zur Benutzung in der Funktion wieder runterholen muss.
Den Rückgabewert holt BB dann aus dem eax Register.

So, nun wirds schon etwas verzwickter, denn jetzt kommt der Exportblock.

Der Aufbau des Headers ist strikt vorgegeben und noch relativ uninteressant:
Code: [AUSKLAPPEN]
section '.edata' export data readable

   dd 0            ; Unbenutzt
   dd 0            ; Zeitstempel(optional)
   dd 0            ; Unbenutzt/ eigt. Versionsinformationen
   dd RVA dllname  ; relative virtuelle Addresse(RVA) des DLL Dateinamens
   dd 0            ; Beginn der Zuordnungszahlen
   dd 1            ; Anzahl der Funktionen
   dd 1            ; Anzahl der Funktionsnamen 

   dd RVA ExportAdressTable  ; RVA der Adressentabelle(EAT)
   dd RVA ExportNamesTable   ; RVA der Namentabelle(ENT)
   dd RVA Ordinals           ; RVA zur Zuordnungstabelle
Eine RVA ist eine (zur Startadresse des Programmes relative) Adresse im Ram.

Danach können wir auch gleich schon unser dllname Label von oben definieren:
Code: [AUSKLAPPEN]
   dllname db 'test.dll',0

Nun kommen wir zu dem interessanten Teil, nämlich unsere drei Tabellen bzw. genauergenommen eigentlich Arrays:

ENT(Namenstabelle): Hier drin stehen die RVAs der Namenlabels, unter denen man später die Funktionen importiert. Die Einträge müssen alphabetisch korrekt sortiert sein, sonst kann es vorkommen, dass Windows die Funktion nicht findet.

Zuordnungszahlentabelle: Die Einträge sind in paralleler Reihenfolge mit denen der ENT verknüpft. Der Wert selber verweißt auf einen Eintrag in der EAT.

EAT(Adressentabelle): Hier stehen die RVAs der Funktionen selbst drin.


Lange Erklärung, kurzer Code:
Code: [AUSKLAPPEN]
 ExportNamesTable:
    dd RVA _MyAdd  ; RVA des Funktionsnamens
 Ordinals:
    dw 0           ; Zuordnungszahl
 ExportAdressTable:
    dd RVA MyAdd   ; RVA der Funktion

 _MyAdd db 'MyAdd',0        ;Funktionsname


Aufgrund der Tatsache, dass wir in unserem Beispiel nur eine Funktion haben, sieht dies noch recht einfach aus. Machen wir mal ein anderes Beispiel:
Code: [AUSKLAPPEN]
; Funktionsnamen/adressen Anzahl im Header müssen natürlich angepasst werden!

ExportNamesTable:     ; Alphabetische Reihenfolge
    dd RVA _HisAdd
    dd RVA _MyAdd
    dd RVA _OurAdd
    dd RVA _TheirAdd
    dd RVA _YourAdd
Ordinals:
    dw 2 ; HisAdd ist der dritte Eintrag in der EAT
    dw 0 ; MyAdd ist der erste Eintrag in der EAT
    dw 3 ; usw.
    dw 4
    dw 1
ExportAdressTable:
    dd RVA MyAdd
    dd RVA YourAdd
    dd RVA HisAdd
    dd RVA OurAdd
    dd RVA TheirAdd

 _MyAdd       db 'MyAdd',0
 _YourAdd     db 'YourAdd',0
 _HisAdd      db 'HisAdd',0
 _OurAdd      db 'OurAdd',0
 _TheirAdd    db 'TheirAdd',0   
Sieht doch gleich viel witziger aus, oder nicht? Very Happy

Dann belassen wir es mal hierbei und putzen den Ram:
Code: [AUSKLAPPEN]
section '.reloc' fixups data discardable


Unser kompletter Code sieht dann so aus:
Code: [AUSKLAPPEN]
format PE GUI 4.0 DLL
entry DllMain

section '.code' code readable executable

DllMain:
        mov eax,1
        ret

MyAdd:
        push ebp
        mov ebp,esp
        add esp,8
        pop eax
        pop ebx
        add eax,ebx
        mov esp,ebp
        pop ebp
    ret


section '.edata' export data readable

   dd 0
   dd 0
   dd 0
   dd RVA dllname
   dd 0
   dd 1
   dd 1


   dd RVA ExportAdressTable
   dd RVA ExportNamesTable
   dd RVA Ordinals

   dllname db 'test.dll',0

   ExportNamesTable:
    dd RVA _MyAdd
   Ordinals:
    dw 0
  ExportAdressTable:
    dd RVA MyAdd

    _MyAdd db 'MyAdd',0

section '.reloc' fixups data discardable

Dies können wir nun kompilieren(FASM erkennt anhand vom Header automatisch, dass es sich um eine DLL handelt).


Die dazugehörige Userlib:
Code: [AUSKLAPPEN]
.lib "test.dll"
Add%(value1%,value2%):"MyAdd"


Und folgender Code funktioniert:
Code: [AUSKLAPPEN]
Print Add(-14,15)
WaitKey()
End


Perfekt Very Happy
----------------------------------------------------------------

Ein Vorteil von FASM sind natürlich die Macros mit der sich sehr viel vereinfachen lässt. Mithilfe von Macros würde der Code so aussehen:

Code: [AUSKLAPPEN]
format PE GUI 4.0 DLL
entry DllMain

include '%fasminc%\win32a.inc'

section '.code' code readable executable

proc DllMain
      mov eax,TRUE
      ret
endp

proc MyAdd value1,value2
     mov eax, [value1]
     add eax, [value2]
    ret
endp

section '.edata' export data readable
  export 'test.dll',\
         MyAdd, 'MyAdd'
section '.reloc' fixups data discardable
Sieht also schon wesentlich übersichtlicher und verständlicher aus.
----------------------------------------------------------------

So weit so gut, Feedback, Fragen, Kritik oder irgendwelche Fehler bitte hier posten.
Mfg
Willi
Ich habe keine Lösung, aber ich bewundere das Problem.
Tehadon
Q6600, MSI Neo2-FR, 4GB Ram, nVidia 7800 GTX

At the Farewell Party visit: MySpace | Homepage
 

Kaddy

BeitragSo, Jun 21, 2009 11:20
Antworten mit Zitat
Benutzer-Profile anzeigen
kleine frage^^

Wenn ich jetz in bb mit assemblern arbeite und dies dann übersetze habe ich doch den gleichen effeckt also die exe bleibt unverändert, oder wie das ganze system nahe angesteuert?
ich meine ist es das gleiche im endeffeckt wenn ich

Code: [AUSKLAPPEN]
DATA SEGMENT             
Meldung db "Hello World"   
        db "$"             
DATA ENDS               
CODE SEGMENT           
ASSUME CS:CODE,DS:DATA   
Anfang:                   
mov ax, DATA               
mov ds, ax                 
mov dx, offset Meldung     ;
mov ah, 09h               
int 21h                   
mov ax, 4C00h             
int 21h                   
CODE ENDS             
END Anfang               


oder

Code: [AUSKLAPPEN]

Print "Hello World"
waitkey
end


verwände?

müsste das ganze nicht dann auch auf linux laufen wenn ich es dann übersetze oder ist und bleibt es dann einfach nur ein bb prog .D

ich hoffe es war verständlich wie ich es meinte[/code]
Bin Aktuell auf der Suche nach einen Programmierer Team, ob Hobby Team oder Firma ist egal. Einfach eine PM an mich schreiben.
Bezahlung verlange ich NATÜRLICH keine Wink

Es gibt 10 arten von Menschen, die einen verstehen das Binärsystem , die anderen nicht SmileSmile

flona

BeitragSo, Jun 21, 2009 12:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Nein es läuft nicht auf Linux, da der Compiler nur unter Windows läuft und auch nur auf Windows ausführbare Dateien erstellt. Die ganzen Header der EXE und was weiß ich läuft nicht unter Linux(Korrigiert mich wenn ich falsch liege).
Außerdem bin ich mir sicher, dass BB nicht mit Interupts wie in deinem Beispiel arbeitet, sondern mit WinApi Befehlen(WriteConsole, ...).
Zu deiner Frage ob die Datei dann anders ist: Die Runtimefunktionen wie Print, WaitKey, ... werden immer IN die EXE eingebunden. Wenn du das ganze als Dll in ASM schreibst ist der Code in der Dll Datei AUSgelagert, die dann wiederrum von BB dynamisch eingebunden wird.

Ich hoffe ich habe mich nicht allzu unverständlich ausgedrückt Wink
www.Dreier-Florian.kilu.de
Intel Core 2 Quad Q9400 | Zotac 9800GT | 4GB RAM | 1TB HDD | Windows 7 Professional 32bit

Tankbuster

BeitragSo, Jun 21, 2009 12:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Assembler kannst du direkt an den Prozessor schicken, aber Windows-Executables laufen eben nur unter Windows, da Windows sie erstmal interpretieren muss, und dann an den Prozessor schickt.

Zitat:
müsste das ganze nicht dann auch auf linux laufen wenn ich es dann übersetze oder ist und bleibt es dann einfach nur ein bb prog .D


Durch diese Methode hier, erreichst du einfach, dass dein ASM-Code auf Windows einfach so als Windows-Executable ausgeführt werden kann. Das ganze wird hinterher ja als .exe kompiliert.
Außerdem sind die Blitz-exen immer ziemlich groß, da noch der ganze Funktionsumfang von Blitz mit eingebunden ist.


Auf Linux wird das ganze daher nicht laufen Wink
Twitter
Download Jewel Snake!
Windows|Android
 

Kaddy

BeitragSo, Jun 21, 2009 20:34
Antworten mit Zitat
Benutzer-Profile anzeigen
vielen dank für die antworten.
Also bleibt es ebend Blitz Very Happy
Das wäre jetz natürlich zu schön gewesen die Blitz ide als assembler zu verwänden ^^
Bin Aktuell auf der Suche nach einen Programmierer Team, ob Hobby Team oder Firma ist egal. Einfach eine PM an mich schreiben.
Bezahlung verlange ich NATÜRLICH keine Wink

Es gibt 10 arten von Menschen, die einen verstehen das Binärsystem , die anderen nicht SmileSmile

Neue Antwort erstellen


Übersicht BlitzBasic FAQ und Tutorials

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group