Let's make a practical example:
Main PROC has a 16 bytes string defined as:
Area db 16 DUP(?)
and the area is passed via its address to another PROC:
Invoke SecProc, ADDR Area
SecPROC needs to redefine AREA as four dword in a structure:
align N16
Area16S STRUCT
Area1 dd
Area2 dd
Area3 dd
Area4 dd
Area16S ENDS
Area16 Area16S <> ; <-------- How I define this with the Address the PROC receives?
In other words I need to access the original Area defined in the main prog
with a different structure based on the address of the Area.
How to connect the new structure to the Area via the pointer?
align N16
Area16S STRUCT
Area1 dd
Area2 dd
Area3 dd
Area4 dd
Area16S ENDS
first, let's define this structure type properly
i don't know if the text you show is in a data section or not
it doesn't need to be in a section - you are defining a data type - not data
you cannot align a structure type definition with ALIGN
when you define the data label in the data section, then ALIGN will work
Area16S STRUCT [16]
Area1 dd
Area2 dd
Area3 dd
Area4 dd
Area16S ENDS
this aligns the members - not what you want :biggrin:
when you define the data...
ALIGN 16
MyArea Area16S <>
this aligns the structure
now - to that proc parameter...
when you pass a pointer to the structure, the proc has no idea what it is
it only sees an address as a long integer and passes it on the stack as such
inside the proc, you can use 1 of 2 popular methods to tell the assembler it is a structure reference
MyProc PROC lpStruct:LPVOID
mov edx,lpStruct
mov eax,[edx].Area16S.Area1
ret
MyProc ENDP
MyProc PROC lpStruct:LPVOID
ASSUME EDX:Ptr Area16S
mov edx,lpStruct
mov eax,[edx].Area1
ret
ASSUME EDX:Nothing
MyProc ENDP
Almost clear.
One more point to clear.
Is it the same if I define the type in the Main PROC
or in the called PROC? There is something that suggests to
do it in the first or latter way?
i typically define structure types and other data types at the beginning of the source file
also - define equates, macros, and prototypes at the beginning
usually, i put that stuff in an INC file
the data definition goes in .DATA or .DATA?
include \masm32\include\masm32rt.inc
Area16S STRUCT
Area1 dd
Area2 dd
Area3 dd
Area4 dd
Area16S ENDS
MyProc PROTO :LPVOID
.DATA?
ALIGN 16
MyArea Area16S <>
.CODE
Main PROC
INVOKE MyProc,offset MyArea
INVOKE ExitProcess,0
Main ENDP
MyProc PROC lpStruct:LPVOID
ret
MyProc ENDP
END Main
It apparently does not matter where you declare the structure. And the data definition can also be on the stack.
;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================
.data
.code
;==============================================================================
SecProc proc address:DWORD
comment |
Area16S STRUCT
Area1 dd ?
Area2 dd ?
Area3 dd ?
Area4 dd ?
Area16S ENDS
|
mov edx, address
mov [edx].Area16S.Area1, 1
mov [edx].Area16S.Area2, 2
ASSUME edx:PTR Area16S
mov [edx].Area3, 3
mov [edx].Area4, 4
ASSUME edx:NOTHING
ret
SecProc endp
;==============================================================================
Main proc
LOCAL Area[16]:BYTE
invoke SecProc, ADDR Area
lea ebx, Area
printf("%X\t", DWORD PTR [ebx])
printf("%X\t", DWORD PTR [ebx+4])
printf("%X\t", DWORD PTR [ebx+8])
printf("%X\n\n", DWORD PTR [ebx+12])
ret
comment |
Area16S STRUCT
Area1 dd ?
Area2 dd ?
Area3 dd ?
Area4 dd ?
Area16S ENDS
|
Main endp
Area16S STRUCT
Area1 dd ?
Area2 dd ?
Area3 dd ?
Area4 dd ?
Area16S ENDS
;==============================================================================
start:
;==============================================================================
call Main
inkey
exit
;==============================================================================
end start
Thanks, good hints.
What about a preinizialized STRUCT? Does it work?
.data
Area16S STRUCT
Area1 dd 20202020H
Area2 dd 20202020H
Area3 dd 20202020H
Area4 dd 20202020H
Area16S ENDS
align 16
Area Area16S ,0 ; <-------------- Is this area filled with spaces and has a zero string terminator?
The location of the structure declaration apparently does matter if the data definition is in the data segment.
;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================
Area16S STRUCT
Area1 dd ?
Area2 dd ?
Area3 dd ?
Area4 dd ?
Area16S ENDS
;==============================================================================
.data
Area_ Area16S <20202020h,20202020h,20202020h,20202020h>
db 0
.code
;==============================================================================
SecProc proc address:DWORD
mov edx, address
mov [edx].Area16S.Area1, 1
mov [edx].Area16S.Area2, 2
ASSUME edx:PTR Area16S
mov [edx].Area3, 3
mov [edx].Area4, 4
ASSUME edx:NOTHING
ret
SecProc endp
;==============================================================================
Main proc
LOCAL Area[16]:BYTE
invoke SecProc, ADDR Area
lea ebx, Area
printf("%X\t", DWORD PTR [ebx])
printf("%X\t", DWORD PTR [ebx+4])
printf("%X\t", DWORD PTR [ebx+8])
printf("%X\n\n", DWORD PTR [ebx+12])
printf("|%s|\n\n", ADDR Area_)
ret
Main endp
;==============================================================================
start:
;==============================================================================
call Main
inkey
exit
;==============================================================================
end start
As strange as it can look, this prog works:
;--------------------------------------------------------------
; Test_Redefined_Area.asm
; -------------------------------------------------------------
; Test to verify that a redefined area works as expected.
; frktons 10-Jan-2013 @Masm32 Forum
;--------------------------------------------------------------
include \masm32\include\masm32rt.inc
.686
.xmm
FillArea PROTO Dest:DWORD, Src:DWORD
.data
Area16S STRUCT
Area1 dd 30303030H
Area2 dd 30303030H
Area3 dd 30303030H
Area4 dd 30303030H
AreaZT db 00H
Area16S ENDS
align 16
Area Area16S <>
align 4
PtrArea dd Area.Area1
align 4
MsgA db "Ciao"
.code
start:
print "Original Content of Area is "
print PtrArea, 13, 10, 13, 10
Invoke FillArea, PtrArea, ADDR MsgA
print "Content of Area is now "
print PtrArea, 13, 10, 13, 10
inkey
jmp end_of_task
;-----------------------------------------------------------------------
; Fills a 16 bytes area with four dword content
;-----------------------------------------------------------------------
FillArea PROC PtrDest:DWORD, PtrSrc:DWORD
mov edi, PtrDest
mov esi, PtrSrc
mov eax, [esi]
mov Area.Area1, eax
mov Area.Area2, eax
mov Area.Area3, eax
mov Area.Area4, eax
ret
FillArea ENDP
end_of_task:
exit
end start
Quote from: frktons on January 11, 2013, 03:33:14 AM
What about a preinizialized STRUCT? Does it work?
Yes.
include \masm32\include\masm32rt.inc
Area16S STRUCT
Area1 dd 123
Area2 dd 456
Area3 dd 789
Area4 dd 012
Area16S ENDS
.data
MyArea Area16S <>
.code
start: inkey str$(MyArea.Area2), 13, 10
exit
end start
Quote from: jj2007 on January 11, 2013, 03:51:34 AM
Quote from: frktons on January 11, 2013, 03:33:14 AM
What about a preinizialized STRUCT? Does it work?
Yes.
include \masm32\include\masm32rt.inc
Area16S STRUCT
Area1 dd 123
Area2 dd 456
Area3 dd 789
Area4 dd 012
Area16S ENDS
.data
MyArea Area16S <>
.code
start: inkey str$(MyArea.Area2), 13, 10
exit
end start
Very well Jochen, I just posted the same conclusion one second before yours. :biggrin:
Your solution gives some more interesting hints to meditate, by the way. :eusa_clap:
It is very interesting to note that you can define a STRUCT
wherever you like, and also preinitialize it, even if it is
outside of the .data segment.
Very flexible and can solve many data structure problems as well.
Something a little bit obscure is the mixed use of STRUCT and
defined data that MichaelW does in its last example:
printf("|%s|\n\n", ADDR Area_)
Considering you have never addressed Area_ in your code
and it is initialized to spaces, what did you expect the prog
should display with the previous line of code?
if you define the structure type as pre-initialized, don't try to define the structure label in .DATA? :biggrin:
Quote from: dedndave on January 11, 2013, 04:16:30 AM
if you define the structure type as pre-initialized, don't try to define the structure label in .DATA? :biggrin:
Well, probably that is the only case in which MASM'd complain. :P
By the way we have moved aside from the first question, but I think there is
enough stuff to meditate upon, and the answer is inside me, but unfortunately it is
uncorrect. :lol:
structures are really only difficult when you nest structures inside structures inside structures with unions,
then try to initialize them when you define the data label :lol:
Quote from: dedndave on January 11, 2013, 04:37:19 AM
structures are really only difficult when you nest structures inside structures inside structures with unions,
then try to initialize them when you define the data label :lol:
Oh-Oh. NOOOOOOO. :dazzled: That scares me a lot. Better to use simple structures and simple unions.
I've used Unions only once in Assembly, but in PL1 I liked them very much.
They were called
redefinitions and had the capacity to build a struct
based on a variable, or to redefine an area, or part of it, with a different struct.
I've to study ASM UNIONS one of these days. 8)
if it's my own structure, i find a different way to do it - lol
if it's defined by MS, i have to work with it :P
Quote from: dedndave on January 11, 2013, 05:06:52 AM
if it's my own structure, i find a different way to do it - lol
if it's defined by MS, i have to work with it :P
In this case you have to. :t
One more question about data and PROCIf I have 3 equates on main prog, and I call an external PROC
in a LIB, that uses these equates, how should I define them
in order to make them visible and usable by both main and proc?
One EQU 1
Maxrow EQU 32
MaxCol EQU 128
....
CALL AnyProc
AnyProc PROC
?????
mov eax, Zero
mov ebx, MaxRow
mov ecx, MaxCol
.....
equates don't have "visibility" like data, per se
you can define the same equates in the program source, and in the source for the module
it's nice if they are the same value :P
another way to go is to put the common equates in an INC file
then, include that INC file in both sources
remember, at assembly time, equates are resolved as simple numeric constants
you might have a hard time with referencing a symbol like this from 2 different files
END_DATA EQU $
Quote from: frktons on January 11, 2013, 04:13:46 AM
Something a little bit obscure is the mixed use of STRUCT and
defined data that MichaelW does in its last example:
printf("|%s|\n\n", ADDR Area_)
Considering you have never addressed Area_ in your code
and it is initialized to spaces, what did you expect the prog
should display with the previous line of code?
It displays the initialized structure as an ANSI string, which I thought was what you were after. I added the vertical bar characters before and after the string so you could see where it started and ended.
Thanks Dave and Michael.
I think I can go on until next doubt. :P