The MASM Forum

General => The Workshop => Topic started by: LordAdef on April 14, 2020, 09:26:08 AM

Title: I'm back, my friends!
Post by: LordAdef on April 14, 2020, 09:26:08 AM
I'm back and wished to say hello first.

I'm very fond of the people here. I hope everyone is safe and sound during these sad days.

Since I'm still a noob after all this time, here goes a question (that justifies it being in the Campus):
What's the best way to dynamically set the assume edi: ptr STRUCT?  I've got an array of pointers. I call a function the needs to assume, but there are different types of structures in the pointers :
ui_addPanel proc uses edi esi parent:DWORD, me:DWORD, \
                        tLeft:DWORD, tTop:DWORD, tRight:DWORD, tBottom:DWORD
    assume edi:ptr UI
    assume esi:ptr Panel           ; <=====  there can be many possible Structures, other than Panel
    mov edi, parent
    mov esi, me

    mov myLeds[2 * sizeof Led].val, 10         
    inv ui_getNextAvailableInArray, edi

    mov [edi].child[eax*4], esi        ; add the component ptr to parent array
    mcm [esi].parent, [edi].hdc        ; save the parent dc

    mam [esi].rect.left,     tLeft
    mbm [esi].rect.top,        tTop
    mcm [esi].rect.right,     tRight
    mdm [esi].rect.bottom,     tBottom

    inv ui_createComponetHdc, edi, esi, NULL

    assume edi:nothing
    assume esi:nothing
    ret
ui_addPanel endp




Title: Re: I'm back, my friends!
Post by: jj2007 on April 14, 2020, 02:14:43 PM
Hi Alex,
Nice to see you :thup:

What exactly do you want to achieve? IMHO assume is confusing, equates are simpler and easier to read:
    mov ecx, me ; me is a pointer to a RECT
    rcme equ <[ecx.RECT]> ; for readability
    mov eax, rcme.right
    mov rcme.left, eax
Title: Re: I'm back, my friends!
Post by: aw27 on April 14, 2020, 02:24:24 PM
You don't need to use ASSUME, there are 2 better ways.


include \masm32\include\masm32rt.inc

.data
myRect RECT <11,120,220,190>

.code

main proc
mov esi, offset myRect
mov eax, (RECT PTR [esi]).right ; method 1
sub eax, dword ptr [esi].RECT.left ; method 2

printf( "Width is %d", eax) ; expected result is 220-11=209

invoke ExitProcess, 0
main endp

end


Title: Re: I'm back, my friends!
Post by: Siekmanski on April 14, 2020, 08:31:25 PM
Hi Alex,

Welcome back.  :thumbsup:
Title: Re: I'm back, my friends!
Post by: mineiro on April 14, 2020, 09:15:52 PM
Bem-vindo Alexandre;
Espero que esteja bem, saúde, harmonia e serenidade.
Abraços.
Title: Re: I'm back, my friends!
Post by: hutch-- on April 14, 2020, 10:48:38 PM
Good to see you back again Alex, now we can expect to see some rocket code.  :thumbsup:
Title: Re: I'm back, my friends!
Post by: daydreamer on April 15, 2020, 01:12:49 AM
Welcome back Alex, so we can expect a 200% assembly game soon :thumbsup:
Title: Re: I'm back, my friends!
Post by: HSE on April 15, 2020, 01:24:56 AM
Hi Alex!

You can do that if you developed that structures.

You have to store in a fixed position what kind of structure is. Easy if you can use the first d/qword in the structure:
t1 struct
   tipo dd 1
   ...
t1 ends
t2 struct
   tipo dd 2
  ...
t2 ends


if esi is a pointer to an structure:.if [esi] ==1
   assume esi:ptr t1
    ...
   here code using t1
    ...
.elseif [esi] == 2
   assume esi:ptr t2
    ...
   here code using t2
    ...
.endif
assume esi:nothing

Title: Re: I'm back, my friends!
Post by: LordAdef on April 18, 2020, 04:07:07 PM
Thanks everyone for the warm greetings!
JJ and Jose, in your examples you do know the struct is a RECT. That's the point. HSE understood what I meant. HSE, I've done this sort of code before, checking the struct type. 

I just thought there should be a clever (meaning you guys) way to do it, without doing cmps. Maybe, I should rethink the code architecture in order to circumvent the limitation. There is a reason for that, by the way.
Quote
Good to see you back again Alex, now we can expect to see some rocket code.

Hi Hutch, well I will try anyway  :rolleyes:
QuoteWelcome back Alex, so we can expect a 200% assembly game soon
Hi Daydreamer, yes I am back to coding the game!
Title: Re: I'm back, my friends!
Post by: LordAdef on April 18, 2020, 04:56:10 PM
Hi, me again...

I was thinking about the "assume" thing.... I believe I found a way. It looks ugly but it works! I've done it assuming the ptr STRUCT  (in EBX) "before" invoking :
Caller:
ui_addPanel proc uses edi esi parent:DWORD, me:DWORD, \
                        tLeft:DWORD, tTop:DWORD, tRight:DWORD, tBottom:DWORD
    assume edi:ptr UI
    assume esi:ptr Panel
    mov edi, parent
    mov esi, me
   ; =========================
   ; HERE IS THE CODE :
    mov ebx, 111      ; this just a controller
    con "ebx BEFORE = %d", ebx

    assume ebx: ptr Panel      ; here I assume the struct type, before calling
    inv ui_testStruct, me
   ; => assume ebx:nothing   doesn't work if placed here!
    con "ebx AFTER = %d", ebx   ; ebx is ok
   ; ==================================================


