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
#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)
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
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
;###########################################################
;# X86
;###########################################################
# 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]
# _Loop:
# _FASM_DBG("_DebugREG_32")
# _FASM_DBG("_DebugXMM_32")
# paddb xmm0, xmm4
# paddw xmm1, xmm5
# paddd xmm2, xmm6
# addps xmm3, xmm7
# sub ecx, 1
# jnz _Loop
#cs
X86
#ce
# ret 8
#ASMEND
Func _DebugREG_32($tData)
ConsoleWrite("-= Debug X86 ==========================================" & @CRLF)
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
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"))
ConsoleWrite("> Byte Xmm0: " & DllStructGetData($tXMM, "xmm0") & @CRLF)
ConsoleWrite("> Word Xmm1:")
For $i = 1 To 8
ConsoleWrite(" " & DllStructGetData($tXMM, "xmm1", $i))
Next
ConsoleWrite(@CRLF)
ConsoleWrite("> DWord Xmm2:")
For $i = 1 To 4
ConsoleWrite(" " & DllStructGetData($tXMM, "xmm2", $i))
Next
ConsoleWrite(@CRLF)
ConsoleWrite("> Float Xmm3:")
For $i = 1 To 4
ConsoleWrite(" " & DllStructGetData($tXMM, "xmm3", $i))
Next
ConsoleWrite(@CRLF)
ConsoleWrite(@CRLF)
EndFunc ;==>_DebugXMM_32
#ASM _ASM_Test64
# use64
;###########################################################
;# X64
;###########################################################
# 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]
# _Loop:
# _FASM_DBG("_DebugREG_64")
# _FASM_DBG("_DebugXMM_64")
# paddb xmm0, xmm4
# paddw xmm1, xmm5
# paddd xmm2, xmm6
# addps xmm3, xmm7
# sub rcx, 1
# jnz _Loop
#cs
X64
#ce
# ret
#ASMEND
Func _DebugREG_64($tData)
ConsoleWrite("-= Debug X64 ==========================================" & @CRLF)
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
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"))
ConsoleWrite("> Byte Xmm0: " & DllStructGetData($tXMM, "xmm0") & @CRLF)
ConsoleWrite("> Word Xmm1:")
For $i = 1 To 8
ConsoleWrite(" " & DllStructGetData($tXMM, "xmm1", $i))
Next
ConsoleWrite(@CRLF)
ConsoleWrite("> DWord Xmm2:")
For $i = 1 To 4
ConsoleWrite(" " & DllStructGetData($tXMM, "xmm2", $i))
Next
ConsoleWrite(@CRLF)
ConsoleWrite("> Float Xmm3:")
For $i = 1 To 4
ConsoleWrite(" " & DllStructGetData($tXMM, "xmm3", $i))
Next
ConsoleWrite(@CRLF)
ConsoleWrite(@CRLF)
EndFunc ;==>_DebugXMM_64
Hier noch eine (vorkompilierte) Version von "Conway's Game of Life" (benötigt aktuelle Beta)
Spoiler anzeigen
#AutoIt3Wrapper_Autoit3Dir=c:\Program Files (x86)\AutoIt3\Beta
#AutoIt3Wrapper_UseX64=n
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
;#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")
Opt("MustDeclareVars", 1)
Opt("GUIOnEventMode", 1)
_GDIPlus_Startup()
Global $iLife_X = 600 * 4
Global $iLife_Y = 600 * 4
Global $iLife_PatX = $iLife_X + 2 + 16
$iLife_PatX = $iLife_PatX + 16 - Mod($iLife_PatX, 16)
Global $iLife_PatY = $iLife_Y + 4
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)
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)
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)
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)
Global $iGui_W = 600
Global $iGui_H = 600
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)
GUISetState()
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]_Random()
[/autoit] [autoit][/autoit] [autoit]Global $iTimer = TimerInit(), $iSteps = 0
While 1
_Calc()
_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)
$iSteps += 1
WinSetTitle($hGui, "", "Conway's Game of Life " & $iLife_X & "x" & $iLife_Y & " / " & StringFormat("%.1f", 1000 / (TimerDiff($iTimer) / $iSteps), 1) & " fps")
WEnd
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
#ASM _ASM_Calc
# use32
# mov edx, [esp+12]
# mov ebx, [edx+8] ;PatX
;###########################################################
;# 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
; 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
; 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
; 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
# add esi, ebx
# add edi, ebx
# mov cl, [edi+1]
# mov ch, [edi+eax]
# mov [esi], ch
# mov [esi+eax+1], cl
;###########################################################
;# 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
;###########################################################
;# 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...
# 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
# add edi, 16
# sub ecx, 16
# jnz _LoopX
# sub eax, 1
# jnz _LoopY
;###########################################################
;# 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
# 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
;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
# _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
# ret 12
#ASMEND
#ASM _ASM_SetBitmap
# use32
;###########################################################
;# 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]
# mov eax, 1
# movd xmm6, eax
# pshufd xmm6, xmm6, 0
# movd xmm5, [edx+20]
# pshufd xmm5, xmm5, 0
# pxor xmm7, xmm7
[/autoit] [autoit][/autoit] [autoit]# _Loop:
# movdqu xmm0, [esi]
# movdqa xmm2, xmm0
# punpcklbw xmm0, xmm7
# punpckhbw xmm2, xmm7
# movdqa xmm1, xmm0
# movdqa xmm3, xmm2
# punpcklbw xmm0, xmm7
# punpcklbw xmm2, xmm7
# punpckhbw xmm1, xmm7
# punpckhbw xmm3, xmm7
# pcmpeqd xmm0, xmm6
# pcmpeqd xmm1, xmm6
# pcmpeqd xmm2, xmm6
# pcmpeqd xmm3, xmm6
# 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
# add esi, 16
# sub ecx, 16
# jnz _Loop
# ret 12
#ASMEND
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
#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
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
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
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!
(Ich hab mir einige Sachen ganz dreist abgeguckt )
lgE