News:

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

Moving a byte to a 32 bit address - how to do it?

Started by frktons, September 04, 2010, 10:24:04 PM

Previous topic - Next topic

frktons

I'm still confused with the use of MOV, BYTE PTR, and 32 bit registers addressing.

if I have a BYTE variable defined as:
MyByte   db 151

and I want to MOV it to a 32 byte address in EAX how do I change this:

mov [eax], MyByte ?

This obviously gives an error because the two operands are not the same size.

Nor it works this way:
mov  byte ptr [eax], MyByte
Mind is like a parachute. You know what to do in order to use it :-)

Gunner

~Rob (Gunner)
- IE Zone Editor
- Gunners File Type Editor
http://www.gunnerinc.com

frktons

Quote from: Gunner on September 04, 2010, 10:34:26 PM
The following works:
lea eax, MyByte
mov eax, [eax]


Thanks Gunner.

This works but it is indirect, I was trying to do it in a single instruction.

I think there is another way as well, but I can't remember how to use MOV
and BYTE PTR to get it working.
Mind is like a parachute. You know what to do in order to use it :-)

Antariy

Frank,


; move byte from memory to eax:
xor eax,eax ; if you dont want have only value of byte, you can not write this line
mov al,byte ptr [anyLabel]


Or you can use this:

movzx eax,byte ptr [anyLabel]


Second code makes only value of byte in eax - this command zeroed other high bytes.



Alex

frktons

Quote from: Antariy on September 04, 2010, 10:43:28 PM
Frank,


; move byte from memory to eax:
xor eax,eax ; if you dont want have only value of byte, you can not write this line
mov al,byte ptr [anyLabel]


Or you can use this:

movzx eax,byte ptr [anyLabel]

Thanks Alex, but this is not what I need.

I have this variable:

MyByte   db 151

and I want to MOV it to a 32 byte address that is in EAX.
I need to move the byte to [eax] not to eax.
I need only 1 byte mov to 1 byte in memory, without changing others bytes
that are in memory.

These don't work:

1. mov [eax], MyByte

2. mov  byte ptr [eax], MyByte

3.     lea  ebx, MyByte
        mov  [eax], [ebx]

I'm looking for an instruction that moves the content of MyByte variable
into the address that is in EAX, nothing else.

Frank





Mind is like a parachute. You know what to do in order to use it :-)

Antariy

Frank, try this:


movzx ecx,byte ptr [MyByte]
mov byte ptr [eax],cl




Alex

Antariy

Frank, the general rule: you cannot move memory to memory, you must use intermediate code.



Alex

frktons

Quote from: Antariy on September 04, 2010, 11:07:07 PM
Frank, try this:


movzx ecx,byte ptr [MyByte]
mov byte ptr [eax],cl


Alex


OK Alex this works. Thanks  :U
Mind is like a parachute. You know what to do in order to use it :-)


frktons

#9
Quote from: jj2007 on September 05, 2010, 07:18:34 AM
Look at movsb.

INTEL says:
Quote
Description

