flat assembler
Message board for the users of flat assembler.

Index > Main > Assembling multiple source files

Author
Thread Post new topic Reply to topic
LnS



Joined: 17 May 2010
Posts: 2
LnS
Hello everyone!

I've got a question for you guys: Is there any way at all to use multiple source files in a project assembled with FASM?

I know it's possible to have the source separated in multiple .inc files then using the 'Include' directive to make it so everything is in a single file, but I was actually looking for something a little more elegant, as that usually ends up looking pretty confusing in larger projects, and I'm not too keen on the idea of having to include a different file for each section of the PE that references a part of the source.

What I'm trying to say is I'd like to have the source code split into several .asm modules, each one with their own .data, .text and .idata sections, then have the assembler compile them to MS COFF files and link them together automatically.

I can't seem to find a way to do it though. It would be great if FASM featured an 'Import' directive with which you could specify a source file and it would first assemble then link it to the final executable for you.

If that's not possible though, I'd appreciate if you kind people could direct me as to how exactly one should define and call public procedures in COFF object files from an .asm file that has yet to be assembled.

I can't seem to get my head around the 'extrn' definitions for importing APIs in the MS COFF files either, since apparently you can't have an import table on them, so any help with that would be greatly appreciated.

Sorry if I'm not altogether familiar with these concepts, I'm still trying to learn assembly as best I can. Sad

Thanks in advance!
Post 17 May 2010, 01:09
View user's profile Send private message Reply with quote
bitshifter



Joined: 04 Dec 2007
Posts: 764
Location: Massachusetts, USA
bitshifter
You can have all the sections you want, but FASM has no internal linker.
Post 17 May 2010, 03:50
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
LnS,

Separate compile and link stages are OK with FASM (although you apparently will need linker). Import from DLLs usually requires import libraries for them (GoLink provides capability to use export directories of those DLLs to be used directly) and _/_imp_/@ name decoration in extrn directives:
Code:
; coff1.fasm
  format  MS COFF
     include "Win32AX.Inc"

 .code
       public  _msg
        extrn   "__imp__MessageBoxA@16" as MessageBox: dword
proc _msg c lpText: dword, lpCaption: dword
   invoke  MessageBox, HWND_DESKTOP, [lpText], [lpCaption], MB_OK
      ret
endp    
Code:
; coff2.fasm
      format  MS COFF
     include "Win32AX.Inc"

 .code
       public  start
start:
 extrn   _msg
        ccall   _msg, _text, _caption
       ret

     .data
_text  db      "Hello, world!", 0
_caption db     "extrn/public", 0    
Linking with either

link /subsystem:windows /entry:start coff1.obj coff2.obj user32.lib

or

GoLink.exe coff1.obj coff2.obj user32.dll

produces working PE (GoLink seems to understand _/_imp_/@ decoration).

Matt Pietrek wrote nice explanation in his fine Under The Hood MSJ column relating this matter.
Post 17 May 2010, 19:49
View user's profile Send private message Reply with quote
LnS



Joined: 17 May 2010
Posts: 2
LnS
Thanks baldr, that's exactly what I was looking for! Smile

Just one thing, in the definition for extrn "__imp__MessageBoxA@16" as MessageBox: dword , is the syntax supposed to reflect the following pattern: extrn "__imp__{ApiName}@{LengthInBytesOfAllArguments}" as {ExportName}: {ReturnType} for any given API? [/i]
Post 17 May 2010, 20:15
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
It is more like "__imp__{ApiName}@{LengthInBytesOfAllArguments}" as {SymbolToBeUsedInSource}: {SymbolType}

Note that __imp__* are dword pointers to functions (for that reason baldr used invoke instead of stdcall)
Post 17 May 2010, 21:08
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
LnS,

The pattern is simple:
  1. MessageBoxA is the undecorated function name;
  2. stdcall convention decorates name as _MessageBoxA@16 (4 arguments 4 bytes each);
  3. declspec(dllimport) prepends _imp_, that yields _imp__MessageBoxA@16 as undecorated name for pointer in IAT;
  4. this pointer variable gets _ prefix according to standard conventions.
I've already explained this mechanics in "extrn" topic. There is slight difference under _WIN64, step 2 is omitted (so in 64-bit User32.Lib IAT entry is named __imp_MessageBoxA).
Post 18 May 2010, 03:27
View user's profile Send private message 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-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.