Unable to generate a .exe file from an assembly file

Started by Quin, April 30, 2025, 09:05:14 PM

Previous topic - Next topic

Quin

Hi,
I have this code:
option casemap:none

includelib user32.lib
includelib kernel32.lib

ExitProcess PROTO :DWORD
MessageBoxA PROTO :DWORD,:DWORD,:DWORD,:DWORD

.data
title db "Hello!", 0
message db "This is raw assembly!", 0

.code
start:
invoke MessageBoxA, NULL, offset message, offset title, MB_OK
invoke ExitProcess, 0
end start
and I try compiling it with:
Quotecc test.asm
It gives me test.obj, but doesn't link it into a binary, despite me not providing the /a option. What gives?
Use the assembly, Luke.

Vortex

Hi Quin,

Kindly, instead of cc, can you use Poasm allowing to set the specific options? That is much more easy.

I modified your code as some equates were missing :

Batch file to build the project :

\Pellesc\bin\poasm /AIA32 Test.asm
\Pellesc\bin\polink /SUBSYSTEM:WINDOWS /LIBPATH:\Pellesc\Lib\Win Test.obj

The updated source code :

[code].386
.model flat,stdcall
option casemap:none

includelib user32.lib
includelib kernel32.lib

ExitProcess PROTO :DWORD
MessageBoxA PROTO :DWORD,:DWORD,:DWORD,:DWORD

MB_OK equ 0
NULL  equ 0

.data

title   db "Hello!", 0
message db "This is raw assembly!", 0

.code

start:
invoke MessageBoxA,NULL,ADDR message,ADDR title,MB_OK
invoke ExitProcess, 0

END start

About preferring ADDR instead of OFFSET while invoking functions :

QuoteAn OFFSET in MASM is a location (literally an OFFSET) from the front of the file where an address using the keyword ADDR can be either a stack local OR an OFFSET. ADDR is usually restricted to higher level INVOKE syntax.

https://masm32.com/board/index.php?msg=53727
Code it... That's all...

Quin

VOrtex,
You're the man! This fully works!
What if I want to compile as x64 though? I assume I don't need .386 or .model flat, stdcall, but when removing /AIA32 and those two lines and recompiling with the win64 lib folder, the binary is generated, but instantly crashes. Is this mostly meant for generating 32-bit code, or do I just have some mismatched protos (e.g. DWORD instead of QWORD or similar)?
It is raw assembly so maybe 32-bit is just easier/better, but I enjoy having all the memory available to me :D
Use the assembly, Luke.

Vortex

Hi Quin,

The calling convention of 64-asm is different, it's the 64-bit fastcall convention : the first four parameters passed to rcx,rdx,r8 and r9. The following ones are passed to the stack. Also, the stack alignment is very strict, it must be always 16-bit.

Here is the example code :

MessageBoxA PROTO :QWORD,:QWORD,:QWORD,:QWORD
MessageBox EQU <MessageBoxA>

ExitProcess PROTO :QWORD

MB_OK equ 0
NULL  equ 0

.data

msg    db 'Hello!',0
title  db 'MsgBox',0

.code

main PROC PARMAREA=4*SIZEOF QWORD

    invoke MessageBox,NULL,ADDR msg,ADDR title,MB_OK
    invoke ExitProcess,0

main ENDP

END

Poasm takes care of the stack alignment.

Batch file to build the project :

\PellesC\bin\poasm /AAMD64 Hello.asm
\PellesC\bin\polink /SUBSYSTEM:WINDOWS /LIBPATH:\PellesC\Lib\Win64 /ENTRY:main Hello.obj kernel32.lib user32.lib

About PARMAREA :

QuoteThe optional PARMAREA = expression specifies the size of the parameter area. It must be specified if the procedure is calling other procedures, and must be the size of the largest parameter area passed to any procedure. It can be larger (will just waste space), but it may not be smaller. The expression must be a constant expression.

A nice introduction to x64 Assembly :

https://www.codeproject.com/Articles/17263/Moving-to-Windows-Vista-x64

Code it... That's all...

Quin

Hi Vortex,
Ah, I see! The woes of Assembly programming, I suppose :D
Doable for sure, but I can now see why you prefer /AIA32. Much cleaner
Thanks for your help!
Use the assembly, Luke.

Vortex

Hi Quin,

With thanks to Pelle, Poasm makes easier 64-bit assembly coding. The assembler handles all the stack organization including alignment to 16 bytes.
Code it... That's all...

Quin

Hi Vortex,
Yes, I saw that topic. Very cool stuff! I love this toolchain :)
Use the assembly, Luke.