Author of FASM has developed a simple dll to assemble just inside the memory.
The link to fasm dll: http://board.flatassembler.net/topic.php?t=6239

I have ported example of fasm.dll usage with detailed error handling.
There are many areas where the fasm.dll can be used as a backend for build-in scripting facilities or new simple basic compiler

Note
Not all fasm examples can be assembled using this way. Macro operators, modern asm statements and include statements does not supported. However, a real working example (PE or MZ executable file) can be achieved.

Usage:
1. Download fasmDll.zip from the link above
2. Extract fasm.dll into the folder with your source code

Screenshots:


Discussion
https://www.powerbasic.com/support/p...d.php?p=405849

Code:
#PBFORMS CREATED V2.01
#COMPILE EXE
#DIM ALL

#INCLUDE ONCE "WIN32API.INC"
#INCLUDE ONCE "COMMCTRL.INC"
#INCLUDE ONCE "PBForms.INC"
%IDD_DIALOG1  =  101
%TXT_TEXTBOX1 = 1001
%CMD_BUTTON1  = 1002
%TXT_TEXTBOX2 = 1003

DECLARE FUNCTION fasm_GetVersion   LIB "FASM.DLL" ALIAS "fasm_GetVersion" () AS DWORD
DECLARE FUNCTION fasm_Assemble     LIB "FASM.DLL" ALIAS "fasm_Assemble" _
                                                  (BYVAL pSource AS DWORD, _
                                                   BYVAL pFasmMemory AS DWORD, _
                                                   BYVAL cMemorySize AS DWORD, _
                                                   BYVAL passLImit AS DWORD, _
                                                   BYVAL hDispPipe AS LONG ) AS LONG

DECLARE FUNCTION fasm_AssembleFile LIB "FASM.DLL" ALIAS "fasm_Assemble" _
                                                  (BYVAL pSourceFile AS DWORD, _
                                                   BYVAL pFasmMemory AS DWORD, _
                                                   BYVAL cMemorySize AS DWORD, _
                                                   BYVAL passLImit AS DWORD, _
                                                   BYVAL hDispPipe AS LONG ) AS LONG

DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG

' demo source code
$fasm_source_demo = _
    "org 100h" & $CRLF & _
    "mov ah,09h" & $CRLF & _
    "mov dx,text" & $CRLF & _
    "mov ah,09h" & $CRLF & _
    "int 21h" & $CRLF & _
    "int 20h" & $CRLF & _
    "text db ""Hello!"", 24h" & $CRLF

%SOURCE_SIZE = 24000&
%COMPIL_SIZE = &H80000&

UNION Ubuff
    out_len AS DWORD
    errcode AS LONG
END UNION

UNION Ufile
    out_data AS DWORD
    errline  AS LONG
END UNION

UNION UOffs
    file_offset AS DWORD
    macro_calling_line AS DWORD
END UNION

TYPE TLINE_HEADER
  file_path   AS DWORD
  line_number AS DWORD
  offs AS UOffs
  macro_line  AS DWORD
END TYPE

TYPE TFASM_STATE
    cond AS DWORD
    buff AS UBuff
    file AS UFile
END TYPE

