简体   繁体   中英

why does movsw instruction increments the si and di registers by2 while movsb instruction increments the si and di registers by 1?

I was working with the movsb and movsw instruction in assembly language using the flat assembler. Now, i noticed that when the movsb instruction is executed the SI and DI register is incremented by 1 while the movsw instruction increments the SI AND DI register by 2. I am a bit confused why? Can anyone explain me the reason. I am adding my codes below for both the instruction with comments. Please help me out. Thanks!

Using the movsb instruction(Flat assembler)

cld ;clear direction flag

lea si,[val]  ;the memory address of source is loaded in the source register

lea di,[v];the memory address of the destination is loaded in the destination register

mov cx,5 ; the counter basically executes for the number of characters in the array

rep movsb ; repeats the instruction for 5 times

val:
     db 'A' 
     db 'B'
     db 'C'
     db 'D'
     db 'E'

v db 5 DUP(?)

Using the movsw instruction(Flat assembler)

cld    ;clear the direction flag

lea si,[a];load the address of a in source
;register
lea di,[b] ;load the address of b in destination
;register
mov cx,3
rep movsw  ;copy each word from source to
;destination and increment the source register
;by 2 and destination register by 2

a: 
  dw '1'
  dw '2'
  dw '3'

b dw 3 DUP(?)

movsw , movsb , movsd , movsq are instructions used to copy data from the source location DS:(ER)SI to destination location ES:(ER)DI .

They are useful because there is no mem-to-mem move instruction in IA32e.

They are meant to be used in cycles (for example by using the rep prefix), so besides moving the data they also increments (if DF flag, Direction Flag, is 0) or decrements (if DF flag is 1) the pointers to the source and destination locations, ie the (ER)SI and (ER)DI registers.

From the assembly programmer perspective the memory is byte-addressable, it means that each address store one byte.

  • movsb moves a byte, so the register are incremented/decremented by 1.
  • movsw moves a WORD (2 bytes), so the register are incremented/decremented by 2.
  • movsd moves a DWORD (Double Word, 2 Word, 4 bytes), so the register are incremented/decremented by 4.
  • movsq moves a QWORD (Quad Word, 4 words, 8 bytes), so the register are incremented/decremented by 8.

Because movsb moves (or copies, really) one Byte, while movsw moves one Word. A word in x86 terminology is 2 bytes.

From Intel's manual:

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.
The registers are incremented or decremented by 1 for byte operations, by 2 for word operations, or by 4 for doubleword operations.

Or, more formally:

IF (Byte move)
  THEN IF DF = 0
    (E)SI ← (E)SI + 1;
    (E)DI ← (E)DI + 1;
  ELSE
    (E)SI ← (E)SI – 1;
    (E)DI ← (E)DI – 1;
  FI;
ELSE IF (Word move)
  THEN IF DF = 0
    (E)SI ← (E)SI + 2;
    (E)DI ← (E)DI + 2;
  FI;
  ELSE
    (E)SI ← (E)SI – 2;
    (E)DI ← (E)DI – 2;
  FI;

movsb moves a byte from SI to DI and decrements/increments them both by one byte. movsw moves a word from SI to DI and decrements/increments them both by two bytes (a word). Each of these instructions basically do the same thing, except they move different sizes of memory.

I hope this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM