Related Projects > NASMX

Using NASMX generates invalid executable

(1/2) > >>

aVoX:
Hi!

This is the first time i try NASMX, so I tried to write the smallest program possible:

--- Code: ---%include "inc\nasmx.inc"
%include "inc\win32\windows.inc"
%include "inc\win32\kernel32.inc"
%include "inc\win32\user32.inc"

[section .text]
proc WinMain,   ptrdiff_t hInstance,        \
                ptrdiff_t hPrevInstance,    \
                ptrdiff_t lpCmdLine,        \
                dword     nCmdShow
locals none
    NOP
endproc

ENTRY example
proc example,    dword     arg_count,        \
                ptrdiff_t arg_var
locals none

    invoke  GetModuleHandleA, NULL
    invoke  WinMain, eax, NULL, NULL, SW_SHOWNORMAL
    invoke  ExitProcess, 0

endproc
--- End code ---

After building using this script:

--- Code: ---@echo off
nasm.exe -o example.obj -f win32 -Ox example.asm

if errorlevel 1 goto err_asm

golink.exe /mix /console /entry example /fo example.exe example.obj kernel32.dll user32.dll

if errorlevel 1 goto err_link

echo Build succeeded
goto end

:err_asm
echo An assembly error occured!
echo.
pause
goto end

:err_link
echo An error occured while linking!
echo.
pause
goto end

:end
--- End code ---
I get an executable, as expected. But when I try to run it, Windows tells me "example.exe is not a valid Win32 application."

How am I using NASMX wrong in not even 30 lines of code?
Thanks in advance!

Rob Neff:
You have linkage issues, not necessarily NASMX issues.

Change the linker line in your script from this:


--- Code: ---golink.exe /mix /console /entry example /fo example.exe example.obj kernel32.dll user32.dll

--- End code ---

to this:


--- Code: ---golink.exe /entry _main /fo example.exe example.obj kernel32.dll user32.dll

--- End code ---

One thing that the ENTRY macro does is help ensure the correct starting point for your program regardless of OS.  For Windows this becomes "_main" ( on Linux it is just "main" without the underscore prefix ).   It's just one of those things you must always do.  We can't automate this in build scripts you write.

Unfortunately Jeremy's http://www.godevtool.com website is currently down so I can't refer you to the documentation on the /mix command line argument which is also causing you issues.  That command line argument won't become necessary until you start "mixing" Win32 with C calls ( eg: different name mangling schemes ).

The GoLink /console arg is OK if you're about to build a console-only app.  This helps the linker in not pulling in the graphic library stuff.  Just stick with the linker line I provided above until you need further help.  :)

aVoX:
Hey Rob, thanks a lot for your input!
I played around a lot with my build script in the meantime, (incuding toggling /mix and /console switches), but nothing changed. Now I exchanged /entry example for /entry _main and removed /mix, but still, the error message stays the same (the output executable, or at least its size, also stays exactly the same, the linker always creates a file of 1,536 bytes). I also tried to re-use a build script from NASMX' "demos" directory, again with the same result. For these reasons I believed, that it must be a problem with NASMX.
Wrong. I just linked everything using MSVC's LINK utility, which produces a slightly larger, but at least working executable (not cool, I want to use distributable freeware). So, any ideas on that?

By the way, I actually want to mix STDCALLs (for Win32 stuff) and CDECLs (for the functions in my own program), at least this is what I am used to, coming from a C world. (Or is there a good reason not to use CDECL everywhere possible?)

About the /console switch - for debugging reasons I want a console I can dump my debug info in, when everything is in a state I am satisfied with, I am going to remove the console (in which case the code stays the same, but the build scripts /console switch has to go, if I understand correctly)

Thanks, and bye.

Edit:
Now I programmed a small MessageBox program manually, not using NASMX, with the same build script and it worked. Another case where it looks like the usage of NASMX destroys the executable, even though I know now, that's not the case. Strange stuff going on...

