News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Link.exe expecting symbols with _prefixed

Started by madhur_ahuja, December 03, 2010, 04:21:26 AM

Previous topic - Next topic

madhur_ahuja

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 ?

ToutEnMasm


This can be only an error of syntax.He can be solve easily if you post your code here.

donkey

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.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

madhur_ahuja

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 ?

donkey

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.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

dedndave

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

hutch--

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.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

madhur_ahuja

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.

dedndave

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

dedndave

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

hutch--

> 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.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

dedndave

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

dedndave

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

MichaelW

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.
eschew obfuscation

madhur_ahuja

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