Ward

The Embedded Flat Assembler (FASM) UDF

17 posts in this topic

#1 ·  Posted (edited)

This UDF is similar to my previous Inline Assembly UDF, but only better. Because this one uses flat assembler, a open source and powerful assembler. See http://flatassembler.net/. Thanks to XDa from http://www.opensc.ws/ provide a "fasm.dll". So my job is just easy, warp it using my MemoryDll UDF.

 

The usage is also similar to previously, but a kind of different. FasmGetFuncPtr() will compile the source and return the address ready to be call. And FasmGetBasePtr() only return the base address without compiling and error handling. FasmGetBasePtr() is added for "org" directive.

 

Have fun. Maybe also take a look at AndyG's Fractals script.

 

FASM.zip (55.47K)

Number of downloads: 127

 

2010/03/19 Update Note:

# Embedded FASM version update to v1.68

# Add OOP version using AutoItObject, thanks to AutoItObject-Team

# New examples

# Better error handling, can handle errors in macro now

FASM.zip (141.76K)

Number of downloads: 601

 

2011/06/14 Update Note:

# Embedded FASM version update to v1.69

# AutoItObject UDF version update to v1.2.8.0

# MemoryDLL UDF update to X64 supported version

# New BinaryCall UDF to run a machine code in "Binary" format

# Add FASMServer and FASMServerDemo, demonstrate embedded assembly in AutoIt X64

# Add fast BinaryXOR function (Both X86/X64) as an example (in FASMServerDemo2)

FASM.zip

Edited by Ward
1 person likes this

新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了

 

Share this post


Link to post
Share on other sites



Hi.....

