News:

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

lea eax, dword ptr [0] aka lea eax, [small 0]

Started by jj2007, March 12, 2011, 11:46:29 AM

Previous topic - Next topic

jj2007

I wanted to find a clever way to zero eax without changing flags and tried lea eax, dword ptr
  • [/b]
    The trick works but is 5 bytes long (67:8D06 0000), and according to Olly it's called lea eax, [small 0]
    :bg

clive

Microsoft (R) Macro Assembler Version 6.15.8803     03/12/11 06:44:16
test83.asm      Page 1 - 1


        .386
        .MODEL FLAT
00000000         .CODE


00000000  B8 00000000         mov     eax,0

00000005  6A 00         push    0
00000007  58         pop     eax

00000008  67& 8D 06 0000         lea     eax,byte ptr [0]

        END
It could be a random act of randomness. Those happen a lot as well.

donkey

Quote from: jj2007 on March 12, 2011, 11:46:29 AM
I wanted to find a clever way to zero eax without changing flags and tried lea eax, dword ptr
  • [/b]
    The trick works but is 5 bytes long (67:8D06 0000), and according to Olly it's called lea eax, [small 0]
    :bg

:bg

4 bytes:

pushfd
xor eax,eax
popfd
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

jj2007

m2m eax, 0 is three bytes (Clive), the pushfd trick is a good one for delaying a loop that is too fast, but well, I made it in two bytes in the end. There is always some xor reg32, reg32 around, so push reg32/pop eax does the job in two bytes ;-)

Anyway, the [small 0] in Olly got my attention. Googling didn't yield any results, so I wonder if Olly invented this one. Especially since ML.exe says lea eax, dword ptr [small 0] deserves error A2206:missing operator in expression ::)

clive

Quote from: jj2007 on March 12, 2011, 02:39:09 PM
Anyway, the [small 0] in Olly got my attention. Googling didn't yield any results, so I wonder if Olly invented this one. Especially since ML.exe says lea eax, dword ptr [small 0] deserves error A2206:missing operator in expression ::)

Can't say I've heard of the address override being referred to as small. Though short/small/near do make sense as a way to infer alternate encoding strategies. The 68K has the .L and .W directives for overriding the assembler's default/optimal encodings.
It could be a random act of randomness. Those happen a lot as well.

jj2007

Some more observations:

lea eax, fs:[0] ; 8D05 00000000    lea eax, [0]
lea eax, dword ptr [0] ; 67:8D06 0000       lea eax, [small 0]
lea eax, word ptr [0] ; 67:8D06 0000       lea eax, [small 0]
lea eax, byte ptr [0] ; 67:8D06 0000       lea eax, [small 0]

The last three are all encoded as 67& 8D 06 0000, in ml 6.14, 6.15 and 9.0
In contrast, JWasm doesn't like it: 3*Error A2049: Invalid instruction operands

BogdanOntanu

Avoid using the old 16 bits style address modes in 32 bits (ie avoid using the 0x67 prefix)...   because it is slow and the 16 bits addressing mode (aka ModRM) is less flexible than the 32 bits one.

Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

hutch--

 :bg

JJ,

I know this may be senile decay, not reading the topic until after lunch time etc but if zeroing EAX without changing the flags is the task, what is wrong wioth MOV EAX, 0  ?
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

dedndave

push 0 / pop eax is the smallest way i can think of
it may be a little faster if you put some other instruction between them   :P

jj2007

Quote from: hutch-- on March 13, 2011, 01:03:37 AMif zeroing EAX without changing the flags is the task, what is wrong wioth MOV EAX, 0  ?
Hutch, in spite of the prominent role of The Colosseum, this is still basically an assembler forum, so #define WIN32_LEAN_AND_MEAN :bdg

Quote from: dedndave on March 13, 2011, 02:12:44 AM
push 0 / pop eax is the smallest way i can think of

Dave, as I wrote earlier, if you search long enough before the line where you need the zeroed eax, there is always an xor edx, edx hanging around, so push edx/pop eax does the job in two bytes. Maybe in the innermostest of all loops you could use mov eax, 0, but for normal use push/pop is simply the best solution :bg

clive

Quote from: jj2007 on March 13, 2011, 08:13:56 AMthere is always an xor edx, edx hanging around, so push edx/pop eax does the job in two bytes. Maybe in the innermostest of all loops you could use mov eax, 0, but for normal use push/pop is simply the best solution :bg
Personally,I'd use just the two  byte MOV EAX,EDX, and not bother with a trip to the stack.
It could be a random act of randomness. Those happen a lot as well.

hutch--

 :bg

#define WIN32_LEAN_AND_MEAN

If that means 2 instruction fetches instead of one with MOV EAX, 1, I will stick to the bloat. Those 3 bytes will explode your hard disk.  :P
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

jj2007

Quote from: clive on March 13, 2011, 12:08:15 PM
Quote from: jj2007 on March 13, 2011, 08:13:56 AMthere is always an xor edx, edx hanging around, so push edx/pop eax does the job in two bytes. Maybe in the innermostest of all loops you could use mov eax, 0, but for normal use push/pop is simply the best solution :bg
Personally,I'd use just the two  byte MOV EAX,EDX, and not bother with a trip to the stack.

The xor edx, edx happens several lines earlier:

xor edx, edx
push edx  ; we need a zero...
.repeat
   ...
   .Break .if Sign?
   ...
   inc edx
.Until edx>=123
pop eax   ; ... here
.if Sign?
    ... do stuff, ret non-zero eax
;   implicit else:
;   ret zero in eax
.endif

dedndave

i doubt that the fetch is a big issue - you either have to fetch 5 bytes, or you have to fetch 3 - lol
i can see where it makes a difference if it occurs several times - it is just more efficient to find a brief method
if it is going to be used repeatedly, put a 0 in EBX, EBP, ESI, or EDI and leave it there throughout the routine
in a program i am working on, i do this in the "main" routine, in the "wmCreate" routine, and throughout most of the "init" routine
it doesn't just apply to 0 - it applies to any value that is going to be used over and over
whether speed or size are critical or not - it does not hurt to use an efficient method
we write in assembler, in part, because we get to control such things

hutch--

Dave,

That is fine on an 8088 but the world has changed since 1980, pipelines, instruction queues and scheduling left that stuff behind long long ago. Instructions go through a pipeline AS instructions, not sequential bytes so the instruction count id a lot more important than the byte length.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php