The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: madhur_ahuja on December 03, 2010, 04:21:26 AM

Title: Link.exe expecting symbols with _prefixed
Post by: madhur_ahuja on December 03, 2010, 04:21:26 AM
Hi , I have assembled two files Example.asm and io.asm.
Io.asm defines some functions as public:
PUBLIC itoaproc, atoiproc

Example.asm tries to consume these functions by declaring them as EXTERN

However, while linking, there is an error
Cannot resolve reference _itoaproc, _atoiproc

Why is it expecting underscore prefixed symbols ? What is the solution ?
Title: Re: Link.exe expecting symbols with _prefixed
Post by: ToutEnMasm on December 03, 2010, 07:33:43 AM

This can be only an error of syntax.He can be solve easily if you post your code here.
Title: Re: Link.exe expecting symbols with _prefixed
Post by: donkey on December 03, 2010, 08:01:48 AM
With Microsoft's ml.exe, when you declare a symbol as PUBLIC an underscore (_) is prefixed to the symbol in the OBJ file.  Perhaps when you declare it as EXTERN you have to also add the underscore.
Title: Re: Link.exe expecting symbols with _prefixed
Post by: madhur_ahuja on December 03, 2010, 08:19:17 AM
Quote from: donkey on December 03, 2010, 08:01:48 AM
With Microsoft's ml.exe, when you declare a symbol as PUBLIC an underscore (_) is prefixed to the symbol in the OBJ file.  Perhaps when you declare it as EXTERN you have to also add the underscore.

Thanks for the confirmation. I believe this behaviour was not in MASM 5.1. Is there any workaround to it ?
Title: Re: Link.exe expecting symbols with _prefixed
Post by: donkey on December 03, 2010, 08:24:01 AM
Have you tried defining the symbol using the underscore in the EXTERN directive ? Beyond that I am not a MASM user so I cannot really help but the majority of members here are MASM guys, someone might have a better solution.
Title: Re: Link.exe expecting symbols with _prefixed
Post by: dedndave on December 03, 2010, 10:55:02 AM
you might try using EXTERNDEF instead of PUBLIC/EXTERN

http://www.masm32.com/board/index.php?topic=15480

what i learned in that thread was that EXTERNDEF replaces both/either
Title: Re: Link.exe expecting symbols with _prefixed
Post by: hutch-- on December 03, 2010, 11:46:13 AM
madhur_ahuja,

Instead of members having to guess what you are doing and what masm version you are using, post some code instead of wasting their time.
Title: Re: Link.exe expecting symbols with _prefixed
Post by: madhur_ahuja on December 03, 2010, 10:43:08 PM
Now that was rude. I think I provided enough info. OK. Attached are files. I have corrected the funtion names to include _ as suggested above.

I am using same version of ml.exe and link.exe as provided by latest build of masm32.
Title: Re: Link.exe expecting symbols with _prefixed
Post by: dedndave on December 03, 2010, 11:22:48 PM
Hutch can be as nice or as rude as he likes - it is his forum

PUBLIC _itoaproc, _atoiproc, _dtoaproc, _atodproc, _outproc, _inproc, _szlenproc
PROC's are already PUBLIC - remove that line

_itoaproc    PROC   NEAR32
in FLAT model, you will rarely use FAR procs, and i am not sure NEAR32 is valid
just use PROC
_itoaproc    PROC
Title: Re: Link.exe expecting symbols with _prefixed
Post by: dedndave on December 03, 2010, 11:44:12 PM
also - good idea to specify root-relative paths in include/includelib

when you include a file, it is as though you pasted the text in where the include is
so - you do not need EXTERN, PUBLIC, EXTERNDEF
if you were creating a lib file (IO.LIB), then you need them
Title: Re: Link.exe expecting symbols with _prefixed
Post by: hutch-- on December 04, 2010, 01:16:56 AM
> Now that was rude.

No, just efficient, (well almost, no PROTOTYPES).

Stripped out the leading underscores, added STDCALL and removed the NEAR32 and "io.asm" builds into an object module correctly.

HELLO.ASM is missing the prototypes for the procedures in IO.ASM and apparently some macros.

Now I know that many nof our members are magicians who walk on water and are modest about it but with missing prototytpes and macros even they cannot make what is not there. Post that code and the rest looks reasonably simple to fix.

