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.
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
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
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
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.
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
yah - a quick browse of the masm manual shows that things have changed since version 5.1 :P
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.
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.
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.
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.
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
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.
it brings up an interesting point, though
i may set up masm 5.10 for writing 16-bit .com files :P
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.
Quote from: jj2007 on December 27, 2011, 05:37:52 PM
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
From what I compiled, this puts the data in the same position as the data that is declared "normally."
A file compare does show the programs have some differences.
true - it is in the same position in the resultant EXE file
however, the forward reference issue is strictly a source file problem
the assembler chokes because MS has simplified the first pass, compared to older MASM versions
It would seem to me that the point of this issue is because the DATA section makes the liistimg look ugly when dealing with programs that use a lot of data. The solution of using an INC file as mentioned above is a good one. Don't forget, though, that you can use the NOLISTING directive around the datat section also.
Paul
Isn't there an option to coagulate all the data sections in the assembler ?
:8)
you can combine sections
i believe PoLink does this by nature
or with Link, use the /MERGE option