in the called procedure, you don't even need to assume nothing, afaik

ui_testStruct proc uses ebx, me:DWORD
    mov ebx, me
    con "ebx within proc is  %d", [ebx].val
    ;assume ebx: nothing
    ret
ui_testStruct endp

Any thoughts?
Title: Re: I'm back, my friends!
Post by: jj2007 on April 18, 2020, 10:24:23 PM
Ok, now I got it, I had misunderstood your problem. Here is one way to do it:
include \masm32\include\masm32rt.inc

.data
MyRect RECT <12, 34, 56, 78>
MyPoint POINT <123, 456>
MySmallRect SMALL_RECT <11, 22, 33, 44>

.code
mytest proc uses esi edi pWhatever, StructType
  mov eax, StructType
  mov esi, pWhatever
  dec eax
  .If Sign?
print "it's a rect, and right="
print str$([esi.RECT.right]), 13, 10
  .else
dec eax
.If Sign?
print "it's a point, and x="
print str$([esi.POINT.x]), 13, 10
.else
dec eax
.If Sign?
print "it's a smallrect, and right="
print str$([esi.SMALL_RECT.Right]), 13, 10
.endif
.endif
  .endif

  ret
mytest endp

start:
  cls
  invoke mytest, addr MyRect, 0
  invoke mytest, addr MyPoint, 1
  invoke mytest, addr MySmallRect, 2
  exit

end start


Personally, I would prefer this one, for better readability:
include \masm32\include\masm32rt.inc

.data
MyRect RECT <12, 34, 56, 78>
MyPoint POINT <123, 456>
MySmallRect SMALL_RECT <11, 22, 33, 44>

.code
rc equ <[esi.RECT]>
pt equ <[esi.POINT]>
src equ <[esi.SMALL_RECT]>

mytest proc uses esi edi pWhatever, StructType
  mov eax, StructType
  mov esi, pWhatever
  dec eax
  .If Sign?
print "it's a rect, and right="
print str$(rc.right), 13, 10
  .else
dec eax
.If Sign?
print "it's a point, and x="
print str$(pt.x), 13, 10
.else
dec eax
.If Sign?
print "it's a smallrect, and right="
print str$(src.Right), 13, 10
.endif
.endif
  .endif

  ret
mytest endp

start:
  cls
  invoke mytest, addr MyRect, 0
  invoke mytest, addr MyPoint, 1
  invoke mytest, addr MySmallRect, 2
  exit

end start


Just for fun, one more - the smallest exe:
include \masm32\include\masm32rt.inc

.data
dd 0
MyRect RECT <12, 34, 56, 78>
dd 1
MyPoint POINT <123, 456>
dd 2
MySmallRect SMALL_RECT <11, 22, 33, 44>

.code
rc equ <[esi.RECT]>
pt equ <[esi.POINT]>
src equ <[esi.SMALL_RECT]>

mytest proc uses esi edi pWhatever
  mov esi, pWhatever
  lodsd
  dec eax
  .If Sign?
print "it's a rect, and right="
print str$(rc.right), 13, 10
  .else
dec eax
.If Sign?
print "it's a point, and x="
print str$(pt.x), 13, 10
.else
dec eax
.If Sign?
print "it's a smallrect, and right="
print str$(src.Right), 13, 10
.endif
.endif
  .endif
  ret
mytest endp

start:
  cls
  invoke mytest, addr MyRect-4
  invoke mytest, addr MyPoint-4
  invoke mytest, addr MySmallRect-4
  exit

end start


Attention with the last one, you need a good assembler (UAsm, AsmC, JWasm) for it. MASM has a bug:
print str$(src.Right), 13, 10
translates to
push offset 004030A9
push 0                         ; ÚArg2 = 0
push word ptr [esi+4]          ; ³Arg1
call dwtoa                     ; ÀNewMasm32.dwtoa


UAsm translates it correctly to
push offset 004030A9           ; ÚArg2 = NewMasm32.4030A9
movzx eax, word ptr [esi+4]    ; ³
push eax                       ; ³Arg1
call dwtoa                     ; ÀNewMasm32.dwtoa
Title: Re: I'm back, my friends!
Post by: HSE on April 18, 2020, 11:47:53 PM
Hi Aex!

This code:    assume ebx: ptr Panel      ; here I assume the struct type, before calling
    inv ui_testStruct, me
   ; => assume ebx:nothing   doesn't work if placed here!
    con "ebx AFTER = %d", ebx   ; ebx is ok

Is equal to:
    inv ui_testStruct, me
   assume ebx: ptr Panel     
   con "ebx AFTER = %d", ebx   ; ebx is ok


assume is an instruccion for the assembler at assembling time, and is sequential. The procedure ui_testStruct is in another place, and t's not affected in any way by assume.
Title: Re: I'm back, my friends!
Post by: deeR44 on November 02, 2020, 06:03:29 PM
QuoteI'm back, my friends!

Finally! I've been waiting and waiting and waiting. I'm so glad! Wow!
Title: Re: I'm back, my friends!
Post by: TouEnMasm on November 02, 2020, 07:08:52 PM

If you don't want to use assume,you can also use TEXTEQU

adrect TEXTEQU <[R10].RECT>
.code
lea r10,rect
mov R11D,adrect.left