Assembler mit FASM.dll

  • Hi zusammen,

    HIER kann man die FASM.dll herunterladen. Mit dem angehängten Script erhält man einen aus AutoIt aufrufbaren Assembler.

    Es sind, ausser der DLL, keine weiteren Includes nötig!
    Der Assemblercode kann sowohl als Text (z.B. aus einer Datei), oder direkt eingegeben werden, wird auf Fehler untersucht und dann sofort per DllCallAddress() ausgeführt. Aufruf aus AutoIt als Einzeiler natürlich ^^

    Bitte mal einfachen 64-Bit-Code testen (ich kann das zzt. nicht), soll dieser Assembler auch können! Aufrufkonventionen beachten!

    Spoiler anzeigen
    [autoit]


    ;fasm.dll hier:
    ;http://board.flatassembler.net/topic.php?t=6239

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;asm-code als string
    Global $sourcetext = _ ;pseudo-Random, Rückgabe in EAX
    "use32" & @CRLF & _ ;32 bit
    "mov ecx,[esp+4]" & @CRLF & _ ;ersten parameter laden
    "rdtsc" & @CRLF & _ ;timerticks in EDX:EAX
    "rcl eax,cl" & @CRLF & _ ;EAX linksrum rotieren, CL mal
    "mov ebx,123433" & @CRLF & _ ;Primzahl laden
    "mul ebx" & @CRLF & _ ;und mit EAX multiplizieren
    "" & @CRLF & _
    "" & @CRLF & _ ;Leerzeilen ^^
    "" & @CRLF & _
    "ret 8" & @CRLF & _ ;Aufrufparameter vom Stack löschen und zurück
    "" & @CRLF & _
    ""

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;Source,Rückgabetyp,Typ1,Para1,Typ2,Para2....
    $return = _FASMdll($sourcetext, "word", "int", 22, "ptr", 33)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $return = ' & $return & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

    [/autoit] [autoit][/autoit] [autoit]

    ;das wars schon....

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _FASMdll($sourcetext, $Returntype, $Type1 = "", $Param1 = 0, $Type2 = "", $Param2 = 0, $Type3 = "", $Param3 = 0, $Type4 = "", $Param4 = 0, $Type5 = "", $Param5 = 0, $Type6 = "", $Param6 = 0, $Type7 = "", $Param7 = 0, $Type8 = "", $Param8 = 0, $Type9 = "", $Param9 = 0, $Type10 = "", $Param10 = 0, $Type11 = "", $Param11 = 0, $Type12 = "", $Param12 = 0, $Type13 = "", $Param13 = 0, $Type14 = "", $Param14 = 0, $Type15 = "", $Param15 = 0, $Type16 = "", $Param16 = 0, $Type17 = "", $Param17 = 0, $Type18 = "", $Param18 = 0, $Type19 = "", $Param19 = 0, $Type20 = "", $Param20 = 0) ;assembles the code
    ;Dll öffnen
    $FASMdll = DllOpen("fasm.dll")
    if @error then exit(Msgbox(0,"FASM.dll","Error loading FASM.dll"))
    ;Version auslesen
    $version = DllCall($FASMdll, "ptr", "fasm_GetVersion")
    ConsoleWrite('FASM.dll Version = ' & $version[0] & @CRLF& @CRLF)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;asm-code in speicher schreiben
    $struct_source = DllStructCreate("byte [10000]");sollte reichen^^
    DllStructSetData($struct_source, 1, StringToBinary($sourcetext))
    $ptr_source = DllStructGetPtr($struct_source)

    [/autoit] [autoit][/autoit] [autoit]

    ;bytes reservieren für den assembler
    $len_mem = 800000
    $struct_mem = DllStructCreate("byte [" & $len_mem & "]")
    $ptr_mem = DllStructGetPtr($struct_mem)

    [/autoit] [autoit][/autoit] [autoit]

    ;FASM_STATE-struct, siehe FASM.ASH
    $struct_state = DllStructCreate("dword condition; int output_lenght; ptr error_code;ptr output_data; long error_line", $ptr_mem)
    $ptr_state = DllStructGetPtr($struct_state)

    [/autoit] [autoit][/autoit] [autoit]

    ;Assembler aufrufen
    $ret = DllCall($FASMdll, $Returntype, "fasm_Assemble", "ptr", $ptr_source, "ptr", $ptr_mem, "dword", $len_mem, "dword", 100, "dword", 0)
    if @error then
    Msgbox(0,"FASM.dll","Error calling FASM.dll (fasm_Assemble)")
    DllClose($FASMdll)
    Exit
    endif
    ;FASM_STATE-struct auslesen
    $err_state_condition = DllStructGetData($struct_state, "condition")
    ;ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $err_state_condition = ' & $err_state_condition & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $err_state_output_length = DllStructGetData($struct_state, "output_lenght")
    ;ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $err_state_output_length = ' & $err_state_output_length & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $err_state_error_code = DllStructGetData($struct_state, "error_code")
    ;ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $err_state_error_code = ' & $err_state_error_code & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $err_state_output_data = DllStructGetData($struct_state, "output_data")
    ;ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $err_state_output_data = ' & $err_state_output_data & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $err_state_error_line = DllStructGetData($struct_state, "error_line")
    ;ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $err_state_error_line = ' & $err_state_error_line & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;
    If $err_state_condition = 0 Then ;kein Fehler aufgetreten
    ;assemblierten code auslesen...
    $code_struct = DllStructCreate("byte [" & $err_state_output_length & "]", $err_state_error_code)
    $code_ptr = DllStructGetPtr($code_struct)
    $code = DllStructGetData($code_struct, 1)
    ;code anzeigen
    ConsoleWrite('$code = ' & $code & @CRLF & @CRLF )

    [/autoit] [autoit][/autoit] [autoit]

    ;DllCallAddress() generieren
    $scriptstring = "DllCallAddress($Returntype,$code_ptr"
    For $n = 1 To @NumParams / 2 - 1
    If Eval("Type" & $n) <> "" Then $scriptstring &= ",'" & Eval("Type" & $n) & "'," & Eval("Param" & $n);parameter gefunden
    Next
    $scriptstring &= ")"

    [/autoit] [autoit][/autoit] [autoit]

    ;...und aufrufen
    $ret = Execute($scriptstring) ;dllcalladdress aufrufen
    If @error Then exit(MsgBox(0, "FASMdll", "Error executing: " & @CRLF & $scriptstring))

    [/autoit] [autoit][/autoit] [autoit]

    ;Ergebnis=Rückgabe aus code
    Return $ret[0]

    [/autoit] [autoit][/autoit] [autoit]

    Else ;Fehler aufgetreten
    ;s. FASM.ASH
    $struct_LINE_HEADER = DllStructCreate("dword file_path;dword line_number;dword file_offset;dword macro_callin_line; dword macro_line", $err_state_error_code)
    $file_path = DllStructGetData($struct_LINE_HEADER, "file_path")
    $line_number = DllStructGetData($struct_LINE_HEADER, "line_number")
    exit(MsgBox(0, "Fasm.dll", "Fehler " & _fasmdll_errcode($err_state_output_length) & " aufgetreten in Zeile " & $line_number))
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_FASMdll

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _fasmdll_errcode($errcode)

    [/autoit] [autoit][/autoit] [autoit]

    Local $FASMerrtext = "unknown Error"

    [/autoit] [autoit][/autoit] [autoit]

    Switch $errcode
    Case 0
    $FASMerrtext = "OK" ;
    Case 1
    $FASMerrtext = "WORKING" ;
    Case 2
    $FASMerrtext = "ERROR"
    Case -1
    $FASMerrtext = "INVALID_PARAMETER";1
    Case -2
    $FASMerrtext = "OUT_OF_MEMORY" ;2
    Case -3
    $FASMerrtext = "STACK_OVERFLOW" ;3
    Case -4
    $FASMerrtext = "SOURCE_NOT_FOUND";4
    Case -5
    $FASMerrtext = "UNEXPECTED_END_OF_SOURCE";5
    Case -6
    $FASMerrtext = "CANNOT_GENERATE_CODE";6
    Case -7
    $FASMerrtext = "FORMAT_LIMITATIONS_EXCEDDED";7
    Case -8
    $FASMerrtext = "WRITE_FAILED" ;8

    [/autoit] [autoit][/autoit] [autoit]

    ; Error codes for FASM_ERROR condition
    Case -101
    $FASMerrtext = "FILE_NOT_FOUND" ;101
    Case -102
    $FASMerrtext = "ERROR_READING_FILE";102
    Case -103
    $FASMerrtext = "INVALID_FILE_FORMAT";103
    Case -104
    $FASMerrtext = "INVALID_MACRO_ARGUMENTS";104
    Case -105
    $FASMerrtext = "INCOMPLETE_MACRO";105
    Case -106
    $FASMerrtext = "UNEXPECTED_CHARACTERS";106
    Case -107
    $FASMerrtext = "INVALID_ARGUMENT";107
    Case -108
    $FASMerrtext = "ILLEGAL_INSTRUCTION";108
    Case -109
    $FASMerrtext = "INVALID_OPERAND";109
    Case -110
    $FASMerrtext = "INVALID_OPERAND_SIZE";110
    Case -111
    $FASMerrtext = "OPERAND_SIZE_NOT_SPECIFIED";111
    Case -112
    $FASMerrtext = "OPERAND_SIZES_DO_NOT_MATCH";112
    Case -113
    $FASMerrtext = "INVALID_ADDRESS_SIZE";113
    Case -114
    $FASMerrtext = "ADDRESS_SIZES_DO_NOT_AGREE";114
    Case -115
    $FASMerrtext = "DISALLOWED_COMBINATION_OF_REGISTERS";115
    Case -116
    $FASMerrtext = "LONG_IMMEDIATE_NOT_ENCODABLE";116
    Case -117
    $FASMerrtext = "RELATIVE_JUMP_OUT_OF_RANGE";117
    Case -118
    $FASMerrtext = "INVALID_EXPRESSION";118
    Case -119
    $FASMerrtext = "INVALID_ADDRESS";119
    Case -120
    $FASMerrtext = "INVALID_VALUE" ;120
    Case -121
    $FASMerrtext = "VALUE_OUT_OF_RANGE";121
    Case -122
    $FASMerrtext = "UNDEFINED_SYMBOL";122
    Case -123
    $FASMerrtext = "INVALID_USE_OF_SYMBOL";123
    Case -124
    $FASMerrtext = "NAME_TOO_LONG" ;124
    Case -125
    $FASMerrtext = "INVALID_NAME" ;125
    Case -126
    $FASMerrtext = "RESERVED_WORD_USED_AS_SYMBOL";126
    Case -127
    $FASMerrtext = "SYMBOL_ALREADY_DEFINED";127
    Case -128
    $FASMerrtext = "MISSING_END_QUOTE";128
    Case -129
    $FASMerrtext = "MISSING_END_DIRECTIVE";129
    Case -130
    $FASMerrtext = "UNEXPECTED_INSTRUCTION";130
    Case -131
    $FASMerrtext = "EXTRA_CHARACTERS_ON_LINE";131
    Case -132
    $FASMerrtext = "SECTION_NOT_ALIGNED_ENOUGH";132
    Case -133
    $FASMerrtext = "SETTING_ALREADY_SPECIFIED";133
    Case -134
    $FASMerrtext = "DATA_ALREADY_DEFINED";134
    Case -135
    $FASMerrtext = "TOO_MANY_REPEATS";135
    Case -136
    $FASMerrtext = "SYMBOL_OUT_OF_SCOPE";136
    Case -140
    $FASMerrtext = "USER_ERROR" ;140
    Case -141
    $FASMerrtext = "ASSERTION_FAILED";141
    EndSwitch
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $FASMerrtext = ' & $FASMerrtext & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Return $FASMerrtext

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_fasmdll_errcode

    [/autoit] [autoit][/autoit] [autoit][/autoit]


    Todo:
    - Lt. Beschreibung sollen ausführbare Dateien erstellt werden können, incl. Makros !
    Muss ich erst noch implementieren.
    - Wer Lust hat, einen Editor (Syntax highlighting ftw) zu integrieren, immer her damit^^
    - Debugger aus _AssembleIt() integrieren.

  • Wenn du schon die FASM.au3 neu baust, vergiss nicht, dass für Schleifen einmal assemblieren reicht. Wenn alle Features usw. drin sind wird das ganze bestimmt sehr hilfreich sein und nicht mit 1000x FasmAdd nerven ;)
    (FASM hat übrigens schon eine IDE)