News:

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

Declare "data" after "code" ?

Started by WYVERN666, December 27, 2011, 03:45:12 PM

Previous topic - Next topic

WYVERN666

Hi all. Why i cant reference data declared after the code section with the OFFSET keyword?. 

According with one of the Iczelion's tutorials:
Quote
"addr cannot handle forward reference while offset can"

This is a example of my MASM output:
Quote
aja.asm(14) : error A2006: undefined symbol : var_1
aja.asm(14) : error A2114: INVOKE argument type mismatch : argument : 3
aja.asm(14) : error A2006: undefined symbol : var_2
aja.asm(14) : error A2114: INVOKE argument type mismatch : argument : 2

Thanks.


dedndave

yah - since i have learned 32-bit masm, i have not had this problem much
because the data is usually conveniently declared before the code

with older versions of MASM, we wrote .COM (tiny model) programs all the time
the data was quite often at the end of the code segment
but, in order to forward reference the data, you may have to use a size override operator
this is because, when the assembler makes its' first pass, it does not know the size of the data item
        mov dword ptr SomeLabel,0

i am not sure if something changed in this regard from MASM version 5.1 to the newer versions

if the data is local, it would seem cumbersome to create a forward reference
but, i suppose it could be overcome by writing your own prologue and epilogue

WYVERN666

Hi dedndave, thanks for your answer. But i cant make it work with INVOKE sintax, look for example calling MessageBoxA:   


INVOKE MessageBoxA, 0, dword offset var_1, dword offset var_2, 0


Y tried with "ptr" too, but now i get:

I get:
Quote
aja.asm(14) : error A2206: missing operator in expression
aja.asm(14) : error A2114: INVOKE argument type mismatch : argument : 3
aja.asm(14) : error A2114: INVOKE argument type mismatch : argument : 2

dedndave

these are strings - not dwords

you might try "offset byte ptr var_1"

however, when you use the offset operator, it should not need the size

i have never had this problem - lol

if that does not work, try this:

var_1_address EQU offset byte ptr var_1
var_2_address EQU offset byte ptr var_2
INVOKE MessageBoxA, 0, var_1_address, var_2_address, 0



WYVERN666

Well, is funny but it doesnt work in any way... i think i am going to put the DATA section before CODE. I cant believe MASM cant work the other way.

dedndave

show us your code
let me try...

at any rate - it is much simpler to put all the data before the code
if that isn't "pretty", put it in an INC file   :U

dedndave

yah - a quick browse of the masm manual shows that things have changed since version 5.1   :P

WYVERN666

I made the MessageBox example to show you, is just that invoke plus a Exitprocess invoke and a data section with title and message values.
And what you mean with that things changed?, i have MASM 6.14.8444.

WYVERN666

If you can compile just a simple MessageBox program with a DATA section placed after CODE, please show me how! :bg.

The MASM manual says about CODE and DATA: "The .MODEL directive must precede these directives", but anything about the order betwen themselves.

jj2007

Dave is on the right track - this works:

include \masm32\include\masm32rt.inc

.code
start: push MB_OK
push offset AppName
push chr$("Hello World")
push 0
call MessageBox
exit

.data
AppName db "Masm32:", 0

end start


Quote from: WYVERN666 on December 27, 2011, 05:12:50 PMI made the MessageBox example to show you, is just that invoke plus a Exitprocess invoke and a data section with title and message values.

To the OP: Why are you so lazy? Do you think it's our job to construct the missing bits around your code? What I posted is a complete example. What you posted is a fragment which I usually would not look at, but in this case I was curious to find out whether Dave's theory was correct.

WYVERN666

Hi jj2007!. No, im not lazy. There is no missing nothing, is just a MessageBox. When dedndave asked me for the code it was for the "real program" code, wich is pointless kause i already presented the same problem for a theortical so simple MessageBox program that outputs the same error.

We "conclude" that the problem is not present when PUSHING and CALLING, also your code works fine without the size operator (is important detail the "END start" after the DATA section). But still i cant make this works with INVOKE sintax.

MichaelW

IMO it makes more sense to just put the data section first, but this works:

include \masm32\include\masm32rt.inc
EXTERNDEF AppName:BYTE
.code
start:
  invoke MessageBox, 0, chr$("Hello World"), OFFSET AppName, MB_OK
exit
.data
AppName db "Masm32:", 0
end start
eschew obfuscation

hutch--

The reason is very simple, ML loads data on its first pass so the data must be available BEFORE the code that calls it. You can test this easily by using a .DATA block in the code section.


mov eax, offset mydata
.data
mydata dd 1234
.code


It fails because ML has not yet loaded the OFFSET of mydata into its data structure. Do it the other way round and it works fine.


.data
mydata dd 1234
.code
mov eax, offset mydata


Basically ML does not support forward referencing. Same goes for LOCAL variables, they MUST be declared first within a proc.

I know this was how guys wrote code in TASM 15 years ago but the world has changed and your code layout must change with it.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

dedndave

it brings up an interesting point, though
i may set up masm 5.10 for writing 16-bit .com files   :P

MichaelW

#14
What I don't understand is that in my code ML knows what the size of an offset address is, so it has everything it needs to encode the AppName push instruction except the address. Even with the data section preceding the code section, and no EXTERNDEF, in the listing file the address is encoded as zero and marked as relocatable, so the linker will resolve it:

00000002  68 00000000 R   *    push   dword  ptr OFFSET FLAT:AppName

So why with invoke does ML need to know what the type of the AppName symbol is?

...

And after thinking about this a while, the answer is, it doesn't. I had to specify the type BYTE in my EXTERNDEF statement so it would not conflict with the actual definition. ML apparently just needed to know that AppName would be defined at some point before the linking stage.

eschew obfuscation