'==================================================================
' PURPOSE
'     Assemble FASM code and output to binary file
' INPUT
'    1. inSCR: input source code
'    2. OutBinFile: output filename (optional)
' RETURN
'    Detailed error message if any or Formatted hexadecimal representation of
'    assembled file on success
'==================================================================
FUNCTION fasm (BYVAL inSrc$, BYVAL OutBinFile$) AS STRING
    LOCAL FASM_STATE  AS TFASM_STATE
    LOCAL LINE_HEADER AS TLINE_HEADER

    LOCAL a1 AS STRING * %SOURCE_SIZE, pa1 AS STRING PTR, _
          b1 AS STRING * %COMPIL_SIZE, pb1 AS BYTE   PTR, _
          binrBuf, binrHex, Out_Msg AS STRING, _
          r,i AS LONG

    IF LEN(insrc$) = 0 THEN
       ?"Nothing to assemble. No FASM code",0,"Error"
       EXIT FUNCTION
    END IF

    ' append NUL if necessary
    IF ASC(insrc$,-1) <> 0 THEN insrc$ &= $NUL

    a1  = insrc$
    pa1 = VARPTR(a1)
    b1  = STRING$(%COMPIL_SIZE, 0)
    pb1 = VARPTR(b1)

    ' start assembling
    CALL fasm_Assemble (pa1, pb1, %COMPIL_SIZE, 100, 0) TO r

    ' populate the STATE structure
    TYPE SET FASM_STATE = LEFT$(b1, SIZEOF(TFASM_STATE)) ' <-- POKE$ VARPTR(FASM_STATE), LEFT$(b1, SIZEOF(TFASM_STATE))

    ' handle error messages
    IF r THEN
       ' populate the line number structure
       TYPE SET LINE_HEADER = PEEK$( FASM_STATE.file.errline, SIZEOF(TLINE_HEADER) )
       FUNCTION = Get_Fasm_Error_Msg (inSrc$, FASM_STATE, LINE_HEADER)
       EXIT FUNCTION
    END IF

    binrBuf = PEEK$(FASM_STATE.file.out_data, FASM_STATE.buff.out_len)

    IF LEN(OutBinFile$) THEN
       DIM F AS LONG: F=FREEFILE: OPEN OutBinFile$ FOR OUTPUT AS #f
       PRINT #f,binrBuf;
       CLOSE #f
    END IF
    FOR i = 1 TO FASM_STATE.buff.out_len
        IF i MOD 10 =0 THEN
           binrHex &= $CRLF
        ELSE
           binrHex &= HEX$( ASC(binrBuf,i), 2) & $SPC
        END IF
    NEXT i
    FUNCTION = binrHex
END FUNCTION

'==================================================================
' PURPOSE
'    Decode aseemble conditions and error codes into the readable format
' INPUT
'    1. inSCR: input source code
'    2. FS - TFASM_STATE structure
'    3. LH - LINE_HEADER structure
' RETURN
'    Detailed error message if any or empty string on success
'==================================================================
FUNCTION GET_FASM_ERROR_MSG ( BYVAL srcCode AS STRING, BYVAL FS AS TFASM_STATE, BYVAL LH AS TLINE_HEADER ) AS STRING
    LOCAL err_msg, f_state_msg, f_code_msg AS STRING

    f_state_msg = SWITCH$(FS.cond = -1,"INVALID PARAMETER",_
                          FS.cond = -2,"OUT OF MEMORY",_
                          FS.cond = -3,"ISTACK OVERFLOW",_
                          FS.cond = -4,"SOURCE NOT FOUND",_
                          FS.cond = -5,"UNEXPECTED END OF SOURCE",_
                          FS.cond = -6,"CANNOT GENERATE CODE",_
                          FS.cond = -7,"FORMAT LIMITATIONS EXCEDDED",_
                          FS.cond = -8,"WRITE FAILED")

    IF FS.cond = 2 THEN
       err_msg = "Error " & LTRIM$(STR$(FS.buff.errcode)) & ": " & READ$(ABS(FS.buff.errcode+100)) & $CRLF & _
                 " Line " & LTRIM$(STR$(LH.line_number)) & ": " & PARSE$(srcCode, $CRLF, LH.line_number)
    ELSEIF FS.cond = 0 THEN
       err_msg = ""
    ELSEIF FS.cond = 1 THEN
       err_msg = "Working ..."
    ELSE
       err_msg = "Compilation Aborted. " & f_state_msg
    END IF

    FUNCTION = err_msg

    DATA "FILE NOT FOUND","ERROR READING FILE", "INVALID FILE FORMAT", "INVALID MACRO ARGUMENTS", "INCOMPLETE MACRO"
    DATA "UNEXPECTED CHARACTERS", "INVALID ARGUMENT", "ILLEGAL INSTRUCTION", "INVALID OPERAND", "INVALID OPERAND SIZE"
    DATA "OPERAND SIZE NOT SPECIFIED", "OPERAND SIZES DO NOT MATCH", "INVALID ADDRESS SIZE", "ADDRESS SIZES DO NOT AGREE"
    DATA "PREFIX CONFLICT", "LONG IMMEDIATE NOT ENCODABLE", "RELATIVE JUMP OUT OF RANGE", "INVALID EXPRESSION"
    DATA "INVALID ADDRESS", "INVALID VALUE", "VALUE OUT OF RANGE", "UNDEFINED SYMBOL", "INVALID USE OF SYMBOL"
    DATA "NAME TOO LONG", "INVALID NAME", "RESERVED WORD USED AS SYMBOL",  "SYMBOL ALREADY DEFINED", "MISSING END QUOTE"
    DATA "MISSING END DIRECTIVE", "UNEXPECTED INSTRUCTION", "EXTRA CHARACTERS ON LINE", "SECTION NOT ALIGNED ENOUGH"
    DATA "SETTING ALREADY SPECIFIED", "DATA ALREADY DEFINED", "TOO MANY REPEATS", "SYMBOL OUT OF SCOPE", "USER ERROR", "ASSERTION FAILED"