Moves the byte, word, or doubleword specified with the second operand (source
operand) to the location specified with the first operand (destination operand). Both
the source and destination operands are located in memory. The address of the
source operand is read from the DS:ESI or the DS:SI registers (depending on the
address-size attribute of the instruction, 32 or 16, respectively). The address of the
destination operand is read from the ES:EDI or the ES:DI registers (again depending
on the address-size attribute of the instruction)
. The DS segment may be overridden
with a segment override prefix, but the ES segment cannot be overridden.
At the assembly-code level, two forms of this instruction are allowed: the "explicitoperands"
form and the "no-operands" form. The explicit-operands form (specified
with the MOVS mnemonic) allows the source and destination operands to be specified
explicitly. Here, the source and destination operands should be symbols that
indicate the size and location of the source value and the destination, respectively.
This explicit-operands form is provided to allow documentation; however, note that
the documentation provided by this form can be misleading. That is, the source and
destination operand symbols must specify the correct type (size) of the operands
(bytes, words, or doublewords), but they do not have to specify the correct location.
The locations of the source and destination operands are always specified by the
DS:(E)SI and ES:(E)DI registers, which must be loaded correctly before the move
string instruction is executed.
The no-operands form provides "short forms" of the byte, word, and doubleword
versions of the MOVS instructions. Here also DS:(E)SI and ES:(E)DI are assumed to
be the source and destination operands, respectively. The size of the source and
destination operands is selected with the mnemonic: MOVSB (byte move), MOVSW
(word move), or MOVSD (doubleword move).
After the move operation, the (E)SI and (E)DI registers are incremented or decremented
automatically according to the setting of the DF flag in the EFLAGS register.
(If the DF flag is 0, the (E)SI and (E)DI register are incremented; if the DF flag is 1,
the (E)SI and (E)DI registers are decremented.) The registers are incremented or
decremented by 1 for byte operations, by 2 for word operations, or by 4 for doubleword
operations.
The MOVS, MOVSB, MOVSW, and MOVSD instructions can be preceded by the REP
prefix (see "REP/REPE/REPZ /REPNE/REPNZ—Repeat String Operation Prefix" in
Chapter 4 of the Intel® 64 and IA-32 Architectures Software Developer's Manual,
Volume 2B, for a description of the REP prefix) for block moves of ECX bytes, words,
or doublewords.

It seems that to use MOVSB I need to fill ESI for source address and  EDI for target address.
It could be useful If I had to MOV 11 bytes, for example, using REP/MOVSB and putting
11 into ECX for contiguous addresses.

In my case I only need to move The same BYTE variable to different non contiguous addresses.
To be exact I need to move the BYTE variable to an area every fourth bytes:

x---x---x---x---x---x

the "x" represent the addresses into a memory block at which I have to MOV the BYTE variable.
the "-" represent the addresses occupied by other values that I have to leave where they are.

In this case I should manually change EDI before each MOV.

Or at least this is what I think.

I'm using Alex suggestion, and having the destination address in EAX, I do:

    movzx ebx, byte ptr [MyByte]
    mov   ecx, 11
Again:
    mov   byte ptr [eax],bl
    add    eax, 4
    dec    ecx
    jnz     Again


There is any advantage for using MOVSB instead of the mnemonics I'm
actually using?

It would change this way:

     lea  edi,  MyByte
     lea  esi,  MyDestination
     mov  ecx, 11
Again:
     movsb
     add   esi, 3
     dec   edi
     dec   ecx
     jnz    Again


If I correctly understood what MOVSB does.
And it doesn't look like a better solution than the previous one.       

Frank




Mind is like a parachute. You know what to do in order to use it :-)

frktons

The complete code in which I'm using these mnemonics is a proc for
building a Box inside a buffer:


; -------------------------------------------------------------------------
; Fill the buffer with a box of 80 characters starting at line requested
; till the number of line passed as II parameter
;--------------------------------------------------------------------------

BuildBox PROC Row1:DWORD, Row2:DWORD


    mov  eax,  Row1
    sub  eax,  1
    imul eax,  320
    mov  edx, eax

    lea  eax, ConsoleScreen
    add  eax, edx


    movzx ebx, byte ptr [TopLeft]
    mov   byte ptr [eax],bl

    add  eax, 4

    mov  ecx, 78

    movzx ebx, byte ptr [HorizLine]

    mov  bl,  HorizLine
   
FillBoxLine1:

    mov  byte ptr [eax], bl
    add  eax,   4
    dec  ecx
    jnz  FillBoxLine1

    movzx ebx, byte ptr [TopRight]

    mov  byte ptr [eax], bl
    add  eax,   4

    mov  ecx, Row2
    sub  ecx, Row1
    dec  ecx
    movzx ebx, byte ptr [VerticLine]

FillBorder:


    mov   byte ptr [eax], bl

    add  eax,   4
    mov  edx,   4
    imul edx,  78

    add  eax, edx
    mov  byte ptr [eax], bl
    add  eax,   4   
    dec  ecx
    jnz  FillBorder

    movzx ebx,byte ptr [BottomLeft]
    mov   byte ptr [eax], bl

    add  eax,   4

    mov  ecx, 78

    movzx ebx, byte ptr [HorizLine]

