News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

PUBLIC declaration problem in client module

Started by Buek, September 28, 2014, 01:12:57 PM

Previous topic - Next topic

Buek

I have an interesting problem with MASM 6.14 when trying to export a constant from a module with the PUBLIC statement (EXTERNDEF does not work due to a known MASM bug). The exporting module correctly uses the label defined as Var2= $$DataBuf+32  in its initialization code but when the same label Var2 is exported, the client module uses the address $$DataBuf instead of $$DataBuf+32. The added 32 bytes in the address get dropped in the export process. The client module imports the Var2 label as EXTERN Var2:DWORD. This results in the wrong Var2 address being used in the client module. Any help in resolving this issue would be highly welcome.

With best regards,

Buek
**********************************

The exact code in the exporting module looks like this (I omitted the code in the procedures WrStr etc to save space):

.386
.model flat,c
option casemap:none

.data
$$DataBuf db 64 DUP(0)
$$VAR EQU $$DataBuf
$$StrBuf0 db "String 1" ,0,0,0,0
$$StrBuf1 db "This is string 2" ,0,0
Var1= $$DataBuf
Var2= $$DataBuf+32

EXTERNDEF syscall R10:DWORD, syscall R11:DWORD, syscall oldcw:WORD, syscall temp_bcd:TBYTE, syscall buffer:DWORD, syscall BufferCounter:DWORD
PUBLIC Var1,Var2

.code
EXTERNDEF   $WrChar:NEAR,  $WrStr:NEAR,  $WrLn:NEAR

$WrChar  PROC ; code not shown to save space
$WrChar  ENDP

$WrStr  PROC ; code not shown to save space
$WrStr  ENDP

$WrLn  PROC ; code not shown to save space
$WrLn  ENDP


;==================================
;   IOOut PROCEDURE
;==================================
IOOut PROC
LEA  ESI,DWORD PTR [$$VAR+64]
LEA  EDI,DWORD PTR [Var1]
MOV  ECX,17
CLD
REP MOVSB
LEA  ESI,DWORD PTR [$$VAR+84]
LEA  EDI,DWORD PTR [Var2]           ; Var2 is used correctly here as $$DataBuf+32. The same reference in the client module results in $$DataBuf only being used by MASM
MOV  ECX,27
CLD
REP MOVSB
RET
IOOut ENDP
end

dedndave

EXTERNDEF syscall R10:DWORD, syscall R11:DWORD, syscall oldcw:WORD, syscall temp_bcd:TBYTE, syscall buffer:DWORD, syscall BufferCounter:DWORD

the use of "syscall" in this context makes no sense to me
now - i am not an expert, so maybe it's ok   :P

but, i think the real problem is the use of "=", and what you are expecting from it
TempVar1 = 6

it's a temporary reassignment of text
the assembler sees that and, unless TempVar1 is reassigned, replaces each occurance with the value 6
in the other source file, however, TempVar1 has no meaning, as it has not been assigned a value

dedndave

making Var1 and Var2 PUBLIC doesn't get the job done
notice, these constants are neither data, nor code - they have no address

what you might want to do, is to define the constants in each source file
or, better yet, place them in a common inc file, and include it in both sources

dedndave

the real symbol to make PUBLIC would be $$DataBuf
the assembler places the address of that item into the OBJ file

then, make all references to that address

Buek

Thanks for the replies. My comment is as follows:
1. The use of syscall is to link the two modules without an error. I found this to be working by trial and error. Substituting "=" by EQU in the assignment produces the same result.
2. The code which produces the problem is the output of a compiler which I wrote. I am now implementing separate compilation, so at assembly time, the client module does not see the internal offsets of the public variables which it imports.  The label Var2 (=$$DataBuf +32) does correctly reference $$DataBuf+32 in the exporting module i.e the statement  lea edi,dword ptr[Var2] loads the address $$Databuf+32 into edi. However, when the same statement is carried out in the client module, lea edi,dword ptr[Var2] loads the address of $$DataBuf into edi and not as one would expect the address of $$DataBuf+32. 
There is  a workaround for this problem but it would mean some significant changes in the compiler code which I prefer not to make. If I split $$DataBuf which is defined as $$DataBuf db 64 DUP(0) into two arrays such as $$DataBuf1 db 32 dup(0) and $$DataBuf2 db 32 dup(0) and assign Var2 = $$DataBuf2, then the code produces the desired result.

dedndave

well - working or not working   :biggrin:
it's very cluttered

i would probably define a structure (type)
BufStruct STRUCT
  Buf1 db 32 dup(?)
  Buf2 db 32 dup(?)
BufStruct ENDS


then, define the data
.data?
$$DataBuf BufStruct <>


declare only $$DataBuf as PUBLIC, and access the 2 members   :P
$$DataBuf.Buf1
$$DataBuf.Buf2

qWord

Quote from: Buek on September 28, 2014, 05:57:00 PM1. The use of syscall is to link the two modules without an error. I found this to be working by trial and error.
it just must be the same calling convention in all modules (not necessarily syscall) for name mangling.
Quote from: Buek on September 28, 2014, 05:57:00 PMHowever, when the same statement is carried out in the client module, lea edi,dword ptr[Var2] loads the address of $$DataBuf into edi and not as one would expect the address of $$DataBuf+32.
That is an bug of MASM 6.14/15. For Later version (7+ or JWASM) using equates (=) with PUBLIC, does work as intended.

Quote from: dedndave on September 28, 2014, 01:21:35 PMTempVar1 = 6
it's a temporary reassignment of text
no, MASM does handle equates/constants as integers. For code or data labels it does also save the corresponding information with the equate.
MREAL macros - when you need floating point arithmetic while assembling!

dedndave

Quote from: qWord on September 28, 2014, 08:43:53 PM
Quote from: dedndave on September 28, 2014, 01:21:35 PMTempVar1 = 6
it's a temporary reassignment of text
no, MASM does handle equates/constants as integers. For code or data labels it does also save the corresponding information with the equate.

what i meant by "reassignment of text":
each place the assembler sees "TempVar1", it replaces that text with the constant = 6

Vortex

Hi Buek,

The SYSCALL convention does not decorate the symbols but it requires stack balancing like the C calling convention.

dedndave

i guess "substitution" might have been a better term  :P

Buek

Thanks a lot everybody for their contributions. That PUBLIC equate phenomenon seems to be a bug, so I have to either work around it or use another assembler. Both will require some additional effort but at least I now know why I am doing this.

Best regards, Buek

Buek

I just downloaded and assembled the code with JWASM.  I am glad to report that the program assembled correctly. Obviously I stumbled over a MASM bug here. Thanks again to all for the help.

Regards, Buek