END FUNCTION


FUNCTION PBMAIN()
    PBFormsInitComCtls (%ICC_WIN95_CLASSES OR %ICC_DATE_CLASSES OR %ICC_INTERNET_CLASSES)
    ShowDIALOG1 %HWND_DESKTOP
END FUNCTION

CALLBACK FUNCTION ShowDIALOG1Proc()
    LOCAL tSrc, oSrc AS STRING
    IF CB.MSG = %WM_COMMAND THEN
        IF CB.CTL = %IDCANCEL THEN DIALOG END CB.HNDL,0
        IF CB.CTL = %CMD_BUTTON1 AND CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN
           CONTROL GET TEXT CB.HNDL, 1001 TO tSrc
           CALL fasm(tSrc, "MyFile.bin") TO oSrc
           CONTROL SET TEXT CB.HNDL, 1003, oSrc
        END IF
    END IF
END FUNCTION

FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
    LOCAL lRslt  AS LONG
    LOCAL hDlg   AS DWORD
    LOCAL hFont1 AS DWORD
    LOCAL hFont2 AS DWORD

    LOCAL fVer AS DWORD, sVersion AS STRING

    ' Get Fasm Version
    fVer = fasm_GetVersion()
    sVersion = USING$("#_.#", LO(WORD, fVer), HI(WORD, fVer))

    DIALOG NEW hParent, "Flat Assemler " & sVersion, 288, 226, 179, 228, TO hDlg

    CONTROL ADD TEXTBOX, hDlg, %TXT_TEXTBOX1, "", 3, 3, 171, 102, %WS_CHILD _
        OR %WS_VISIBLE OR %WS_BORDER OR %WS_TABSTOP OR %WS_HSCROLL OR _
        %WS_VSCROLL OR %ES_LEFT OR %ES_MULTILINE OR %ES_AUTOHSCROLL OR _
        %ES_AUTOVSCROLL OR %ES_WANTRETURN, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT _
        OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
    CONTROL ADD BUTTON,  hDlg, %CMD_BUTTON1, "Assemble ...", 3, 105, 171, 15
    CONTROL ADD TEXTBOX, hDlg, %TXT_TEXTBOX2, "", 3, 120, 171, 105, %WS_CHILD _
        OR %WS_VISIBLE OR %WS_BORDER OR %WS_TABSTOP OR %WS_HSCROLL OR _
        %WS_VSCROLL OR %ES_LEFT OR %ES_MULTILINE OR %ES_AUTOHSCROLL OR _
        %ES_AUTOVSCROLL OR %ES_WANTRETURN, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT _
        OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
    FONT NEW "Helvetica", 8, 0, %RUSSIAN_CHARSET TO hFont1
    FONT NEW "Fixedsys", 8, 0, %RUSSIAN_CHARSET TO hFont2
    CONTROL SET FONT hDlg, %TXT_TEXTBOX1, hFont1
    CONTROL SET FONT hDlg, %TXT_TEXTBOX2, hFont2
    CONTROL SET TEXT hDlg, 1001, $fasm_source_demo
    DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
    FONT END hFont1
    FONT END hFont2
    FUNCTION = lRslt
END FUNCTION