Just as an aside, the code looks like it was written back in the middle 90s for masm 6.11 by the notation and code style. Once you get it up and going you can do a lot better and a lot faster if it matters.
Title: Re: Link.exe expecting symbols with _prefixed
Post by: dedndave on December 04, 2010, 03:03:19 AM
as Hutch mentioned, your problems are largely syntax

however, i also noticed that the procs use BASIC calling convention
easy to fix - the parms are reverse order
some parms are words - we always pass dwords to maintain stack alignment
not as easy to fix if other parts of this library are written to pass words - lol
but, it can and should be done

another big issue is that they are written as procs, but you are trying to call them as macros
in this case, they really should be procs

push/pop:
for win32, procs should preserve EBX, ESI, EDI, EBP, and the DF should remain cleared
EAX, ECX, and EDX can be trashed, and are often used to return results
you may assume the DF will be cleared
however, if the rest of this library is written to preserve a set DF, you may want to keep that until you fix all the procs
i see a lot of them pushf and popf - again - these are words
use pushfd and popfd to maintain stack alignment
pushing and poping can be done an easier way (see example below)

PROTO's:
we usually place protos near the beginning of the program
they do not need to declare stdcall or the names of parms (see example below)
once a proc has been PROTO'ed, you may use invoke to call it
here is a simple example of using PROTO
;proto's are placed near the beginning of the program

MyProc  PROTO   :DWORD,:DWORD
;       .
;       .
;       .
        .CODE

MyProc  PROC    uses ebx esi edi dwSource:DWORD,lpBuffer:DWORD

        LOCAL   dwSign:DWORD

        mov     eax,dwSource
        cdq
        or      edx,1
        mov     dwSign,edx    ;+1 of pos, -1 if neg
        mov     edi,lpBuffer
;       .
;       .
;       .
        ret

MyProc  ENDP

notice that the "uses ebx esi edi" takes care of pushing/poping those registers
the masm prologue/epilogue takes care of the stack frame (ebp), assigning space for locals, and adjusting the stack after RET

now, to use the proc...
        INVOKE  MyProc,value,offset buffer
the PROTO must preceed the INVOKE in the source file
we pass the address of buffer - not it's contents
Title: Re: Link.exe expecting symbols with _prefixed
Post by: dedndave on December 04, 2010, 04:10:58 AM
oh - i forgot to mention one thing....
all the procs you have in io.asm are replaced with modern better faster code in the masm32 libraries   :bg
for the most part, thanks to Mr. Rude   :U
Title: Re: Link.exe expecting symbols with _prefixed
Post by: MichaelW on December 04, 2010, 06:12:39 AM
What a mess. The file io.asm looks like some code I have by Richard Detmer, that has the same right to left parameter order. The Detmer examples specify:

.model flat, stdcall

And work out the difference with a set of interface macros.
Title: Re: Link.exe expecting symbols with _prefixed
Post by: madhur_ahuja on December 04, 2010, 06:13:24 AM
You are right. its the code from that book. 

My Bad! I forgot to include header file, which converts those procs to macros and takes care of other concerns you mentioned. I am pasting it below:

;IO.H - header file for I/O macros
; 32-bit version for flat memory model
; R. Detmer   last revised 8/2000
.NOLIST     ; turn off listing
.386

           EXTERN itoaproc:near32, atoiproc:near32
           EXTERN dtoaproc:near32, atodproc:near32
           EXTERN inproc:near32, outproc:near32

itoa        MACRO dest,source,xtra      ;; convert integer to ASCII string

           IFB <source>
           .ERR <missing operand(s) in ITOA>
           EXITM
           ENDIF

           IFNB <xtra>
           .ERR <extra operand(s) in ITOA>
           EXITM
           ENDIF

           push   ebx                ;; save EBX
           mov    bx, source
           push   bx                 ;; source parameter
           lea    ebx,dest           ;; destination address
           push   ebx                ;; destination parameter
           call   itoaproc           ;; call itoaproc(source,dest)
           pop    ebx                ;; restore EBX
           ENDM

