flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
macomics 14 Apr 2025, 21:08
Have you read this and this?
It says here about "!". I haven't seen your entire code. But I suspect that you have used the library macro twice. Hence the import error. Macros do not invent anything, but only collapse what fasm/fasmg/fasm2 generates without their capabilities. To understand the actions of macros, it is useful to build a program a couple of times without using macro. Well, then gradually rewrite it, gradually adding new macros. |
|||
![]() |
|
kake_zinger 15 Apr 2025, 03:59
Sure let's see the code, it's for testing the fabulous @# (0..9) , @#f and @#b macros and other basic concepts:
Code: ; vim: set nocompatible filetype=fasm fileencoding=utf-8 tabstop=2 shiftwidth=2 softtabstop=2 expandtab showtabline=2 showcmd showcmdloc=last virtualedit=block: use AMD64, everything format PE64 console 5.0 entry start include 'win64ax.inc' include '@@.inc' _data cur_fmt db '%s',10, 5 dup(0) ; Current print format str_fmt_n db '%s',10, 5 dup(0) ; Default print format, with newline str_fmt db '%s ', 5 dup(0) ; Alt print format, space separated crlf db 13,10, 6 dup(0) line0 db 'Line 00',0 line1 db 'Line 01',0 line2 db 'Line 02',0 line3 db 'Line 03',0 line4 db 'Line 04',0 line5 db 'Line 05',0 line6 db 'Line 06',0 line7 db 'Line 07',0 line8 db 'Line 08',0 line9 db 'Line 09',0 lines db 'Line scrambler: ',0 _code start: ;push rbp ; Align stack to 16, nope _code contains sub rsp,8 already mov rbp, rsp ; Create a stack frame sub rsp, 0x30 ; 2 qword pushes and shadow space ;Test: , use xmm0 for m2m copy movq xmm0, qword [str_fmt_n] movq qword [cur_fmt], xmm0 @0: mov rdx, line0 call .printf jmp @9f @1: mov rdx, line1 call .printf jmp @8f @2: mov rdx, line2 call .printf jmp @6f @3: mov rdx, line3 call .printf jmp exit @4: mov rdx, line4 call .printf jmp @7f @5: mov rdx, line5 call .printf jmp @4b @6: mov rdx, line6 call .printf jmp @3b @7: mov rdx, line7 call .printf jmp @2b @8: mov rdx, line8 call .printf jmp @5b @9: mov rdx, line9 call .printf jmp @1b jmp exit .printf: ; Print one string, addr in rdx ; printf uses rcx and r9, restore them for example's sake push r9 push rcx push rbp mov rbp, rsp ;sub rsp, 32 ; Allocate local vars here, address with rbp - 8 * var# (1..4) mov rcx, cur_fmt ;mov rdx, string ; From caller xor r8,r8 xor r9,r9 sub rsp, 32 call [printf] add rsp, 32 mov rsp, rbp ; Undo local var allocation pop rbp pop rcx pop r9 ret exit: call [getch] ; Press anykey to exit mov ecx, 0 call [ExitProcess] _end start ;library msvcrt, 'MSVCRT.DLL' ;import msvcrt, printf, 'printf', getch, '_getch' ;include 'api\msvcrt.inc' ; Try to use autoimport section '.reloc' fixups data readable discardable if $ = $$ dd 0, 16 ; Dummy relocation entry if generated reloc would be empty end if Any combination of library/include/import after _end will not get printf imported. Especially library msvcrt, 'MSVCRT.DLL' include 'api\msvcrt.inc' works in Fasm (of course including kernel32 too) but not here with Fasm2 and _end macro. |
|||
![]() |
|
macomics 15 Apr 2025, 11:48
Let's take it in order.
Here is the _end macro from the win64ax.inc file Code: macro _end label _winx.entry := label ; It adds another section to your PE64 file - import section '.idata' import data readable writeable ; Next, the library macro creates the structure of the import section. ; In fact, this is a table that contains pointers to strings and subtables. ; It should be the only one in the section, and restarting the library macro will do nothing or, conversely, lead to an error. ; My version of the library macro has a directive that won't allow it to be called twice. library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL',\ gdi32,'GDI32.DLL',\ advapi32,'ADVAPI32.DLL',\ comctl32,'COMCTL32.DLL',\ comdlg32,'COMDLG32.DLL',\ shell32,'SHELL32.DLL',\ wsock32,'WSOCK32.DLL' ; Next are the includes of files with subtables for importing the function. ; In each of these files, just call the import macro and list the label + name pairs for all functions from the library. ; But the library label must already be present in the previous call to the library macro. ; We will not talk about the assistant macro for creating aliaces for A or W functions now. include! 'api/kernel32.inc' include! 'api/user32.inc' include! 'api/gdi32.inc' include! 'api/advapi32.inc' include! 'api/comctl32.inc' include! 'api/comdlg32.inc' include! 'api/shell32.inc' include! 'api/wsock32.inc' end macro That is, when using _end macro, you need to add your own (msvcrt) library to the library list. To do this, you will have to completely redefine this macro with a new set of libraries. |
|||
![]() |
|
bitRAKE 15 Apr 2025, 22:57
kake_zinger wrote: Any combination of library/include/import after _end will not get printf imported. win[32|64][A|W] - this is the base win[32|64][A|W]x - advanced macro win[32|64][A|W]xp - parameter counting Not changing the include files requires working from a lower level to add libraries - using the {base} include and specify the libraries explicitly in the source. You'll see that in any of the examples using additional libraries. The advanced layer and above incapsulates the API support to ONLY those present in the includes. Of course, it's highly recommend to change the include files, or build on top of the {base} layer - which was largely the approach I've taken with fasmg. ---- It seems there is always another way with fasmg! We can wrap the library macro: Code: macro library? definitions& library definitions,\ msvcrt, 'MSVCRT.DLL' import msvcrt, printf, 'printf', getch, '_getch' ; maybe package API functions: ; include! 'api/msvcrt.inc' end macro Let me know if you would like a complete example. |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.