News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Any way to simplify this loop?

Started by Astro, August 15, 2009, 12:46:19 PM

Previous topic - Next topic

Astro

mov ebx,0h
mov ecx,numdev
MEM_ALLOC:
mov ebx,[ebx]+64h
dec ecx
cmp ecx,0h
jnz MEM_ALLOC


* sigh *

Any way to simplify this? I tried:

mov ebx,64h
mov ebx,[ebx]*numdev ; error here

...but it complains "constant expected".

Best regards,
Astro.

redskull

Are those brackets in the wrong place?  I'm not sure I see what this does, or why you can't just use a MUL:

mov eax, 64
mul numdev, eax
mov ebx, eax

-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government

qWord

mov ebx,0h ;xor ebx,ebx
...
mov ebx,[ebx]+64h

you are accessing a DWORD located at 0+64h

Quote...but it complains "constant expected".
an Address can be specified through Scale, Index and Base (SIB)
Scale: multiply a register (32bit) by 1,2,4 or 8
Index: register (32bit)
Base: an offset

e.g.: mov eax,DWORD ptr [eax+ecx*4+1234]

EDIT: "dec ecx" sets the zero flag - there is no need for cmp (BTW: test reg,reg is better for such an task).

FPU in a trice: SmplMath
It's that simple!

Astro

mov eax,DWORD ptr [eax+ecx*4+1234]
Can you explain exactly how this gets executed please?

Quote"dec ecx" sets the zero flag - there is no need for cmp
OK!

Quote(BTW: test reg,reg is better for such an task).
According to the MASM docs, both take the same time to execute. What is the advantage of one vs. the other?

Quoteor why you can't just use a MUL:
haha - it seems to hate me and generates an error.

Best regards,
Astro.

Astro

Wow - it worked.

I used the mul option - two lines.

   mov eax,64h
   mul numdev


:U

Thanks!

Best regards,
Astro.

hutch--

 :bg


mov ebx,0h
mov ecx,numdev
MEM_ALLOC:
mov ebx,[ebx]+64h
dec ecx
cmp ecx,0h
jnz MEM_ALLOC


You don't need to do the compare as DEC and SUB ECX, 1 set the zero flag for the following JNZ.


@@:
  mov ebx, [ebx+64h]
  sub ecx, 1
  jnz @B
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

qWord

Quote from: Astro on August 15, 2009, 01:45:02 PM
mov eax,DWORD ptr [eax+ecx*4+1234]
Can you explain exactly how this gets executed please?
Don't know what do explain here - first the Addr. is calculated and then the memory is accessed.

Quote from: Astro on August 15, 2009, 01:45:02 PM
What is the advantage of one vs. the other?
Intel suggest to use it for such task :bg

EDIT: from Intel's Optimization Reference:
QuoteUse a TEST if a register with itself instead of a CMP of the register
to zero, this saves the need to encode the zero and saves encoding space

regards, qWord
FPU in a trice: SmplMath
It's that simple!

Astro

In what order is:

eax+ecx*4+1234
executed?

Does it follow BODMAS, or some other convention?

(4+1234) * ecx

is not the same as

(4*ecx) + 1234

QuoteIntel suggest to use it for such task  :bg
QuoteUse a TEST if a register with itself instead of a CMP of the register
to zero, this saves the need to encode the zero and saves encoding space
Thanks!

Best regards,
Astro.

dedndave

the mul is performed first
it is a shortcut, is all
"lea ecx,[ecx+4*ecx]" is a shortcut that multiplies ecx by 5
much faster than mul by 5

"test eax,eax" is also a shortcut
register to register instructions are faster and sometimes shorter than register to immediate
"or eax,eax" and "and eax,eax" do the same thing
which is fastest is a matter of some discussion - lol
out of habit, i use "or" - it was best back in the days of the 8088 - lol

it is good to learn which flags are examined for the different conditional jumps
it is also good to learn how the simplest instructions affect the flags
shifts and rotates are interesting, of course
arithmetic instructions affect the flags according to the operation
logic instructions are similar, except they always clear the carry flag (except "not", which alters no flags at all)
"not" (logic inst) and "neg" (arith inst) are special they do not always leave the flags as expected
suppose i had the following code...

        add     eax,dwordA
        adc     edx,dwordB

after the add instructions, edx is 0, but eax is non-zero - will the zero flag be set or cleared ?
http://www.arl.wustl.edu/~lockwood/class/cs306/books/artofasm/Chapter_6/CH06-1.html

Astro

Quotewill the zero flag be set or cleared ?
I shall take a look. I have a 50/50 chance of being right.  :bdg

Where do you find these links?  :dazzled:  I must be using the wrong search terms.

Best regards,
Astro.

MichaelW

Quote from: Astro on August 15, 2009, 01:45:02 PM
mov eax,DWORD ptr [eax+ecx*4+1234]
Can you explain exactly how this gets executed please?

The value in the [] brackets is an indirect memory operand that specifies the address of the data to operate on. The address is calculated at run time from the contents of one or two registers one of which can have a scale factor, and any number of displacements. In the example "4" is a scale factor, and "1234" is a displacement. The address is calculated using the standard order of operations, the same order that you would use in solving an algebraic equation.
eschew obfuscation

hutch--

The details of the "complex addressing mode" are worth the effort to learn as they give you the capacity to write very compact code for memory access. The conventions are as follows,

BASE ADDRESS which is a register.
INDEX which is a register
SCALE is required for the data size of the data being indexed. 1 2 4 8.
DISPLACEMENT additional address change with an immediate number.

There have been a few variations on the notation and MASM supports some of them but mainly the complete complex address is contained within a pair of square brackets.

The assembler can tolerate some order variation and will still parse the address correctly but it also allows an "append" type notation of one piar of square brackets followed by another pair of brackets. It acts like the add "+" operator.

What is important to understand is that the notation is a method of specifying a single opcode in the processor which is why you have "mnemonics" which are family names for similar capacities. Just for example the MOV mnemonic has multiple opcodes depending on the operant types and order, instead of having to remember all of them, you use a mnemonic with a well understood notation.

Its worth noting that there are mnemonics that vary from the above order, one mnemonic allows a displacement as the base address which can be very useful in certain contexts where you do not have to use a register. Its often used for array addresses.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Astro

A great post, Hutch!  :thumbu

Quote"lea ecx,[ecx+4*ecx]" is a shortcut that multiplies ecx by 5
much faster than mul by 5
:dazzled:  A few hours later and I'm no wiser.  :eek

QuoteThe address is calculated at run time from the contents of one or two registers one of which can have a scale factor, and any number of displacements. In the example "4" is a scale factor, and "1234" is a displacement. The address is calculated using the standard order of operations, the same order that you would use in solving an algebraic equation.
OK! It is rather obvious I know about 1% of what I need to.

Thanks for the replies - I need to do a lot of reading.  :eek

Best regards,
Astro.

NightWare


dedndave

QuoteThanks for the replies - I need to do a lot of reading.
when you first start out, you may find it handy to play with some little pieces of code in the debugger
that way, you can watch the registers and flags change as each instruction is executed
gawd - i spent hours with SymDeb - the old symbolic debugger - lol
besides, it's fun to watch all the lights go blinkin   :P