Well... it was a long time ago that I last tried anything like this, and my memory may be faulty. There are some "weird" things about Nasm's implementation of the 32-bit extensions to OMF (-f obj). If possible, I would suggest using "-f win32" - and a different linker. Or, possibly use "-f win32" and Agner Fog's "objconv" to convert the object file to OMF. It seems to me that Borland's tools are more sensitive to Nasm's "oddities" than other linkers(?). Alink seemed to work better(?).
One "problem" I see is that if we use "import", we need to "call [foo]" instead of "call foo"! I have no clear idea why this should be so. My recollection is that if we use "import", we don't need to link with a library(?)... at least with Alink, this is true.
EXTERN MessageBoxA
IMPORT MessageBoxA user32.dll
EXTERN ExitProcess
IMPORT ExitProcess kernel32.dll
SECTION code use32 class=CODE
..start: ; entry point for OMF
PUSH 00000040h
PUSH title
PUSH msg
PUSH 00000000h
CALL [MessageBoxA]
PUSH 00000000h
CALL [ExitProcess]
SECTION data use32
title db 'Titulo', 00h
msg db 'Mensaje', 00h
I've cut your code down to what I remember as the "minimum" of what I think "used to work" (with Alink, at least - not sure about Tlink32). See if it helps...
If you really need to use Borland's tools (delphi, in particular), try "-f win32" and "objconv"...
http://www.agner.org/optimize/#objconvIf you're not committed to Borland's tools, try "-f win32" and GoLink. This seems to be the most "popular" linker, these days (pity it isn't open source!). The NASMX package should include it, or get it from Jeremy Gordon's site... Hmmm, Jeremy's site seems to have disappeared(?)... Try NASMX.
Let us know how it goes, if you would...
Best,
Frank