News:

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

mov vs. movzx

Started by Astro, April 26, 2010, 01:14:49 AM

Previous topic - Next topic

Astro

Hi,

Just want to check I understand this correctly:

mov doesn't always overwrite the upper part of a register?

If that is correct, is:

movzx ecx,eax

equivalent to:

xor ecx,ecx
mov ecx,eax


Best regards,
Robin.

joemc

I think you have the right idea, but mov ecx,eax is going to move ALL of eax into ecx so the xor isnt going to do much for you. movzx is good for when you want to move one object that is a different size into a larger one.

a better example would be

movzx ecx,  byte ptr 9

is equivalent to
xor ecx ecx
mov cl, 9

the main time is use it is for string pointers
to get one character from a string pointed to by eax
movzx ecx, byte ptr [eax]

Astro

 ::)

I keep forgetting that part - SIZE DIFFERENCE.

Thanks.

Best regards,
Robin.

hutch--

Robin,

movzx is useful for a couple of reasons, you can tweak the size of a smaller piece of data up to the size you want but it has the added advantage of clearing a partial register read which on some earlier Intel hardware gave you a bad stall.

Typically you have a situation of a BYTE of DATA at an address whewre you use MOVZX to copy it into a full 32 bit register so it can be used with full 32 bit comparisons.


movzx eax, WORD PTR [esp+22]


This gets a 16 bit WORD directly off the stack and writes it to EAX so you can test against it with full 32 bit instructions which is generally faster than using 16 bit compares.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Astro

Nice!! Thanks for the info. I was wondering if:

cmp al,1

was faster or the same as

cmp eax,1

You answered that one! :bg

Best regards,
Robin.

Slugsnack

Quote from: joemc on April 26, 2010, 01:39:40 AM
I think you have the right idea, but mov ecx,eax is going to move ALL of eax into ecx so the xor isnt going to do much for you. movzx is good for when you want to move one object that is a different size into a larger one.

a better example would be

movzx ecx,  byte ptr 9

is equivalent to
xor ecx ecx
mov cl, 9

the main time is use it is for string pointers
to get one character from a string pointed to by eax
movzx ecx, byte ptr [eax]
actually those 2 are not equivalent. byte ptr 9 is not the same as the value 9. byte ptr 9 is the byte that is pointed to by memory address 9. most likely that would cause an access violation since no memory is allocated there.

@ Astro : generally, you dealing with larger registers rather than partial registers is quicker. so cmp eax, 1 would be faster in this case

jj2007

Quote from: Astro on April 26, 2010, 01:14:49 AM
If that is correct, is:
movzx ecx,eax
equivalent to:

xor ecx,ecx
mov ecx,eax


Robin,
movzx eax, ecx will first of all generate error A2070:invalid instruction operands
What works is
movzx eax, ax
movsx eax, ax (sign extension)
movzx eax, cl
movsx eax, cl (sign extension)
movzx eax, word ptr [mem]
movsx eax, word ptr [mem]
movzx eax, byte ptr [mem]
movsx eax, byte ptr [mem]

Astro

Hi jj,

Yes - I already discovered that! :bg  Thanks for pointing it out though.

@joemc:
Quoteactually those 2 are not equivalent. byte ptr 9 is not the same as the value 9.
I've seen it written both ways, and appears to work identically?

e.g.
mov al, byte ptr 8
mov byte ptr al,8


O/T slightly: I've found a weird error I get in one app but not another.

SomeProc proc Buffer:DWORD

mov eax,Buffer
mov eax,[eax] ; this line fails build in one app but works in another????? Build options are the same except processor type.
; working processor is 386, failing processor is 486.


Best regards,
Robin.

Slugsnack

Astro : those instructions do very different things. the first treats al as a pointer and moves the byte value at memory address 8 into it. this would cause an access violation on most machines since that is below the minimum application address. the second is not even a valid instruction. you are telling the computer to move the value 8 into the byte pointed to by al. the machine can not treat al as a pointer however, since pointers are all 32 bits.. even if we were to do the following :
movzx eax, al
mov byte ptr ds:[eax], 8

that is very very different to the 'opposite' of the first instruction which i assume was your intention

MichaelW

For both of these statements:

mov al, byte ptr 8
mov byte ptr al, 8

MASM ignores the unnecessary BYTE PTR operators (unnecessary because the size can be determined from the destination operand) and assembles a MOV reg, immed:

MOV AL, 8

eschew obfuscation

Slugsnack

this is a subject that has been discussed in the past, how :
mov al, byte ptr 8

actually assembles to :
mov al, 8

personally i believe this can be regarded as a 'bug' on the part of the assembler. the first instruction is actually valid. despite the fact that in 90% of cases, the user intended the second instruction, i do not believe it should be just changed.

above is a clear example of where there has been confusion about this already. the equivalence joemc claims is actually true if that is what you input into masm32 since it is 'translated' like above. however if you assembled that code within ollydbg, the semantics becomes very different

Astro

So MASM behavior is:

mov al, byte ptr 8
to:
mov al, 8
which is actually INCORRECT?

Best regards,
Robin.

dedndave

MOV AL,8 is good enough
no need to use "byte ptr", as AL is a byte register, so the operand can only be a byte

brethren

Quote from: Astro on April 26, 2010, 01:14:49 AM
Hi,

Just want to check I understand this correctly:

mov doesn't always overwrite the upper part of a register?

If that is correct, is:

movzx ecx,eax

equivalent to:

xor ecx,ecx
mov ecx,eax


Best regards,
Robin.

movzx ecx, eax is not a valid instruction

the syntax for movzx (move with zero extend)

movzx r32, r/m16
movzx r32, r/m8
movzx r16, r/m8

i'm pretty sure you just made a typo and you meant movzx ecx, ax. if thats what you meant then you're right

xor ecx, ecx
mov cx, ax

would accomplish the same thing as

movzx ecx, ax

MichaelW

Quote from: Slugsnack on April 26, 2010, 10:37:55 AM
this is a subject that has been discussed in the past, how :
mov al, byte ptr 8

actually assembles to :
mov al, 8

personally i believe this can be regarded as a 'bug' on the part of the assembler. the first instruction is actually valid.

It is valid, but it is not interpreted as:

mov al, byte ptr [8]

Would be in, for example, Debug or CodeView.

Judging from multiple statements to this effect in the MASM documentation, the PTR operator is intended for specifying operand size. It is not intended for specifying direct memory operands.
eschew obfuscation