FASM UDF (X86 u X64)

  • Ich habe mir nun meine eigene FASM UDF geschrieben um mir die Arbeit zu erleichtern.

    Die UDF kann direkt aus einem X64 Script heraus einen X64 Assemblercode erzeugen.
    D.h.: mann muss nicht ständig zwischen X64 u X86 wechseln, was die Arbeit erheblich erleichtert.

    Direkt aus dem ASM-Code kann man benutzerdefinierte Debug-Funktionen aufrufen.
    Die Register lassen sich in einer normalen AutoIt-Funktion im gewünschten Format ausgeben.
    So kann man sich für jede Situation die richtige Debug-Funktion basteln (z.B. wenn bei den xmm Registern float und int gemischt vorkommen)

    Der ASM-Abschnitt im Script ist mit den Keywords #ASM, #ASMEND und # definiert:
    Dadurch ist der ASM-Code sehr übersichtlich.
    Beim Aufruf von Tidy.exe verliert man nicht die Formatierung.
    Man kann größere Codeteile wie gewohnt mit #cs und #ce auskommentieren
    Durch geringe Anpassungen in SciTE (beschrieben in FASM.au3) kann man die Übersicht/Schreibgeschwindigkeit noch erhöhen


    Die wichtigsten Funktionen sind:
    _FASM_Compile: kompiliert den ASM-Code
    _FASM_StructCreateBCA16: schreibt den ByteCode in den Speicher
    _FASM_DBG: ruft eine AutoIt-Debugfunktion auf


    Hier ein Beispiel, wie man die Debugfunktion nutzen kann:

    Spoiler anzeigen
    [autoit]

    #AutoIt3Wrapper_UseX64=n

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

    #include "FASM.au3"

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

    Global $bOPCode, $_pASM_Test
    Switch @AutoItX64
    Case 1
    $bOPCode = _FASM_Compile("_ASM_Test64")
    Case Else
    $bOPCode = _FASM_Compile("_ASM_Test32")
    EndSwitch
    $_pASM_Test = _FASM_StructCreateBCA16($bOPCode)

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

    Global $tStruct = DllStructCreate("byte xmm0[16]; word xmm1[8]; dword xmm2[4]; float xmm3[4]; byte xmm4[16]; word xmm5[8]; dword xmm6[4]; float xmm7[4];")
    DllStructSetData($tStruct, "xmm0", "0x11111111222222223333333344444444")
    DllStructSetData($tStruct, "xmm4", "0x11111111111111111111111111111111")
    For $i = 1 To 8
    DllStructSetData($tStruct, "xmm1", 2 ^ $i * 100, $i)
    DllStructSetData($tStruct, "xmm5", 1, $i)
    Next
    For $i = 1 To 4
    DllStructSetData($tStruct, "xmm2", 2 ^ $i * 1000000, $i)
    DllStructSetData($tStruct, "xmm6", 1, $i)
    DllStructSetData($tStruct, "xmm3", 2 ^ $i + 0.5, $i)
    DllStructSetData($tStruct, "xmm7", 10, $i)
    Next

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

    DllCallAddress("none", $_pASM_Test, "int", 4, "struct*", $tStruct)

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

    #ASM _ASM_Test32
    # use32
    # mov ecx, [esp+4] ;LoopCount
    # mov esi, [esp+8] ;StructPointer

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

    ;###########################################################
    ;# X86
    ;###########################################################

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

    # movdqu xmm0, [esi]
    # movdqu xmm1, [esi+16]
    # movdqu xmm2, [esi+32]
    # movdqu xmm3, [esi+48]
    # movdqu xmm4, [esi+64]
    # movdqu xmm5, [esi+80]
    # movdqu xmm6, [esi+96]
    # movdqu xmm7, [esi+112]

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

    # _Loop:
    # _FASM_DBG("_DebugREG_32")
    # _FASM_DBG("_DebugXMM_32")

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

    # paddb xmm0, xmm4
    # paddw xmm1, xmm5
    # paddd xmm2, xmm6
    # addps xmm3, xmm7

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

    # sub ecx, 1
    # jnz _Loop

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

    #cs
    X86
    #ce

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

    # ret 8
    #ASMEND

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

    Func _DebugREG_32($tData)
    ConsoleWrite("-= Debug X86 ==========================================" & @CRLF)

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

    Local $tTmp = DllStructCreate($tagFASM_DBG_32, DllStructGetPtr($tData))
    ConsoleWrite("+ StructPointer ESI: " & DllStructGetData($tTmp, "ESI") & @CRLF)
    ConsoleWrite("! LoopCount ECX: " & DllStructGetData($tTmp, "ECX") & @CRLF)
    EndFunc ;==>_DebugREG_32

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

    Func _DebugXMM_32($tData)
    Local $tTmp = DllStructCreate($tagFASM_DBG_32, DllStructGetPtr($tData))
    Local $tXMM = DllStructCreate("byte xmm0[16]; word xmm1[8]; dword xmm2[4]; float xmm3[4];", DllStructGetPtr($tTmp, "xmm0"))

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

    ConsoleWrite("> Byte Xmm0: " & DllStructGetData($tXMM, "xmm0") & @CRLF)
    ConsoleWrite("> Word Xmm1:")
    For $i = 1 To 8
    ConsoleWrite(" " & DllStructGetData($tXMM, "xmm1", $i))
    Next
    ConsoleWrite(@CRLF)

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

    ConsoleWrite("> DWord Xmm2:")
    For $i = 1 To 4
    ConsoleWrite(" " & DllStructGetData($tXMM, "xmm2", $i))
    Next
    ConsoleWrite(@CRLF)

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

    ConsoleWrite("> Float Xmm3:")
    For $i = 1 To 4
    ConsoleWrite(" " & DllStructGetData($tXMM, "xmm3", $i))
    Next
    ConsoleWrite(@CRLF)

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

    ConsoleWrite(@CRLF)
    EndFunc ;==>_DebugXMM_32

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

    #ASM _ASM_Test64
    # use64

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

    ;###########################################################
    ;# X64
    ;###########################################################

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

    # movdqu xmm0, [rdx]
    # movdqu xmm1, [rdx+16]
    # movdqu xmm2, [rdx+32]
    # movdqu xmm3, [rdx+48]
    # movdqu xmm4, [rdx+64]
    # movdqu xmm5, [rdx+80]
    # movdqu xmm6, [rdx+96]
    # movdqu xmm7, [rdx+112]

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

    # _Loop:
    # _FASM_DBG("_DebugREG_64")
    # _FASM_DBG("_DebugXMM_64")

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

    # paddb xmm0, xmm4
    # paddw xmm1, xmm5
    # paddd xmm2, xmm6
    # addps xmm3, xmm7

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

    # sub rcx, 1
    # jnz _Loop

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

    #cs
    X64
    #ce

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

    # ret
    #ASMEND

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

    Func _DebugREG_64($tData)
    ConsoleWrite("-= Debug X64 ==========================================" & @CRLF)

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

    Local $tTmp = DllStructCreate($tagFASM_DBG_64, DllStructGetPtr($tData))
    ConsoleWrite("+ StructPointer RDX: " & DllStructGetData($tTmp, "RDX") & @CRLF)
    ConsoleWrite("! LoopCount RCX: " & DllStructGetData($tTmp, "RCX") & @CRLF)
    EndFunc ;==>_DebugREG_64

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

    Func _DebugXMM_64($tData)
    Local $tTmp = DllStructCreate($tagFASM_DBG_64, DllStructGetPtr($tData))
    Local $tXMM = DllStructCreate("byte xmm0[16]; word xmm1[8]; dword xmm2[4]; float xmm3[4];", DllStructGetPtr($tTmp, "xmm0"))

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

    ConsoleWrite("> Byte Xmm0: " & DllStructGetData($tXMM, "xmm0") & @CRLF)
    ConsoleWrite("> Word Xmm1:")
    For $i = 1 To 8
    ConsoleWrite(" " & DllStructGetData($tXMM, "xmm1", $i))
    Next
    ConsoleWrite(@CRLF)

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

    ConsoleWrite("> DWord Xmm2:")
    For $i = 1 To 4
    ConsoleWrite(" " & DllStructGetData($tXMM, "xmm2", $i))
    Next
    ConsoleWrite(@CRLF)

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

    ConsoleWrite("> Float Xmm3:")
    For $i = 1 To 4
    ConsoleWrite(" " & DllStructGetData($tXMM, "xmm3", $i))
    Next
    ConsoleWrite(@CRLF)

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

    ConsoleWrite(@CRLF)
    EndFunc ;==>_DebugXMM_64

    [/autoit]


    Hier noch eine (vorkompilierte) Version von "Conway's Game of Life" (benötigt aktuelle Beta)

    Spoiler anzeigen
    [autoit]

    #AutoIt3Wrapper_Autoit3Dir=c:\Program Files (x86)\AutoIt3\Beta
    #AutoIt3Wrapper_UseX64=n

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

    #include <GDIPlus.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>

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

    ;#include "FASM.au3"

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

    ;Global $bOPCode = _FASM_Compile("_ASM_Calc")
    Global $_pASM_Calc = _FASM_StructCreateBCA16("0x8B54240C8B5A088B7C24048B74240889D90FAF4A0489D86BC00201C601C7660F6F06660F7F0783C71083C61083E91075ED8B7C240489FE01DF8B420483C0010FAFC301C689D9660F6F06660F6F0C1F660F7F07F30F7F0C1E83C71083C61083E91075E38B7C240401DF01DF89FE03328B4A048A068A6701880788660101DF01DE83E90175ED8B7C240401DF8B42040FAFC389FE01C68B028A4E018A2C06882F884C070101DE01DF8A4F018A2C07882E884C06018B74240889D90FAF4A0C660FEFC0660F7F0683C61083E91075F48B7424048B7C24088B420483C00201DE83C701660F6F0689D983C610660F6FC8660F6FD0660F6FD8660F6F06660F6FE0660F73DA01660F73DB02660F73FC0E660FEBDC660F73FC01660FEBD4660FFCCB660FFCD1F30F6F1FF30F6F241FF30F6F2C5F660FFCDA660FFCE1660FFCEAF30F7F1FF30F7F241FF30F7F2C5F83C71083E910759583E801758A8B7424048B7C2408B8020000000FAFC301C601C789D90FAF4A04B803030303660F6EF8660F70FF00B802020202660F6EF0660F70F600B801010101660F6EE8660F70ED00660F6F07660F6F0E660F6FD0660F6FD8660F74D6660F74DF660FDBCA660F6FE5660FDBE3660FEBCC660F7F0F83C71083C61083E91075C9C20C00")
    ;$bOPCode = _FASM_Compile("_ASM_SetBitmap")
    Global $_pASM_SetBitmap = _FASM_StructCreateBCA16("0x8B54240C8B7C24048B7424088B5A0889D96BDB0201DE83C6010FAF4A04B801000000660F6EF0660F70F600660F6E6A14660F70ED00660FEFFFF30F6F06660F6FD0660F60C7660F68D7660F6FC8660F6FDA660F60C7660F60D7660F68CF660F68DF660F76C6660F76CE660F76D6660F76DE660FDBC5660FDBCD660FDBD5660FDBDD660F7F0783C710660F7F0F83C710660F7F1783C710660F7F1F83C71083C61083E9107594C20C00")
    ;$bOPCode = _FASM_Compile("_ASM_Random")
    Global $_pASM_Random = _FASM_StructCreateBCA16("0x8B7C24048B4C24088B44240C69C0FD43030005C39E260083F8007C05C60701EB03C6070083C70183E90175E0C20C00")

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

    Opt("MustDeclareVars", 1)
    Opt("GUIOnEventMode", 1)
    _GDIPlus_Startup()

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

    Global $iLife_X = 600 * 4
    Global $iLife_Y = 600 * 4

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

    Global $iLife_PatX = $iLife_X + 2 + 16
    $iLife_PatX = $iLife_PatX + 16 - Mod($iLife_PatX, 16)
    Global $iLife_PatY = $iLife_Y + 4

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

    Global $tLife_Pat = DllStructCreate("byte[" & $iLife_PatX * $iLife_PatY & "]; byte[32];")
    Global $pLife_Pat = Number(DllStructGetPtr($tLife_Pat))
    If Mod($pLife_Pat, 16) Then $pLife_Pat += 16 - Mod($pLife_Pat, 16)

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

    Global $tLife_PatNG = DllStructCreate("byte[" & $iLife_PatX * $iLife_PatY & "]; byte[32];")
    Global $pLife_PatNG = Number(DllStructGetPtr($tLife_PatNG))
    If Mod($pLife_PatNG, 16) Then $pLife_PatNG += 16 - Mod($pLife_PatNG, 16)

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

    Global $tLife_BMP = DllStructCreate("uint[" & $iLife_PatX * $iLife_Y & "]; byte[32];")
    Global $pLife_BMP = Number(DllStructGetPtr($tLife_BMP))
    If Mod($pLife_BMP, 16) Then $pLife_BMP += 16 - Mod($pLife_BMP, 16)
    Global $hBmp_Life = _GDIPlus_BitmapCreateFromScan0($iLife_X, $iLife_Y, $GDIP_PXF32ARGB, $iLife_PatX * 4, $pLife_BMP)

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

    Global $tValues = DllStructCreate("int X; int Y; int PatX; int PatY; uint BGColor; uint Color;")
    DllStructSetData($tValues, "X", $iLife_X)
    DllStructSetData($tValues, "Y", $iLife_Y)
    DllStructSetData($tValues, "PatX", $iLife_PatX)
    DllStructSetData($tValues, "PatY", $iLife_PatY)
    DllStructSetData($tValues, "BGColor", 0xFF000000)
    DllStructSetData($tValues, "Color", 0xFF00FF00)

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

    Global $iGui_W = 600
    Global $iGui_H = 600

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

    Global $hGui = GUICreate("Conway's Game of Life", $iGui_W, $iGui_H)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    Global $hBmp = _WinAPI_CreateBitmap($iGui_W, $iGui_H)
    Global $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBmp)
    _WinAPI_DeleteObject($hBmp)
    $hBmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
    _GDIPlus_BitmapDispose($hBitmap)
    Global $hDC = _WinAPI_GetDC($hGui)
    Global $hCDC = _WinAPI_CreateCompatibleDC($hDC)
    Global $hOBJ = _WinAPI_SelectObject($hCDC, $hBmp)
    Global $hGfx_Buffer = _GDIPlus_GraphicsCreateFromHDC($hCDC)
    _GDIPlus_GraphicsSetInterpolationMode($hGfx_Buffer, 5)
    _GDIPlus_GraphicsSetPixelOffsetMode($hGfx_Buffer, 2)

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

    GUISetState()

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

    _Random()

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

    Global $iTimer = TimerInit(), $iSteps = 0
    While 1
    _Calc()

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

    _GDIPlus_GraphicsClear($hGfx_Buffer, 0xFF000000)
    _GDIPlus_GraphicsDrawImageRect($hGfx_Buffer, $hBmp_Life, 0, 0, $iGui_W, $iGui_H)
    _WinAPI_BitBlt($hDC, 0, 0, $iGui_W, $iGui_H, $hCDC, 0, 0, 0x00CC0020)

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

    $iSteps += 1
    WinSetTitle($hGui, "", "Conway's Game of Life " & $iLife_X & "x" & $iLife_Y & " / " & StringFormat("%.1f", 1000 / (TimerDiff($iTimer) / $iSteps), 1) & " fps")
    WEnd

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

    Func _Calc()
    DllCallAddress("none", $_pASM_Calc, "ptr", $pLife_Pat, "ptr", $pLife_PatNG, "struct*", $tValues)
    DllCallAddress("none", $_pASM_SetBitmap, "ptr", $pLife_BMP, "ptr", $pLife_PatNG, "struct*", $tValues)
    EndFunc ;==>_Calc

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

    #ASM _ASM_Calc
    # use32

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

    # mov edx, [esp+12]
    # mov ebx, [edx+8] ;PatX

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

    ;###########################################################
    ;# Copy NextGeneration Pattern to LifePattern incl. Borders
    ;###########################################################
    # mov edi, [esp+4]
    # mov esi, [esp+8]
    # mov ecx, ebx;PatX
    # imul ecx, [edx+4];PatX*Y
    # mov eax, ebx
    # imul eax, 2
    # add esi, eax ;skip first/last 2 rows
    # add edi, eax
    # _LoopCopy:
    # movdqa xmm0, [esi]
    # movdqa [edi], xmm0
    # add edi, 16
    # add esi, 16
    # sub ecx, 16
    # jnz _LoopCopy

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

    ; Mirror Bottom-Top
    # mov edi, [esp+4]
    # mov esi, edi
    # add edi, ebx;2 row
    # mov eax, [edx+4]
    # add eax, 1
    # imul eax, ebx
    # add esi, eax;Y+2 row
    # mov ecx, ebx
    # _LoopCopyX:
    # movdqa xmm0, [esi]
    # movdqa xmm1, [edi+ebx]
    # movdqa [edi], xmm0
    # movdqu [esi+ebx], xmm1
    # add edi, 16
    # add esi, 16
    # sub ecx, 16
    # jnz _LoopCopyX

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

    ; Mirror Left-Right
    # mov edi, [esp+4]
    # add edi, ebx
    # add edi, ebx
    # mov esi, edi
    # add esi, [edx]
    # mov ecx, [edx+4]
    # _LoopCopyY:
    # mov al, [esi]
    # mov ah, [edi+1]
    # mov [edi], al
    # mov [esi+1], ah
    # add edi, ebx
    # add esi, ebx
    # sub ecx, 1
    # jnz _LoopCopyY

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

    ; Corners
    # mov edi, [esp+4]
    # add edi, ebx
    # mov eax, [edx+4]
    # imul eax, ebx
    # mov esi, edi
    # add esi, eax
    # mov eax, [edx]
    # mov cl, [esi+1]
    # mov ch, [esi+eax]
    # mov [edi], ch
    # mov [edi+eax+1], cl

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

    # add esi, ebx
    # add edi, ebx
    # mov cl, [edi+1]
    # mov ch, [edi+eax]
    # mov [esi], ch
    # mov [esi+eax+1], cl

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

    ;###########################################################
    ;# Clear NextGeneration Pattern
    ;###########################################################
    # mov esi, [esp+8]
    # mov ecx, ebx;PatX
    # imul ecx, [edx+12];PatX*PatY
    # pxor xmm0, xmm0
    # _LoopClear:
    # movdqa [esi], xmm0
    # add esi, 16
    # sub ecx, 16
    # jnz _LoopClear

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

    ;###########################################################
    ;# Count Neighbors
    ;###########################################################
    # mov esi, [esp+4]
    # mov edi, [esp+8]
    # mov eax, [edx+4] ;Y
    # add eax, 2 ;+2 rows
    # add esi, ebx
    # add edi, 1 ;center field
    # _LoopY:
    # movdqa xmm0, [esi]
    # mov ecx, ebx;PatX
    # _LoopX:
    # add esi, 16
    ;xmm0 = 0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 00
    # movdqa xmm1, xmm0
    # movdqa xmm2, xmm0
    # movdqa xmm3, xmm0
    # movdqa xmm0, [esi]
    # movdqa xmm4, xmm0
    # psrldq xmm2, 1
    # psrldq xmm3, 2
    # pslldq xmm4, 14
    ;xmm0 = 1F 1E 1D 1C 1B 1A 19 18 17 16 15 14 13 12 11 10
    ;xmm1 = 0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 00
    ;xmm2 = __ 0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01
    ;xmm3 = __ __ 0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02
    ;xmm4 = 11 10 __ __ __ __ __ __ __ __ __ __ __ __ __ __
    # por xmm3, xmm4
    # pslldq xmm4, 1
    # por xmm2, xmm4
    # paddb xmm1, xmm3 ;=>aktuelle Zeile => 00+02 | 01+03...
    # paddb xmm2, xmm1 ;=>vorherige u nächste Zeile => 00+01+02 | 01+02+03...

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

    # movdqu xmm3, [edi]
    # movdqu xmm4, [edi+ebx]
    # movdqu xmm5, [edi+ebx+ebx]
    # paddb xmm3, xmm2
    # paddb xmm4, xmm1
    # paddb xmm5, xmm2
    # movdqu [edi], xmm3
    # movdqu [edi+ebx], xmm4
    # movdqu [edi+ebx+ebx], xmm5

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

    # add edi, 16
    # sub ecx, 16
    # jnz _LoopX

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

    # sub eax, 1
    # jnz _LoopY

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

    ;###########################################################
    ;# Calc NextGeneration
    ;###########################################################
    # mov esi, [esp+4]
    # mov edi, [esp+8]
    # mov eax, 2
    # imul eax, ebx
    # add esi, eax
    # add edi, eax
    # mov ecx, ebx;PatX
    # imul ecx, [edx+4];PatX*Y

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

    # mov eax, 0x03030303
    # movd xmm7, eax
    # pshufd xmm7, xmm7, 0
    # mov eax, 0x02020202
    # movd xmm6, eax
    # pshufd xmm6, xmm6, 0
    # mov eax, 0x01010101
    # movd xmm5, eax
    # pshufd xmm5, xmm5, 0

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

    ;xmm7 = 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
    ;xmm6 = 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
    ;xmm5 = 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1

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

    # _LoopCalc:
    # movdqa xmm0, [edi]
    # movdqa xmm1, [esi]
    # movdqa xmm2, xmm0
    # movdqa xmm3, xmm0
    ;2=NoChange 3=1 Else=0
    # pcmpeqb xmm2, xmm6
    # pcmpeqb xmm3, xmm7
    # pand xmm1, xmm2
    # movdqa xmm4, xmm5
    # pand xmm4, xmm3
    # por xmm1, xmm4
    # movdqa [edi], xmm1
    # add edi, 16
    # add esi, 16
    # sub ecx, 16
    # jnz _LoopCalc

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

    # ret 12
    #ASMEND

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

    #ASM _ASM_SetBitmap
    # use32

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

    ;###########################################################
    ;# Set Pixel
    ;###########################################################
    # mov edx, [esp+12]
    # mov edi, [esp+4]
    # mov esi, [esp+8]
    # mov ebx, [edx+8]
    # mov ecx, ebx
    # imul ebx, 2
    # add esi, ebx
    # add esi, 1
    # imul ecx, [edx+4]

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

    # mov eax, 1
    # movd xmm6, eax
    # pshufd xmm6, xmm6, 0

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

    # movd xmm5, [edx+20]
    # pshufd xmm5, xmm5, 0

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

    # pxor xmm7, xmm7

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

    # _Loop:
    # movdqu xmm0, [esi]
    # movdqa xmm2, xmm0

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

    # punpcklbw xmm0, xmm7
    # punpckhbw xmm2, xmm7
    # movdqa xmm1, xmm0
    # movdqa xmm3, xmm2
    # punpcklbw xmm0, xmm7
    # punpcklbw xmm2, xmm7
    # punpckhbw xmm1, xmm7
    # punpckhbw xmm3, xmm7

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

    # pcmpeqd xmm0, xmm6
    # pcmpeqd xmm1, xmm6
    # pcmpeqd xmm2, xmm6
    # pcmpeqd xmm3, xmm6

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

    # pand xmm0, xmm5
    # pand xmm1, xmm5
    # pand xmm2, xmm5
    # pand xmm3, xmm5
    #
    # movdqa [edi], xmm0
    # add edi, 16
    # movdqa [edi], xmm1
    # add edi, 16
    # movdqa [edi], xmm2
    # add edi, 16
    # movdqa [edi], xmm3
    # add edi, 16

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

    # add esi, 16
    # sub ecx, 16
    # jnz _Loop

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

    # ret 12
    #ASMEND

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

    Func _Random()
    Local Static $iSeed = Random(0, 2 ^ 16, 1)
    Local $aResult = DllCallAddress("int", $_pASM_Random, "ptr", $pLife_PatNG, "uint", $iLife_PatX * $iLife_PatY, "int", $iSeed)
    $iSeed = $aResult[0]
    EndFunc ;==>_Random

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

    #ASM _ASM_Random
    # use32
    # mov edi, [esp+4]
    # mov ecx, [esp+8] ;Count
    # mov eax, [esp+12] ;Seed
    # _Loop:
    # imul eax, 214013
    # add eax, 2531011
    # cmp eax, 0
    # jl _Zero
    # mov byte[edi], 1
    # jmp _Cont
    # _Zero:
    # mov byte[edi], 0
    # _Cont:
    # add edi, 1
    # sub ecx, 1
    # jnz _Loop
    # ret 12
    #ASMEND

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

    Func _FASM_StructCreateBCA16($bBinaryCode)
    Local $iSize = BinaryLen($bBinaryCode)
    Local $aResult = DllCall("kernel32.dll", "ptr", "VirtualAlloc", "ptr", 0, "ulong_ptr", $iSize + 16, "dword", 0x00001000, "dword", 0x00000040)
    If @error Or Not $aResult[0] Then Return SetError(1, 0, False)
    Local $pStruct = Number($aResult[0])
    $pStruct = $pStruct + 16 - Mod($pStruct, 16)
    Local $tStruct = DllStructCreate("byte[" & $iSize & "];", $pStruct)
    DllStructSetData($tStruct, 1, $bBinaryCode)
    Return $pStruct
    EndFunc ;==>_StructCreateBCA16

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

    Func _Exit()
    _GDIPlus_BitmapDispose($hBmp_Life)
    _GDIPlus_GraphicsDispose($hGfx_Buffer)
    _WinAPI_SelectObject($hCDC, $hOBJ)
    _WinAPI_DeleteObject($hBmp)
    _WinAPI_DeleteDC($hCDC)
    _WinAPI_ReleaseDC($hGui, $hDC)
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>_Exit

    [/autoit]


    Die UDF ist kein Inline-Assembler! Sondern ein Werkzeug zum Entwickeln von fertigem Bytecode.
    Damit FASM auch unter X64 kompilieren kann, wird die FASM.exe auf die Festplatte geschrieben und gestartet.

    Vielen Dank an UEZ und vor allem Andy! :thumbup:
    (Ich hab mir einige Sachen ganz dreist abgeguckt :whistling: )

    lgE

  • Klasse Umsetzung! 8o:thumbup:

    Ich glaube, dass ich doch endlich ASM lernen sollte, damit ich die feinen ASM Sachen hier aus dem Forum anwenden kann.

    Habe bereits mit minx' ASM Tutorial angefangen, aber hat sich wieder im Sande verlaufen... :(

    Vielleicht könnte man ein paar Beispiele mit ASM strukturiert aufsetzen und die Hürde AMS zu lernen dadurch herabsetzen. Ich denke da an ein separates Thema mit "How to Code in ASM", wo dann Beispiele gepostet werden. gibt's ja schon :whistling: -> https://autoit.de/index.php?page=Thread&amp;postID=181436 (Danke an TheShadowAE für den Hinweis)!

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

    3 Mal editiert, zuletzt von UEZ (5. Dezember 2013 um 14:57)

  • Höhö :D


    Das hab ich mir, ganz ehrlich, nicht von dir abgeguckt!


    Ich glaube, dass ich doch endlich ASM lernen sollte...


    Starte doch mal mit diesem Script:

    Spoiler anzeigen
    [autoit]

    #AutoIt3Wrapper_UseX64=n

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

    #include "FASM.au3"

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

    Global $bOPCode, $_pASM_StringCopy
    $bOPCode = _FASM_Compile("_ASM_StringCopy")
    $_pASM_StringCopy = _FASM_StructCreateBCA16($bOPCode)

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

    Global $tStringSrc = DllStructCreate("char[1024];")
    Global $tStringDst = DllStructCreate("char[1024];")
    DllStructSetData($tStringSrc, 1, "AutoIt rulez!")

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

    DllCallAddress("none", $_pASM_StringCopy, "struct*", $tStringSrc, "struct*", $tStringDst, "int", StringLen(DllStructGetData($tStringSrc, 1)))

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

    ConsoleWrite("> Fertig: " & DllStructGetData($tStringDst, 1) & @CRLF)

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

    #ASM _ASM_StringCopy
    # use32
    # mov esi, [esp+4] ;Parameter 1 in ESI laden (Pointer $tStringSrc)
    # mov edi, [esp+8] ;Parameter 2 in EDI laden (Pointer $tStringDst)
    # mov ecx, [esp+12] ;Parameter 3 in ECX laden (StringLen)

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

    # _Loop:
    # mov al, [esi] ;1 Byte von tStringSrc in AL laden
    # mov [edi], al ;Inhalt von AL nach tStringDst schreiben

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

    # _FASM_DBG("_Debug")

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

    # add esi, 1 ;Src Pointer + 1
    # add edi, 1 ;Dst Pointer + 1

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

    # sub ecx, 1 ;LoopCount - 1
    # jg _Loop ;if ecx > 0 then "springe zu _Loop:"

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

    # ret 12 ;Anzahl der Parameter * 4
    #ASMEND

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

    Func _Debug($tData)
    Local $tTmp = DllStructCreate($tagFASM_DBG_32, DllStructGetPtr($tData))
    Local $tEAX = DllStructCreate("char[4];", DllStructGetPtr($tTmp, "EAX"))
    ;EAX ist 32Bit = 4Byte lang und hat folgenden Aufbau:
    ;32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01
    ;|--------------------------------------------- EAX -------------------------------------------|
    ; |--------------------- AX --------------------|
    ; |--------- AH ---------|
    ; |--------- AL ---------|

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

    ConsoleWrite("> Byte in AL: " & DllStructGetData($tEAX, 1, 1) & @CRLF)

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

    ConsoleWrite("+ LoopCnt ECX: " & DllStructGetData($tTmp, "ECX") & @CRLF)
    ConsoleWrite("! Pointer Src ESI: " & DllStructGetData($tTmp, "ESI") & " / Offset: " & DllStructGetData($tTmp, "ESI") - Number(DllStructGetPtr($tStringSrc)) & @CRLF)
    ConsoleWrite("! Pointer Dst EDI: " & DllStructGetData($tTmp, "EDI") & " / Offset: " & DllStructGetData($tTmp, "EDI") - Number(DllStructGetPtr($tStringDst)) & @CRLF)

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

    ConsoleWrite(@CRLF)
    EndFunc ;==>_Debug

    [/autoit]

    Sollte relativ einfach nachzuvollziehen sein.

    Versuch mal jedes Char um 1 zu erhöhen (Aus "A" wird "B" usw...)
    Oder den String in umgedrehter Reihenfolge (StringReverse) zu kopieren (Tip: StringLen / 2 = "shr ecx, 1")


    Und dann experimentier mal mit DEINER Materie - GdiPlus ;)

    Spoiler anzeigen
    [autoit]

    #AutoIt3Wrapper_Autoit3Dir=c:\Program Files (x86)\AutoIt3\Beta
    #AutoIt3Wrapper_UseX64=n
    #include <GDIPlus.au3>
    #include "FASM.au3"

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

    _GDIPlus_Startup()
    Global $tPixels = DllStructCreate("uint[" & 9 * 9 & "];")
    Global $hBitmap = _GDIPlus_BitmapCreateFromScan0(9, 9, $GDIP_PXF32ARGB, 9 * 4, DllStructGetPtr($tPixels))
    Global $hContext = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsClear($hContext, 0xFFFF00FF)
    Global $hBrush = _GDIPlus_BrushCreateSolid(0xFFFF0000)
    _GDIPlus_GraphicsFillRect($hContext, 1, 1, 3, 3, $hBrush)
    _GDIPlus_BrushSetSolidColor($hBrush, 0xFF00FF00)
    _GDIPlus_GraphicsFillRect($hContext, 5, 1, 3, 3, $hBrush)
    _GDIPlus_BrushSetSolidColor($hBrush, 0xFF0000FF)
    _GDIPlus_GraphicsFillRect($hContext, 1, 5, 3, 3, $hBrush)
    _GDIPlus_BrushSetSolidColor($hBrush, 0xFFFFFF00)
    _GDIPlus_GraphicsFillRect($hContext, 5, 5, 3, 3, $hBrush)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hContext)

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

    _GDIPlus_ImageSaveToFile($hBitmap, @ScriptDir & "\Src.bmp")

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

    Global $bOPCode, $_pASM_StringCopy
    $bOPCode = _FASM_Compile("_ASM_Red2White")
    $_pASM_Red2White = _FASM_StructCreateBCA16($bOPCode)

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

    DllCallAddress("none", $_pASM_Red2White, "struct*", $tPixels, "int", 9 * 9)

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

    _GDIPlus_ImageSaveToFile($hBitmap, @ScriptDir & "\Dst.bmp")
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_Shutdown()

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

    #ASM _ASM_Red2White
    # use32
    # mov esi, [esp+4]
    # mov ecx, [esp+8]

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

    # _Loop:
    # mov eax, [esi]
    # _FASM_DBG("_Debug_1")

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

    # cmp eax, 0xFFFF0000
    # jne _NotEqual
    # mov dword[esi], 0xFFFFFFFF
    # _FASM_DBG("_Debug_2")

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

    # _NotEqual:

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

    # add esi, 4
    # sub ecx, 1
    # jg _Loop

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

    # ret 8
    #ASMEND

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

    Func _Debug_2($tData)
    Local $tTmp = DllStructCreate($tagFASM_DBG_32, DllStructGetPtr($tData))
    ConsoleWrite("! EAX: " & Hex($tTmp.EAX, 8) & " = 0xFFFF0000 => Farbe Weiß wird geschrieben" & @CRLF)
    EndFunc ;==>_Debug_2

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

    Func _Debug_1($tData)
    Local $tTmp = DllStructCreate($tagFASM_DBG_32, DllStructGetPtr($tData))
    ConsoleWrite("+ EAX: " & Hex($tTmp.EAX, 8) & @CRLF)
    EndFunc ;==>_Debug_1

    [/autoit]

    Nun probier, dass auch eine weitere Farbe weiß wird...

    lgE


  • Und dann experimentier mal mit DEINER Materie - GdiPlus ;)

    lgE

    Mit UNSERER Materie bitte! :D

    Ich werde mich daran versuchen...

    Hier auch blau zu weiß ASM Code (war nicht so schwer):

    Danke und Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

    3 Mal editiert, zuletzt von UEZ (5. Dezember 2013 um 21:23)

  • Hi,
    nachdem ich RUN() in

    [autoit]

    Local $hPID = Run(@ComSpec & " /c " & 'FASM.exe ' & $sName & '.asm ' & $sName & '.op', @ScriptDir, @SW_HIDE, 0x6)

    [/autoit]

    geändert hatte, lief das script auch unter XP32.
    Fehler waren die in den Pfaden enthaltenen Leerzeichen. Die Fehlermeldungen bekam ich aber trotz allen rumprobierens (Anführungsstriche um die Pfade) nicht weg...

    Ansonsten wieder ein echter Eukalyptus.... :thumbup:

    Wieso du dir die Mühe machst mit dem #ASM und #ASMEND und dann noch das völlig überflüssige # vor die Assemblerbefehle reinbastelst, verstehe ich allerdings nicht.
    Dann lieber in LUA den Teil von #cs und #ce suchen und mit #ASM und #ASMEND ergänzen, so dass der Code dazwischen nicht von AutoIt geparsed wird.

    minx und eukalyptus
    ich glaube es wird Zeit, dass wir uns mal zusammensetzen, anstatt jeder etwas "halbgares" zu basteln und ein richtig fettes "asm-inline" auf die Beine stellen. Was haltet ihr davon? 8o

  • minx und eukalyptus
    ich glaube es wird Zeit, dass wir uns mal zusammensetzen, anstatt jeder etwas "halbgares" zu basteln und ein richtig fettes "asm-inline" auf die Beine stellen. Was haltet ihr davon? 8o

    Collaboration of the evil? :D Warum nicht. (Vielleicht wäre es auch an der Zeit dieses Feature schlicht in die AutoIt Version zu übernehmen ...)

  • minx
    du hast einen Dreher in einer Zeile im GDI-Beispiel

    [autoit]

    Global $hBitmap = _GDIPlus_BitmapCreateFromScan0(9, 9, 9 * 4,$GDIP_PXF32ARGB, DllStructGetPtr($tPixels))

    [/autoit]

    dann läufts

    Zitat

    Collaboration of the evil? Warum nicht.

    :rock:

    Zitat

    Vielleicht wäre es auch an der Zeit dieses Feature schlicht in die AutoIt Version zu übernehmen ...)

    Ich hör schon das Gequieeeeeke der "AutoIt-Geeks", jede Wette, da krabbelt selbst Valik wieder aus der Gruft :rofl:

  • Andy: _GDIPlus_BitmapCreateFromScan0() hatte ich geändert, da $iStride und $pScan0 eher selten genutzt werden und somit am Ende besser aufgehoben sind. Am besten die neuste Beta benutzen. ;)

    Btw,
    ich würde gerne eine Bitmap mit zufälligen Grauwerten immer wieder füllen lassen, aber ich scheitere gerade an der Random Funktion.

    Keine Ahnung, was noch zur Hürde wird.

    Mein Ansatz war dieser:

    Code
    #  Rand:
    #        mov     eax,[X0]
    #        mov     edx,69069
    #        mul     edx
    #        inc     eax
    #        mov     [X0],eax
    #        ret
    
    
    #X0: db 1


    aber dann schmiert das Skript ab.

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • UEZ: Probier nun Rot-Weiß mit SIMD und verarbeite 4 Pixel gleichzeitig. :D
    Edit: im "Game of Life" findest du eine Random-Funktion


    Andy: welche Fehlermeldungen? Bei mir läuft es ohne Probleme unter WinXP32 und Win764

    Wieso du dir die Mühe machst mit dem #ASM und #ASMEND und dann noch das völlig überflüssige # vor die Assemblerbefehle reinbastelst, verstehe ich allerdings nicht.
    Dann lieber in LUA den Teil von #cs und #ce suchen und mit #ASM und #ASMEND ergänzen, so dass der Code dazwischen nicht von AutoIt geparsed wird.

    Wenn alles zwischen #cs und #ce steht, dann geht total der Überblick verloren
    hier mal ein Vergleich:
    autoit.de/wcf/attachment/23738/autoit.de/wcf/attachment/23739/
    im zweiten Bild sieht man auf den ersten Blick, welche Teile nun tatsächlich zum Code gehören und welche nicht.

    Des weiteren zerstört Tidy.exe die Formatierung innerhalb eines CommentBlocks:
    autoit.de/wcf/attachment/23740/


    Optimal wäre ja, wenn LASM auch 64Bit könnte!
    Minx, ist das geplant?

  • Optimal wäre ja, wenn LASM auch 64Bit könnte!
    Minx, ist das geplant?

    Das wäre natürlich mit einem nicht unerheblichen Aufwand verbunden, ist aber generell möglich. Ich habe den Code von Anfang an im SDK Stil verfasst. Mal sehen. Erstmal ImagineCup und Perseus ;)

  • Das klingt jetzt eventuell abwägig (weil ich es schonmal in AutoIt probiert habe, wo es nicht anständig funktioniert hat), aber villeicht kann man tatsächlich effektives Multithreading (nur für ASM natürlich) einbauen. In FB hat das ganz gut funktioniert. Meine Idee ist eine kleine Dll (sollte unter 10kb liegen, und direkt einbaubaubar sein) in FB die 2-n Threads erstellt und einen vorgegeben ASM code per ptr + Structptr (für die Daten) aufruft.

    So nach dem Motto: _ASM_Call(vOP, iThreads, vStruct_Thread1, ... , vStruct-ThreadN)
    In Basic ist es nun einfach z.B. 2 Threads zu erstellen die mit Struct1 und Struct2 gefüttert werden. Anschließend wird wie üblich auf die Terminierung gewartet. (Das warten hat in AutoIt so viel Leistung gefressen, dass es kaum etwas gebracht hat)

    Der Hit wäre natürlich ein optionaler instant return, sodass das Skript praktisch ohne Zeitverlust weiterläuft. (bringt nur etwas bei Abläufen die sich nicht gegenseitig beißen). Wie man soetwas einbaut weiß ich allerdings nicht :D

    Ist nur so eine Idee. Also wenns nicht gefällt einfach ignorieren :)

    lg
    M

  • Das klingt jetzt eventuell abwägig (weil ich es schonmal in AutoIt probiert habe, wo es nicht anständig funktioniert hat), aber villeicht kann man tatsächlich effektives Multithreading (nur für ASM natürlich) einbauen.

    So nach dem Motto: _ASM_Call(vOP, iThreads, vStruct_Thread1, ... , vStruct-ThreadN)
    In Basic ist es nun einfach z.B. 2 Threads zu erstellen die mit Struct1 und Struct2 gefüttert werden. Anschließend wird wie üblich auf die Terminierung gewartet. (Das warten hat in AutoIt so viel Leistung gefressen, dass es kaum etwas gebracht hat)

    Der Hit wäre natürlich ein optionaler instant return, sodass das Skript praktisch ohne Zeitverlust weiterläuft. (bringt nur etwas bei Abläufen die sich nicht gegenseitig beißen). Wie man soetwas einbaut weiß ich allerdings nicht :D


    Sollte das nicht auch in AutoIt gehen? Ich hätte das so versucht (wobei CreateThread natürlich ein Wrapper für die entsprechende Funktion aus kernel32.dll ist):

    [autoit]

    Func _ASM_Call($ptrASM, $iThreads, $aptrStructs)
    For $i = 1 To $iThreads
    CreateThread($ptrASM, $aptrStructs[$i-1])
    Next
    EndFunc

    [/autoit]
  • Ich habe vor kurzen mal an einer Airbag-Dll gebastelt, die AutoIt Funktionen in einen eigenen Speicher schreibt und von dort Threads erstellen kann (also echtes Multithreading mit normalen AutoIt Funktionen), sicher kann man das auch für ASM Calls benutzen, wenn man eine AutoIt Funktion drum wrappt oder direkt den Pointer übergibt. Das funktioniert leider noch nicht zuverlässig genug. War nur mal so eine fixe Idee ^^

  • Wenn man in AutoIt versucht per Kernel32 Threads zu basteln und diese kontrolliert wieder zu schließen stellt man fest, dass es dort viele Probleme gibt.
    Mir war damals folgendes aufgefallen:
    - enormer Overhead (je flinker der ASM, desto größer der Overhead)
    - Threads terminieren (scheinbar) nicht immer ordnungsgemäß (der Thread lief wie gewünscht zum Ende, hat aber kein Freizeichen ausgespruckt)
    - Auf Threads warten dauert "ewig" (bsp: 4 Threads. Allein die 4 DllCalls in AutoIt dauern länger als die komplette Laufzeit des OP)

    lg
    M

  • moin leute,

    ich hab längere zeit die alte fasm.au3 verwendet. Und zwar ging und geht es mir nur darum aus einem inputfenster bytecode zu erzeugen, sowohl x86 als auch x64 ... letzteres war ein problem was ich hier mit zu lösen hoffte, es aber irgendwie nciht hinbekomme... evtl könnt ihr mich untersützen ... ich kompiliere sowohl als 32, als auch als 64 bit... 32 bit geht, aber bei 64 bit registern gehts nicht :(

    [autoit]

    Func _CreatBYTECODEofASM($setMode = 32)
    if $setMode = 32 then $setMode = "use32" ; Wir arbeiten im 32-Bit Modus
    if $setMode = 64 then $setMode = "use64" ; Wir arbeiten im 64-Bit Modus
    $AsmInput = "push rax"
    $AsmInputRA = StringSplit($setMode & @CR & $AsmInput,@CR)
    For $x=1 to $AsmInputRA[0]
    $z = StringRegExpReplace($AsmInputRA[$x], '\r', '')
    $z = StringRegExpReplace($z, '\n', '')
    Next
    $Bytecode = _FASM_CompileASM($AsmInputRA[2]) ; Binärcode erzeugen
    $Bytecode = StringTrimLeft($Bytecode,2)
    MsgBox(0,"Out", $Bytecode)
    Return $Bytecode
    EndFunc

    [/autoit]
  • Ich fand die FASM UDF von eukalyptus immer sehr "umständlich".
    Daher hatte ich mir selber eine FASM.au3 geschrieben die nur 3 Funktionen beinhaltet:

    FASM_Assemble($sAsm) > Gibt den Bytecode eins ASM Codes zurück
    FASM_Error($iError = @error, $iExtended = @extended) > Gibt den letzten Fehler von einer FASM_Assemble() Ausführung zurück
    FASM_Run(Func FASM_Run($dCode, $avParam = $FASM_RUN) > Führt einen Bytecode aus (Parameter können als Array angegeben werden)

    Ich hab dir mal die meine Version der FASM.au3 hochgeladen, jedoch ist eine DLL nötig die ebenfalls im Archiv beiliegt.
    Im Grunde brauchst du nur die FASM_Assemble() Funktion aufrufen und schon bekommst du den Bytecode als Rückgabewert ausgespuckt.

    3 Mal editiert, zuletzt von Yjuq (27. November 2014 um 21:35)