FillBoxLine2:

    mov  byte ptr [eax], bl
    add  eax,   4
    dec  ecx
    jnz  FillBoxLine2

    movzx ebx, byte ptr [BottomRight]
    mov   byte ptr [eax], bl


    ret


BuildBox ENDP



If I can improve this routine getting rid of redundant instructions just
let me know how would you change this code.

Frank

Mind is like a parachute. You know what to do in order to use it :-)

zemtex

Quote from: frktons on September 05, 2010, 10:17:28 AM
The complete code in which I'm using these mnemonics is a proc for
building a Box inside a buffer:


; -------------------------------------------------------------------------
; Fill the buffer with a box of 80 characters starting at line requested
; till the number of line passed as II parameter
;--------------------------------------------------------------------------

BuildBox PROC Row1:DWORD, Row2:DWORD


    mov  eax,  Row1
    sub  eax,  1
    imul eax,  320
    mov  edx, eax

    lea  eax, ConsoleScreen
    add  eax, edx


    movzx ebx, byte ptr [TopLeft]
    mov   byte ptr [eax],bl

    add  eax, 4

    mov  ecx, 78

    movzx ebx, byte ptr [HorizLine]

    mov  bl,  HorizLine
   
FillBoxLine1:

    mov  byte ptr [eax], bl
    add  eax,   4
    dec  ecx
    jnz  FillBoxLine1

    movzx ebx, byte ptr [TopRight]

    mov  byte ptr [eax], bl
    add  eax,   4

    mov  ecx, Row2
    sub  ecx, Row1
    dec  ecx
    movzx ebx, byte ptr [VerticLine]

FillBorder:


    mov   byte ptr [eax], bl

    add  eax,   4
    mov  edx,   4
    imul edx,  78

    add  eax, edx
    mov  byte ptr [eax], bl
    add  eax,   4   
    dec  ecx
    jnz  FillBorder

    movzx ebx,byte ptr [BottomLeft]
    mov   byte ptr [eax], bl

    add  eax,   4

    mov  ecx, 78

    movzx ebx, byte ptr [HorizLine]

FillBoxLine2:

    mov  byte ptr [eax], bl
    add  eax,   4
    dec  ecx
    jnz  FillBoxLine2

    movzx ebx, byte ptr [BottomRight]
    mov   byte ptr [eax], bl


    ret


BuildBox ENDP



If I can improve this routine getting rid of redundant instructions just
let me know how would you change this code.

Frank



Tip 1: You dont need "byte ptr" when the assembler knows you are using an 8 bit register. You really only need it when referencing memory, not a register.

Tip 2: You use the number "4", four times up there. Move the number 4 to a register and use the register instead of a constant number.

Tip 3: When calculating the offset of different lines, consider the cmov instructions instead of using complex jump structures. cmovb will move a value into the number if the number is below the given number (for example).  cmova will move the value if the value is above etc. And when dealing with the 80x25 screen you can implement smart shifting for calculating offset.

As a final note, it can be done alot more efficient but it takes a bit of planning to do so.
I have been puzzling with lego bricks all my life. I know how to do this. When Peter, at age 6 is competing with me, I find it extremely neccessary to show him that I can puzzle bricks better than him, because he is so damn talented that all that is called rational has gone haywire.

frktons

Quote from: zemtex on September 05, 2010, 01:33:02 PM

Tip 1: You dont need "byte ptr" when the assembler knows you are using an 8 bit register. You really only need it when referencing memory, not a register.

Tip 2: You use the number "4", four times up there. Move the number 4 to a register and use the register instead of a constant number.

Tip 3: When calculating the offset of different lines, consider the cmov instructions instead of using complex jump structures. cmovb will move a value into the number if the number is below the given number (for example).  cmova will move the value if the value is above etc. And when dealing with the 80x25 screen you can implement smart shifting for calculating offset.

As a final note, it can be done alot more efficient but it takes a bit of planning to do so.

Thanks for the Tips, zemtex. I'll try to put them in use as far as I can with my actual knowledge.
If you have some spare time and would like to enjoy a CHALLENGE, have a look at:
http://www.masm32.com/board/index.php?topic=14734.0

Frank
Mind is like a parachute. You know what to do in order to use it :-)