Hi,
What is the difference between nested structures and unions?
Best regards,
Robin.
Structures reserve seperate storage space for every element; Unions store all the fields in the same memory, and only address is differently. A good conceptual view of a union is the register set; you can address the same 'space' as eax, ax, ah, or al.
-r
If you look at a structure noting the offsets it explains things nicely:
SOMESTRUCT STRUCT
mem1 dd ? ; offset 0
mem2 dd ? ; offset 4
SUBSTRUCT STRUCT
mem3 dd ? ; offset 8
mem4 dd ? ; offset 12
SUBSTRUCT ENDS
mem5 dd ? ; offset 16
SOMEUNION UNION
mem6 dd ? ; offset 20
mem7 dq ? ; offset 20 << largest member of union
mem8 db ? ; offset 20
SOMEUNION ENDS
mem9 dd ? ; offset 28
SOMESTRUCT ENDS
Note that in the substruct the offset from the beginning of the structure is incremented with each of its members however in the union all members are at the same offset. Also note that the size of the union is the size of its largest member, not the sum of all of its members.
Edgar
I would consider UNION somewhat equivalent to using LABEL.
Edit: Dave - Changed my text after a bit more study of the UNION components while you were posting your reply. :red :eek
looks right to me :P
SOMEUNION is at offset 20
it's largest member is a qword
so, the next element will be at 28
A union is a very useful method to have available as it can take different data sizes in the same argument location. If you want to be able to pass a byte, word, dword, real4/8/10 you create a union that has all of the elements in it then you can select which member you pass. It works by allocating the size of the largets member then writing which ever size data you nominate to that address when you use the union. For example, if the largest member is 80 bytes (real10) you can write any other data size to that address that is the same size or smaller.
Well, UNIONs are great for C language and other languages that use defined types, I include them in the header files but in GoAsm where you need to type cast all memory operands they are a bit redundant. You can just as easily create one member of the largest size and type cast with xxxx PTR or your assemblers equivalent. They are generally self documenting though which is why I like them and always use them.
BTW REAL10 is 80 bits not 80 bytes.
:bg
Yes you are right, we will not have 80 BYTE reals until SSE17 or later on WinUNIVERSE version 12.
Quote from: hutch-- on January 20, 2010, 04:56:30 AM
:bg
Yes you are right, we will not have 80 BYTE reals until SSE17 or later on WinUNIVERSE version 12.
:bg
mov ZXMM3,0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFh
(Used an integer because i couldn't wrap my head around an 80 byte real)
:lol Did you count those 160 F's as you typed them?
mov ZXMM3,-1
Quote from: sinsi on January 20, 2010, 05:58:20 AM
:lol Did you count those 160 F's as you typed them?
The great thing about copy and paste is I didn't have to :)
Quotemov ZXMM3,-1
More dramatic my way...
Quotedonkey
Member
*****
Posts: 2020
Hey I finally have hindsight :P
a Donkey with hindsight ???? - don't make me go there, Edgar - lol
Another way of defining a union in Masm...
include \masm32\include\masm32rt.inc
.code
start:
push chr$("The Union is the Force!")
call MyTest
exit
MyTest proc arg1:DWORD
LOCAL txrg:TEXTRANGE
chars equ <txrg.chrg> ; let's define a union ;-)
mrm txrg.lpstrText, arg1
mov chars.cpMin, 123
mov chars.cpMax, 456
MsgBox 0, str$(txrg.chrg.cpMax), txrg.lpstrText, MB_OK
ret
MyTest endp
end start
JJ,
Unless I have read it wrong, your example is just a nested structure. A CHARRANGE nested in a TEXTRANGE structure. Try this.
IF 0 ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
Build this template with "CONSOLE ASSEMBLE AND LINK"
ENDIF ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \masm32\include\masm32rt.inc
MULTI UNION
itm1 dd ?
itm2 dw ?
itm3 db ?
MULTI ENDS
funnyproc PROTO :DWORD,:MULTI
.code
start:
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
call main
inkey
exit
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
main proc
LOCAL mlt :MULTI
push ebx
mov ebx, 16
mov mlt.itm1, ebx
invoke funnyproc,1,mlt
mov mlt.itm2, bx
invoke funnyproc,2,mlt
mov mlt.itm3, bl
invoke funnyproc,3,mlt
pop ebx
ret
main endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
funnyproc proc typ:DWORD,pUnion:MULTI
.if typ == 1
mov eax, pUnion.itm1
print str$(eax)," Its a DWORD",13,10
.elseif typ == 2
mov ax, pUnion.itm2
movzx eax, ax
print str$(eax)," Its a WORD",13,10
.elseif typ == 3
mov al, pUnion.itm3
movzx eax, al
print str$(eax)," Its a BYTE",13,10
.endif
ret
funnyproc endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end start
Quote from: hutch-- on January 20, 2010, 02:05:04 PM
Unless I have read it wrong, your example is just a nested structure. A CHARRANGE nested in a TEXTRANGE structure.
Hutch,
TEXTRANGE has by default a nested CHARRANGE. I was just showing that you can simulate the behaviour of a union with a simple equate.
Quote mov chars.cpMax, 456
MsgBox 0, str$(txrg.chrg.cpMax), txrg.lpstrText, MB_OK
Your example is more serious, of course :bg
:bg
Damn, somebody has taken me seriously at last. :P
Quote from: hutch-- on January 20, 2010, 09:51:50 PM
:bg
Damn, somebody has taken me seriously at last. :P
He must have been drunk...
drunk AND using his hindsight :P
we always take you seriously, Hutch - you have the hammer :bg
Hi,
Thanks!!
I presume then you can only use it to store one item at a time in the Union?
Best regards,
Robin.
Robin,
Yes, a union that has for example 3 data sizes in it with the largest being 4 bytes will hold 1, 2 or 4 bytes of data in the 4 bytes available. They are very useful for unusual function that need different data sizes passed to them but they are regularly used nested inside conventional structures whe4re a member needs to be able to handle different data sizes or types.
Just for example you could make a union that held either. 64 bytes of string data or a 10 byte REAL10 FP value.
Great! Thanks!
Best regards,
Robin.