atoi        MACRO  source,xtra          ;; convert ASCII string to integer in AX
                                     ;; offset of terminating character in ESI

           IFB      <source>
           .ERR   <missing operand in ATOI>
           EXITM
           ENDIF

           IFNB     <xtra>
           .ERR   <extra operand(s) in ATOI>
           EXITM
           ENDIF
           push   ebx ;; save EBX
           lea    ebx,source         ;; source address to EBX
           push   ebx                ;; source parameter on stack
           call   atoiproc           ;; call atoiproc(source)
           pop    ebx                ;; parameter removed by ret
           ENDM

dtoa        MACRO  dest,source,xtra   ;; convert double to ASCII string

           IFB    <source>
           .ERR   <missing operand(s) in DTOA>
           EXITM
           ENDIF

           IFNB   <xtra>
           .ERR   <extra operand(s) in DTOA>
           EXITM
           ENDIF

           push   ebx                ;; save EBX
           mov    ebx, source
           push   ebx                ;; source parameter
           lea    ebx,dest           ;; destination address
           push   ebx                ;; destination parameter
           call   dtoaproc           ;; call dtoaproc(source,dest)
           pop    ebx                ;; restore EBX
           ENDM

atod        MACRO  source,xtra        ;; convert ASCII string to integer in EAX
                                   ;; offset of terminating character in ESI
           IFB    <source>
           .ERR <missing operand in ATOD>
           EXITM
           ENDIF

           IFNB   <xtra>
           .ERR <extra operand(s) in ATOD>
           EXITM
           ENDIF

           lea    eax,source         ;; source address to EAX
           push   eax                ;; source parameter on stack

           call   atodproc           ;; call atodproc(source)
                                     ;; parameter removed by ret
           ENDM

           output MACRO string,xtra  ;; display string
           IFB    <string>
           .ERR   <missing operand in OUTPUT>
           EXITM
           ENDIF
           IFNB   <xtra>
           .ERR <extra operand(s) in OUTPUT>
           EXITM
           ENDIF

           push   eax                ;; save EAX
           lea    eax,string         ;; string address
           push   eax                ;; string parameter on stack
           call   outproc            ;; call outproc(string)
           pop    eax                ;; restore EAX
           ENDM

input MACRO dest,length,xtra          ;; read string from keyboard

           IFB    <length>
           .ERR <missing operand(s) in INPUT>
           EXITM
           ENDIF

           IFNB   <xtra>
           .ERR <extra operand(s) in INPUT>
           EXITM
           ENDIF

           push   ebx                ;; save EBX
           lea    ebx,dest           ;; destination address
           push   ebx                ;; dest parameter on stack
           mov    ebx,length         ;; length of buffer
           push   ebx                ;; length parameter on stack
           call   inproc             ;; call inproc(dest,length)
           pop    ebx                ;; restore EBX
           ENDM

.NOLISTMACRO ; suppress macro expansion listings
.LIST        ; begin listing
Title: Re: Link.exe expecting symbols with _prefixed
Post by: madhur_ahuja on December 04, 2010, 06:14:54 AM
Quote from: MichaelW on December 04, 2010, 06:12:39 AM
What a mess. The file io.asm looks like some code I have by Richard Detmer, that has the same right to left parameter order. The Detmer examples specify:

.model flat, stdcall

And work out the difference with a set of interface macros.


I only see .MODEL FLAT in my version.
Title: Re: Link.exe expecting symbols with _prefixed
Post by: MichaelW on December 04, 2010, 06:33:00 AM
Quote from: madhur_ahuja on December 04, 2010, 06:14:54 AM
I only see .MODEL FLAT in my version.

Yes, now that I check I had added the stdcall (in 2004).
Title: Re: Link.exe expecting symbols with _prefixed
Post by: japheth on December 04, 2010, 06:50:33 AM

The thread is a mess.

I don't think that it's a good idea to modify the sources. As you said, they are from a book, so it almost certainly once DID work. The sample uses the ".model flat" directive ( which tells me that they are intended for Masm v6.xx ), so everything should work without changes if you use Masm v6.14 included in Masm32.

The problem mentioned in the first post is a "name decoration" problem. Most likely it occurs because  an option (-Gd) was missing in the command line when Masm was launched.

Btw, the io.inc which you posted still lacks the "output" macro, which is used in hello.asm, so it is of little help.
Title: Re: Link.exe expecting symbols with _prefixed
Post by: MichaelW on December 04, 2010, 07:12:37 AM
The "output" macro is there - it's just hard to see because the name is tabbed over to the position of the code. After I sorted out the paths in hello.asm:

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include io.inc
.LISTALL
includelib \masm32\lib\kernel32.lib