Edit 2:
Sorry for swearing, but what the f*** is going on? Now I put something I don't even reference into the data section and it works like expected.

Rob Neff:

--- Quote from: aVoX on September 14, 2013, 09:29:20 AM ---Hey Rob, thanks a lot for your input!
I played around a lot with my build script in the meantime, (incuding toggling /mix and /console switches), but nothing changed. Now I exchanged /entry example for /entry _main and removed /mix, but still, the error message stays the same (the output executable, or at least its size, also stays exactly the same, the linker always creates a file of 1,536 bytes). I also tried to re-use a build script from NASMX' "demos" directory, again with the same result. For these reasons I believed, that it must be a problem with NASMX.
Wrong. I just linked everything using MSVC's LINK utility, which produces a slightly larger, but at least working executable (not cool, I want to use distributable freeware). So, any ideas on that?

--- End quote ---


--- Quote from: aVoX on September 14, 2013, 09:29:20 AM ---Edit 2:
Sorry for swearing, but what the f*** is going on? Now I put something I don't even reference into the data section and it works like expected.

--- End quote ---

Can you attach the source and build script you used that led up to your EDIT#2 issue?  I would like to see for myself what is going on.  It definitely sounds like linker issues to me, possibly segment related, given that LINK worked but GoLink did not.  I've noticed all our demos include at least a .data and/or .bss section.  Or perhaps GoLink just doesn't like you!  ;D


--- Quote from: aVoX on September 14, 2013, 09:29:20 AM ---By the way, I actually want to mix STDCALLs (for Win32 stuff) and CDECLs (for the functions in my own program), at least this is what I am used to, coming from a C world. (Or is there a good reason not to use CDECL everywhere possible?)

--- End quote ---

Programming Win32 assembly can be a pain but you can indeed mix STDCALL and CDECL within the same program using NASMX.  You simply need to ensure that you use the IMPORT, PROTO, and PROC macros properly so that function names are mangled and imported/exported properly.

Both conventions prepend an underscore to the function name.  STDCALL will append "@XX" to the function name where "XX" is the number of parameter bytes.  STDCALL also uses the Pascal function return convention ( eg: ret 8 ) where you don't need to "add esp, xxx" after each call to restore the stack like you do in CDECL.  Obviously you can never create a vararg function with STDCALL. 

NASMX, while not perfect, does its best to handle all that book-keeping stuff.  When you're calling your own functions use whatever convention gives you the smallest and/or fastest bits desired.

Frank Kotler:
I've been doubtful from the start that NASMX could be the issue. NASMX is a macro set, it outputs code that Nasm will either assemble or barf on. If there were an error in NASMX, it might create incorrect code, but I don't see any reason that it should create incompatible code.

I suspect Rob's right that it's a linker issue. I recall that Nasm was accused of a "bug" wherein if we had a .bss section but no .data section, it would crash the loader (this was in Linux). Turned out that it was a certain version of ld - code from Gas did the same thing. An older or newer version of ld worked fine. Perhaps something similar here?

I can't run GoLink in Linux. I can, however run Alink (with some help from a poster Stewart(?) here - long ago - I got it to build on Linux). So I tried it. Avox's code as posted above... I had to flip the backslashes to forward slashes to get the includes to open, but otherwise left it alone. Got a couple of "unresolved external" errors. I remember hearing that we could create our own library by using the "import" directive and assembling as "-f obj". So I did so. I ASSumed that both were in kernel32.dll. This may not be correct. In any case, Alink produced an .exe. I have no idea if Windows will eat it or not. (I'm so stubborn I won't even run WINE!)  Can I attach an .exe? I'll try it... In general, I don't approve of downloading executables, but if anyone wants to try it - AT YOUR OWN RISK...

Edit: Okay, I can't attach an executable... so I zipped it up. Caution: unzips into current directory.

Best,
Frank

Navigation

[0] Message Index

[#] Next page

Go to full version