News:

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

Zero Extending

Started by Bieb, February 03, 2005, 08:50:19 PM

Previous topic - Next topic

Bieb

Will the following code work to zero extend a byte to a DWORD?

Xor Eax, Eax
Mov Al, Byte

That should get the same value, but in a DWORD, right?

00100b

MOVZX will zero-extend

MOVZX EAX, SomeByte


UncannyDude

You are right, Bieb. 00100b just showed another way(and most common one) to do it.

Ratch

Bieb,
     No, XOR EAX,EAX will zero out thte whole word including AL,  MOVZX EAX,XL is the way to go.  Ratch

UncannyDude

Quote from: Ratch on February 03, 2005, 11:01:22 PM
Bieb,
     No, XOR EAX,EAX will zero out thte whole word including AL,  MOVZX EAX,XL is the way to go.  Ratch
...if you are extending from (part of) the same register. Otherwise, XOR/MOV will do too.

BigDaddy

Ratch, he zeroed out eax, THEN moved Byte into al.  That would work, wouldn't it?

Titan

What exactly does this do, and what would you use it for? :red

UncannyDude

@Titan: Any time you need a 32bit-wide value.

Instead of:
mov edx, dword[ebx+al*4]
Use:
movzx eax, al
mov edx, dword[ebx+eax*4]

Instead of:
mov dword[ebx], cl
Use:
and ecx, $ff ; exactly as movzx ecx, cl
mov dword[ebx], ecx


To complement, movzx is for unsigned numbers, and movsx is for signed numbers.

mov al, -5
movzx ecx, al; ecx <- 0xfb = 251
movsx edx, al; edx <- 0xfffffffb = -5

Ratch

 BigDaddy, UncannyDude,
     Yes, you are right.  Sorry.  Ratch

00100b

Isn't something like the following another method of moving a smaller value into a larger destination?

MOV EAX, DWORD PTR SomeByte


UncannyDude

Quote from: 00100b on February 04, 2005, 12:26:29 PM
Isn't something like the following another method of moving a smaller value into a larger destination?

MOV EAX, DWORD PTR SomeByte


There isn't such instruction, "MOV r32, m8" or "MOV r32, r8".

You can move a immediate byte to a dword, but the assembler itself will extend it.

00100b

Quote from: UncannyDude on February 04, 2005, 01:12:19 PM
There isn't such instruction, "MOV r32, m8" or "MOV r32, r8".
No argument there, but using the PTR operator, you can override the default size of an operand.

Just as:

MOV AX, WORD PTR SomeDWord

will move the low-order word of the dword into AX.

The reverse can be used to move a smaller value into a larger destination.

The latest test of this that I performed:

.DATA
    SomeByte BYTE 08h
.CODE
    MOV EAX, 7FFFFFFFh   ; Assign EAX some value that doesn't have zeros

    ; EAX contains 7FFFFFFF

    MOV EAX, DWORD PTR SomeByte  ; Test to see if using PTR to a BYTE zero extends

    ; EAX contains 00000008


Mirno

Remember that spare space in the .DATA (or .DATA?) sections is zero'd by MASM, so for a better example, change SomeByte to

.DATA
  SomeByte BYTE 8
  SomeOtherByte BYTE 9


As you're showing that the trailing bytes after the initial SomeByte are picked up too.

Mirno

00100b

Mirno,

Thanks for pointing that out to me.  EAX = 00000908

Now I know. :U

UncannyDude

Quote from: 00100b on February 04, 2005, 01:45:08 PM
MOV AX, WORD PTR SomeDWord

will move the low-order word of the dword into AX.
Yes, this is "MOV r16, m16". While the WORD directive allow you to cast memory type, it works only because the other operator was 16 bits wide.