I assembled, linked, and tested with this batch file:

@echo off
set file1="io"
set file2="hello"
set lib=c:\masm32\lib
set path=c:\masm32\bin;%path%
if exist %file1%.obj del %file1%.obj
if exist %file2%.obj del %file2%.obj
if exist %file2%.exe del %file2%.exe
ml /c /coff %file1%.asm
pause
ml /c /coff %file2%.asm
pause
Link /SUBSYSTEM:CONSOLE %file2%.obj %file1%.obj
pause
%file2%.exe
echo.
echo.
pause


And there were no problems.
Title: Re: Link.exe expecting symbols with _prefixed
Post by: japheth on December 04, 2010, 07:34:09 AM
Quote from: MichaelW on December 04, 2010, 07:12:37 AM
The "output" macro is there - it's just hard to see because the name is tabbed over to the position of the code.
...
And there were no problems.

Thanks! Yes, no problems. And I additionally tried to remove the "_"-prefixes in io.asm and assembled it with the -Gd option: this also works.
Title: Re: Link.exe expecting symbols with _prefixed
Post by: madhur_ahuja on December 04, 2010, 07:52:34 AM
Thanks guys. Either specifying -Gd or using .model flat, stdcall solves the problem.

However, I believe -Gd means C style function calling and naming conventions as per
http://msdn.microsoft.com/en-us/library/s0ksfwcf.aspx

But I don't see stack being cleaned up by caller as specified in:
http://en.wikipedia.org/wiki/X86_calling_conventions

Am I missing something ?
Title: Re: Link.exe expecting symbols with _prefixed
Post by: MichaelW on December 04, 2010, 08:27:32 AM
For a procedure that uses the C calling convention ML would encode the return instruction to not remove the parameters from the stack, and invoke would add code to remove the parameters from the stack after the call returned. In my tests with ML6.15, and a STDCALL procedure, -Gd did affect the naming convention, but did not affect the encoding of the return instruction or the calling convention that invoke assumed.
Title: Re: Link.exe expecting symbols with _prefixed
Post by: donkey on December 04, 2010, 12:22:52 PM
Quote from: madhur_ahuja on December 04, 2010, 07:52:34 AM
But I don't see stack being cleaned up by caller as specified in:
http://en.wikipedia.org/wiki/X86_calling_conventions

Am I missing something ?

He has explicitly made the procedures into STDCALL by using RET with a value, this will adjust the stack by the number of bytes specified, for example in the _dtoaproc his return is ret 8 which will add 8 to ESP before returning.
Title: Re: Link.exe expecting symbols with _prefixed
Post by: dedndave on December 04, 2010, 12:23:52 PM
BASIC uses this calling convention - reverse parm order, but corrects the stack as in STDCALL

anyways, this is some old stuff - lol
if this is for school, you may not have any choice but to work with it
but, if you are trying to learn masm from a book (on your own), i suggest you get some new stuff
this library can create some bad habits for you

all registers are preserved and the math procs set the flags to indicate the results
very few modern procs work that way
the worst thing is, some procs use word-sized parms
for modern code that uses word parms, dwords are passed to maintain stack alignment

if you modify the procs to be up to date, then much of the example code in the book will not work
Title: Re: Link.exe expecting symbols with _prefixed
Post by: madhur_ahuja on December 04, 2010, 12:27:13 PM
Yes, this is for self learning and not a school. Can you suggest some other reference ?
Title: Re: Link.exe expecting symbols with _prefixed
Post by: dedndave on December 04, 2010, 12:31:24 PM
truthfully, you do not need to buy a book
install the masm32 package
the package contains macros, libraries,  example code, help files, tutorials
the link is in the upper right hand corner of the forum
also in those links, you will find Iczelion's Tutorials - a great way to get started for win32

EDIT
have a look around in those links - a lot of material
another thing you will find in there is a link to Intel Programmer's Reference Manuals
that will cover the instruction set

also - Randy Hyde has a nice online reference....
http://www.arl.wustl.edu/~lockwood/class/cs306/books/artofasm/toc.html
Title: Re: Link.exe expecting symbols with _prefixed
Post by: madhur_ahuja on December 04, 2010, 12:41:13 PM
Thanks a lot  :U