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.