what can i say other than THANK YOU! :(

Andy

Share this post


Link to post
Share on other sites

Thanks a lot for this sharing this ward. Great little examples too. Very helpful. 5*. :(

Share this post


Link to post
Share on other sites

Do you know if there is a way I can pass parameters to the autoit functions?

Share this post


Link to post
Share on other sites

Do you know if there is a way I can pass parameters to the autoit functions?

Check out DllCallbackRegister.


Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites

Do you know if there is a way I can pass parameters to the autoit functions?

It is easy:

#include "FASM.au3"
Dim $Fasm = FasmInit()
Demo7()

Func Demo7()
    ; Demo 7: Call AutoIt Func From Assembly And Pass Parameters
    $AutoItFunc = DllCallbackRegister("AutoItFunc2", "int", "str;uint;uint")
    FasmReset($Fasm)
    FasmAdd($Fasm, "use32") 
    FasmAdd($Fasm, "org " & FasmGetBasePtr($Fasm))
    FasmAdd($Fasm, "rdtsc")
    FasmAdd($Fasm, "push eax")
    FasmAdd($Fasm, "push edx")
    FasmAdd($Fasm, "push s1")
    FasmAdd($Fasm, "call " & DllCallbackGetPtr($AutoItFunc))
    FasmAdd($Fasm, "ret")
    FasmAdd($Fasm, "s1: db 'RDTSC = %08X%08X', 0")
    ConsoleWrite(String(FasmGetBinary($Fasm)) & @CRLF)
    $Ret = MemoryFuncCall("int", FasmGetFuncPtr($Fasm))
    DllCallbackFree($AutoItFunc)
EndFunc

Func AutoItFunc2($String, $Edx, $Eax)
    MsgBox(0, "AutoItFunc", StringFormat($String, $Edx, $Eax))
EndFunc

新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了

 

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Thanks ward. That helped a lot. :(

But now I'm confused on why the data in s1 gets set after the 'ret'. I figured it would be the other way around.

FasmAdd($Fasm, "s1: db 'RDTSC = %08X%08X', 0")
FasmAdd($Fasm, "ret")

Anyway, just another item on the list of "things to read and learn about." Thanks again.

Edited by Beege

Share this post


Link to post
Share on other sites

Object version is refreshing.

Thanks Ward.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

Excellent job again Ward.

Out of curiosity, since FASM supports x64 code ('use64'), what would you say the chances are of someday compiling & integrating a 64-bit DLL. I'm getting well versed in x64 code so I'd be able to provide 64-bit versions of the Examples for ya.

Thanks again for all your work

Ascend4nt

Share this post


Link to post
Share on other sites

This UDF is updated to support AutoIt X86/X64.


新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了

 

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

I like this UDF. It generates very fast and compact code. To see some working examples where it's used to optimize loops and fix x64 issues take a look at this example. See section 1.6 and 1.7. If you have downloaded the examples and want to take a closer look at one of the optimizations go to "OpenGL 1.1TexturesTunnelsutilitiesfasm". I have left the test files (with -a and -b in the names) to optimize loops in "Tunnel effect 2.au3".

When I write assembler source I like to write it in a format like shown in the code boxes.

This is an example with MessageBoxA:

; FASM assembler code

        ; MessageBoxA( hWnd, lpText, lpCaption, uType )

        ; $tData = DllStructCreate( "byte[80];byte[16];handle;ptr[3]" )
        ; Element 3, index 1, offset  96 ( 96) : handle hWnd
        ; Element 4, index 1, offset 100 (104) : ptr    lpText
        ; Element 4, index 2, offset 104 (112) : ptr    lpCaption
        ; Element 4, index 3, offset 108 (120) : ptr    MessageBoxA
        ; (Numbers in brackets are x64 offsets)

        ; Parameters:
        ; [ebp + 08] : uType
        ; [ebp + 12] : $pData

        use32
        push       ebp
        mov        ebp,                esp

        mov        eax,                [ebp + 12]          ; eax is pointer in $tData table

        ; Call MessageBoxA
        ;pusha                                              ; Save registers on stack
        push       dword [ebp +  08]                       ; 4. parameter: uType
        push       dword [eax + 104]                       ; 3. parameter: lpCaption
        push       dword [eax + 100]                       ; 2. parameter: lpText
        push       dword [eax +  96]                       ; 1. parameter: hWnd
        call       dword [eax + 108]                       ; Call MessageBoxA
        ;popa                                               ; Restore registers

        pop        ebp
        ret        08
And the x64 code:

; FASM assembler code

        ; MessageBoxA( hWnd, lpText, lpCaption, uType )

        ; $tData = DllStructCreate( "byte[80];byte[16];handle;ptr[3]" )
        ; Element 3, index 1, offset  96 ( 96) : handle hWnd
        ; Element 4, index 1, offset 100 (104) : ptr    lpText
        ; Element 4, index 2, offset 104 (112) : ptr    lpCaption
        ; Element 4, index 3, offset 108 (120) : ptr    MessageBoxA
        ; (Numbers in brackets are x64 offsets)

        ; Parameters:
        ; rcx : uType
        ; rdx : $pData

        ; x64 function calling convention for parameter passing:
        ; First  parameter: int/ptr -> rcx,  float -> xmm0
        ; Second parameter: int/ptr -> rdx,  float -> xmm1
        ; Third  parameter: int/ptr -> r8,   float -> xmm2
        ; Fourth parameter: int/ptr -> r9,   float -> xmm3
        ; The rest goes onto the stack

        use64

        mov        rax,                rdx                 ; rax is pointer in $tData table

        ; Call MessageBoxA
        sub        rsp,                40                  ; Stack space and alignment
        mov        r9,                 rcx                 ; 4. parameter: uType
        mov        rcx,                qword [rax +  96]   ; 1. parameter: hWnd
        mov        rdx,                qword [rax + 104]   ; 2. parameter: lpText
        mov        r8,                 qword [rax + 112]   ; 3. parameter: lpCaption
        call       qword [rax + 120]                       ; Call MessageBoxA
        add        rsp,                40                  ; Restore stack pointer

        ret
Note that FASM.au3 cannot be run as a 64 bit program. But it certainly can generate 64 bit code. To generate the binary code run MessageBoxA-x64-mk-bin.au3.

This is the AutoIt program to call the assembler functions:

#include "Includes\Utilities.au3"

Opt( "MustDeclareVars", 1 )

Global $hGui = GUICreate( "MessageBoxA demo with FASM", 400, 300 )

Global $pCode, $pData, $tData

GetFasmCode()
GUISetState()
MessageBoxA1()
MessageBoxA2()

Func GetFasmCode()

    ; --- Fasm data ---

    ; MessageBoxA( hWnd, lpText, lpCaption, uType )

    ; Use a struct to pass data from AutoIt to the assembler function. uType will be passed as a parameter.

    $tData = DllStructCreate( "byte[80];byte[16];handle;ptr[3]" )
    ; To make things easier add extra space in tables in the structure until they are 8-bytes aligned. It's also 
    ; nice to have a little bit of extra space. Then you can use this space for an intermediate result, if that
    ; should be necessary. Without the need to change all the offsets. It seems also to be easier to put the
    ; x86/x64 dependant data e.g. handle and ptr in the end of the structure.

    DllStructSetData( $tData, 3, $hGui )                           ; Element 3, index 1, offset  96 ( 96) : handle hWnd
    DllStructSetData( $tData, 4, DllStructGetPtr( $tData, 1 ), 1 ) ; Element 4, index 1, offset 100 (104) : ptr    lpText
    DllStructSetData( $tData, 4, DllStructGetPtr( $tData, 2 ), 2 ) ; Element 5, index 2, offset 104 (112) : ptr    lpCaption
    Local $ptr = GetProcAddress( "user32.dll", "MessageBoxA" )
    DllStructSetData( $tData, 4, $ptr, 3 )                         ; Element 4, index 3, offset 108 (120) : ptr    MessageBoxA
                                                                   ; (Numbers in brackets are x64 offsets)
    $pData = DllStructGetPtr( $tData )

    ; --- Fasm code ---

    Local $sCode, $tCode

    If @AutoItX64 Then
        If Not ReadX64code( "MessageBoxA-x64.bin", "MessageBoxA-x64-mk-bin.au3", $sCode ) Then Exit
    Else
        Local $oFasm = FasmInit()
        If Not ReadFasmCode( "MessageBoxA.asm", $oFasm, $sCode ) Then Exit
        FasmExit( $oFasm )
    EndIf
    $pCode = _MemVirtualAlloc( 0, 128, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE )
    $tCode = DllStructCreate( "byte[128]", $pCode )
    DllStructSetData( $tCode, 1, $sCode )

EndFunc

Func MessageBoxA1()

    SetTextCaption( "This is the first test.", "Test 1" )

    DllCallAddress( "none", $pCode, "uint", 0, "ptr", $pData )

EndFunc

Func MessageBoxA2()

    SetTextCaption( "This is the second test.", "Test 2" )

    Local $aRet = DllCallAddress( "int", $pCode, "uint", 33, "ptr", $pData ), $sText
    If $aRet[0] = 1 Then                               ; 33 = OK + Cancel + Question-mark icon
        $sText = "OK button."
    Else
        $sText = "Cancel button (or close)."
    EndIf
    SetTextCaption( $sText, "Clicked" )
    DllCallAddress( "none", $pCode, "uint", 0, "ptr", $pData )

EndFunc

Func SetTextCaption( $sText, $sCaption )
    ; MessageBoxA( hWnd, lpText, lpCaption, uType )
    ; $tData = DllStructCreate( "byte[80];byte[16];uint[2];handle;ptr[3]" )
    DllStructSetData( $tData, 1, $sText )                          ; Element 1, index 1, offset   0       : byte   $sText
    DllStructSetData( $tData, 1, 0, StringLen( $sText ) + 1 )      ; Null-terminated string
    DllStructSetData( $tData, 2, $sCaption )                       ; Element 2, index 1, offset  80       : byte   $sCaption
    DllStructSetData( $tData, 2, 0, StringLen( $sCaption ) + 1 )   ; Null-terminated string
EndFunc
You find the utility functions GetProcAddress, ReadFasmCode, MakeX64code, ReadX64code and the MessageBoxA files here:

MessageBoxA.7z

Copy BinaryCall.au3, FASM.au3 and MemoryDll.au3 from Ward's UDF to the Includes folder when you extract the 7z-file.

Links

flat assembler

Programmer's Manual

Intel® 64 and IA-32 Architectures Software Developer Manuals

Introduction to 64 Bit Intel Assembly Language

x64 Software Conventions

The Art of Assembly Language

Edited by LarsJ
1 person likes this

Share this post


Link to post
Share on other sites

@Ward

Download Link seems to be dead...


AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

Share this post


Link to post
Share on other sites

I found FASM.zip on my old XP. Downloaded october 2012.

FASM.zip

File is corrupted ?


Signature beginning:   Wondering who uses AutoIT and what it can be used for ?
* GHAPI UDF - modest begining - comunication with GitHub REST API *
ADO.au3 UDF     POP3.au3 UDF     XML.au3 UDF    How to use IE.au3  UDF with  AutoIt v3.3.14.x  for other useful stuff click the following button

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST API *

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 - BETA * ADO.au3 UDF SMTP Mailer UDF *

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Best coding practices * 

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * 

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2017-06-04

Share this post


Link to post
Share on other sites

I found FASM.zip on my old XP. Downloaded october 2012.

FASM.zip

it's not common to see a gzip archive, but thanks it works.


AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

Share this post


Link to post
Share on other sites

Can I use this to detect a pixel, which would be faster than autoit's pixelget or pixelsearch or pixelchecksum?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now