News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

"Hello masm32", not a BOT, new member

Started by LordAdef, January 22, 2017, 09:42:24 AM

Previous topic - Next topic

jj2007

Quote from: LordAdef on April 30, 2017, 10:17:59 AM
A quick help, please...

I need to iterate through an array of structures. [ebx*Bullet ] wont do it, but [2*Bullet] does. Pre compile thing? How do I do this?
xor ecx, ecx
@@:
mov edi, offset man.bullets[ecx*Bullet].active
.IF dword Ptr [edi] == 1
printf (" Bullet %d is active\n", dword Ptr [edi])
.ENDIF
inc ecx
cmp ecx, 100
jnz @B


Marinus is right, ecx gets trashed - MB Print Str$() preserves ecx, but printf() doesn't. Simple solution:

.IF dword Ptr [edi] == 1
push ecx
printf (" Bullet %d is active\n", dword Ptr [edi])
pop ecx
.ENDIF


Btw no need for edi - this should work, too (not tested):
.IF man.bullets[ecx*Bullet].active == 1
push ecx
printf (" Bullet 1 is active\n")  ; 1 is it's value, for sure, so a constant will do ;-)
pop ecx
.ENDIF


LordAdef

Thanks Marinus and JJ,

But ecx being trash is not the point. The point is my clause with a register is not building.

A test bed:
Quoteinclude \masm32\include\masm32rt.inc

        Bullet STRUCT
           active   dd      ?
          speed   dd        ?
          x      dd      ?
          y      dd      ?               
        Bullet ENDS

        Player STRUCT 4
               x          dd    ?
               y          dd    ?
              sprite   dd   ?
               frmx   dd   ?
               frmy   dd   ?
               bullets   Bullet   50 dup (<>)
               kState   dd   ?
        Player ENDS
       
.data
       man Player  <>
.code
start:
       mov   man.bullets[2*Bullet].active, TRUE
       mov    man.bullets[2*Bullet].speed, 100
       mov    man.bullets[2*Bullet].x, 100
       mov    man.bullets[2*Bullet].y, 100
       
       mov eax, 2
       ;mov   man.bullets[2*Bullet].active, FALSE      ; <== THIS WORKS
       mov   man.bullets[eax*Bullet].active, FALSE   ; <== THIS DOESN´T
        
       invoke ExitProcess, eax
end start

This is the problem:
Quote;mov   man.bullets[2*Bullet].active, FALSE      ; <== THIS WORKS
       mov   man.bullets[eax*Bullet].active, FALSE   ; <== THIS DOESN´T

Marinus, thanks for the align trick! Does this automatically align all items in the struct?

Siekmanski

Quote from: LordAdef on May 01, 2017, 08:07:39 AM
Marinus, thanks for the align trick! Does this automatically align all items in the struct?
No, only the struct is aligned, but you can use align xx wihtin a struct or place a dummy byte.

this should work,

mov esi,offset man.bullets
mov ecx,sizeof Bullet

mov eax,2 ; the bullet number
mul ecx
mov dword ptr [esi+eax].Bullet.active,FALSE


edit:

Or in this case because the Bullet struct is 16 bytes,

mov   esi,offset man.bullets
mov   eax,2   ; the bullet number
shl   eax,4
mov   dword ptr [esi+eax].Bullet.active,FALSE
Creative coders use backward thinking techniques as a strategy.

HSE

Inside brackets you only can multiply by 2,4,8,...
Equations in Assembly: SmplMath

LordAdef

Quote from: HSE on May 01, 2017, 08:52:06 AM
Inside brackets you only can multiply by 2,4,8,...


But this works fine:
mov   man.bullets[3*Bullet].active, TRUE         ; <== THIS WORKS

And eax in the test bed was == 2.



edit:
It works fine with a constant. Is this a pre-compiling thing?

Quote.const
   cINDEX      EQU   3 
...
         mov   man.bullets[cINDEX*Bullet].active, TRUE         ; <== THIS WORKS

Siekmanski

Maybe because its an invalid scale value ?
Creative coders use backward thinking techniques as a strategy.

LordAdef

Marinus,
QuoteNo, only the struct is aligned, but you can use align xx wihtin a struct or place a dummy byte.

this should work,

It sure works. However, I wished I could use that syntax, or at least understand why it´s not working

QuoteMaybe because its an invalid scale value ?

Sure, but in this case mov   man.bullets[3*Bullet].active, TRUE shouldn´t work either

Siekmanski

does this work ?

mov   eax,2   ; the bullet number
shl   eax,4
mov man.bullets[eax].active, FALSE   

what assembler do you use ?
Creative coders use backward thinking techniques as a strategy.

jj2007

Quote from: LordAdef on May 01, 2017, 08:54:59 AM
It works fine with a constant. Is this a pre-compiling thing?

Exactly:
At compile time, any constant is fine.
At runtime, HSE's remark is correct: 2, 4 or 8 are the allowed scaling values.

LordAdef

Quote from: Siekmanski on May 01, 2017, 09:12:46 AM
does this work ?

mov   eax,2   ; the bullet number
shl   eax,4
mov man.bullets[eax].active, FALSE   

what assembler do you use ?

That works too.
I´m on HJWasm, since I usually use RichMasm. I try and keep compatibility using qEditor (ML)

LordAdef

QuoteAt compile time, any constant is fine.
At runtime, HSE's remark is correct: 2, 4 or 8 are the allowed scaling values.

I was suspecting that, and the constant test showed it. So, in that syntax the compiler can´t know the value of the register and thus generates an error. Got it.

Thanks everyone, this was instructive.

jj2007

Quote from: LordAdef on May 01, 2017, 09:49:33 AMI´m on HJWasm, since I usually use RichMasm. I try and keep compatibility using qEditor (ML)

This is how I test different assemblers:
; OPT_Assembler ML  ; somewhere in the file forces RichMasm to use \Masm32\bin\ml.exe (or any other exe...)

OPT is case-sensitive, the rest isn't.
Just put an x after the O: OxPT_anyoption to disable an option. If there are several options of the same type, the last one is valid:
...
end start
OPT_Arg1  fileA.txt
OPT_Arg1  fileB.txt

CL$() will find fileB.txt

LordAdef

NICE ONE!!!!! RM/MB always have a away around things..

hutch--

Something that some folks miss, a "syntax error" with an instruction means that the processor does not have a matching opcode for something in source code that has been fed to it. This applies to the multiplier range of 2, 4 and 8, each of which has a matching opcode, try it with any other number and you are trying to call a non existent opcode. The assembler "should" catch this but they can be a bit sloppy and miss a simple error like this, an error type the is mainly a typo.