flat assembler
Message board for the users of flat assembler.

Index > Main > Fasm2 _end macro, how to import/include other libraries?

Author
Thread Post new topic Reply to topic
kake_zinger



Joined: 15 Jul 2004
Posts: 59
kake_zinger 14 Apr 2025, 18:56
I'm struggling to add other libraries using _end macro of Fasm2 (in win64ax.inc), every attempt fails, like:
Code:
library msvcrt, 'MSVCRT.DLL'
import msvcrt, printf, 'printf', getch, '_getch'
    

In the end ended up editing win64ax.inc directly, adding:
Code:
        library kernel32,'KERNEL32.DLL',\
                [...snip...]
                wsock32,'WSOCK32.DLL',\
                msvcrt, 'MSVCRT.DLL'

  include! 'api/msvcrt.inc'
    
why is there a "!" after include, anyway?

msvcrt.inc i made, this far only containing:
Code:

; MSVCRT API calls

import msvcrt,\
       printf,'printf',\
       getch,'_getch'
    

There must be some more portable way, or do i have to include my modified win64ax.inc and msvcrt.inc (and other newly created import libraries) with every program..?

I know it works if done traditionally with library/import (import each function manually) or library/include 'api\msvcrt.inc' (autoimport any function listed in msvcrt.inc) but trying to learn that cool new smooth Fasm2 style.
Post 14 Apr 2025, 18:56
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1097
Location: Russia
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.
Post 14 Apr 2025, 21:08
View user's profile Send private message Reply with quote
kake_zinger



Joined: 15 Jul 2004
Posts: 59
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.
Post 15 Apr 2025, 03:59
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1097
Location: Russia
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.
Post 15 Apr 2025, 11:48
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4207
Location: vpcmpistri
bitRAKE 15 Apr 2025, 22:57
kake_zinger wrote:
Any combination of library/include/import after _end will not get printf imported.
The windows includes of the fasmg package are like a layered onion:

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    
... now when "_end" executes the library macro it is your macro that gets invoked.

Let me know if you would like a complete example.

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 15 Apr 2025, 22:57
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.