News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

How to redefine an area having only the pointer to the area?

Started by frktons, January 11, 2013, 02:20:15 AM

Previous topic - Next topic

frktons

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? 

There are only two days a year when you can't do anything: one is called yesterday, the other is called tomorrow, so today is the right day to love, believe, do and, above all, live.

Dalai Lama

dedndave

    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

frktons

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?
There are only two days a year when you can't do anything: one is called yesterday, the other is called tomorrow, so today is the right day to love, believe, do and, above all, live.

Dalai Lama

dedndave

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

MichaelW

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
Well Microsoft, here's another nice mess you've gotten us into.

frktons

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?
There are only two days a year when you can't do anything: one is called yesterday, the other is called tomorrow, so today is the right day to love, believe, do and, above all, live.

Dalai Lama

MichaelW

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

Well Microsoft, here's another nice mess you've gotten us into.

frktons

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


There are only two days a year when you can't do anything: one is called yesterday, the other is called tomorrow, so today is the right day to love, believe, do and, above all, live.

Dalai Lama

jj2007

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



frktons

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:
There are only two days a year when you can't do anything: one is called yesterday, the other is called tomorrow, so today is the right day to love, believe, do and, above all, live.

Dalai Lama

frktons

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?
There are only two days a year when you can't do anything: one is called yesterday, the other is called tomorrow, so today is the right day to love, believe, do and, above all, live.

Dalai Lama

dedndave

if you define the structure type as pre-initialized, don't try to define the structure label in .DATA?   :biggrin:

frktons

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:
There are only two days a year when you can't do anything: one is called yesterday, the other is called tomorrow, so today is the right day to love, believe, do and, above all, live.

Dalai Lama

dedndave

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:

frktons

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)
There are only two days a year when you can't do anything: one is called yesterday, the other is called tomorrow, so today is the right day to love, believe, do and, above all, live.

Dalai Lama