The MASM Forum

General => The Campus => Topic started by: frktons on January 11, 2013, 02:20:15 AM

Title: How to redefine an area having only the pointer to the area?
Post by: frktons on January 11, 2013, 02:20:15 AM
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? 

Title: Re: How to redefine an area having only the pointer to the area?
Post by: dedndave on January 11, 2013, 02:58:13 AM
    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
Title: Re: How to redefine an area having only the pointer to the area?
Post by: frktons on January 11, 2013, 03:06:56 AM
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?
Title: Re: How to redefine an area having only the pointer to the area?
Post by: dedndave on January 11, 2013, 03:12:14 AM
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
Title: Re: How to redefine an area having only the pointer to the area?
Post by: MichaelW on January 11, 2013, 03:19:33 AM
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
Title: Re: How to redefine an area having only the pointer to the area?
Post by: frktons on January 11, 2013, 03:33:14 AM
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?
Title: Re: How to redefine an area having only the pointer to the area?
Post by: MichaelW on January 11, 2013, 03:45:08 AM
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

Title: Re: How to redefine an area having only the pointer to the area?
Post by: frktons on January 11, 2013, 03:50:53 AM
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


Title: Re: How to redefine an area having only the pointer to the area?
Post by: 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


Title: Re: How to redefine an area having only the pointer to the area?
Post by: frktons on January 11, 2013, 03:54:31 AM
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:
Title: Re: How to redefine an area having only the pointer to the area?
Post by: frktons on January 11, 2013, 04:13:46 AM
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?
Title: Re: How to redefine an area having only the pointer to the area?
Post by: 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:
Title: Re: How to redefine an area having only the pointer to the area?
Post by: frktons on January 11, 2013, 04:35:20 AM
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:
Title: Re: How to redefine an area having only the pointer to the area?
Post by: 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:
Title: Re: How to redefine an area having only the pointer to the area?
Post by: frktons on January 11, 2013, 04:47:56 AM
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)
Title: Re: How to redefine an area having only the pointer to the area?
Post by: 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
Title: Re: How to redefine an area having only the pointer to the area?
Post by: frktons on January 11, 2013, 12:59:37 PM
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 PROC

If 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
.....

Title: Re: How to redefine an area having only the pointer to the area?
Post by: dedndave on January 11, 2013, 01:12:09 PM
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 $
Title: Re: How to redefine an area having only the pointer to the area?
Post by: MichaelW on January 11, 2013, 01:16:40 PM
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.
Title: Re: How to redefine an area having only the pointer to the area?
Post by: frktons on January 11, 2013, 01:27:03 PM
Thanks Dave and Michael.
I think I can go on until next doubt.  :P