MOVSB﹑MOVSW 和 REP 指令
先说搬移字串。搬移字串指令有两种,分別是 MOVSB 和 MOVSW,先说MOVSB。MOVSB 的英文是 move string byte,意思是搬移一个字节,它是把 DS:SI所指位址的一个位元组搬移到 ES:DI所指的位址上,搬移后原來的內容不变,但是原来 ES:DI所指的內容会被覆蓋而且在搬移之后 SI 和 DI会自动地址向下一个要搬移的位址。
一般而言,通常程序设计师只搬一个字节,通常都会重复很多次,如果要重复的话,就得把重复次数先存储在CX 寄存器,并在 MOVSB 之前加上 REP 指令。
下面演示一下用 DEBUG
C:\WINDOWS>debug [Enter] -a [Enter] 1C6C:0100 mov cx,10 [Enter] 1C6C:0103 mov si,200 [Enter] 1C6C:0106 mov di,300 [Enter] 1C6C:0109 rep movsb [Enter] 1C6C:010B [Enter] -a 200 [Enter] 1C6C:0200 db "I learn assembly" [Enter] 1C6C:0210 [Enter]
上面的程式片段是把位于 1C6C:0200 的『I learnassembly』字串移搬到 1C6C:0300 处,此字串共 16 个字元,所以 CX 存入10H。现在來追踪看看。
-t [Enter] AX=0000 BX=0000 CX=0010 DX=0000 SP=FFEE BP=0000 SI=0200 DI=0000 DS=1C6C ES=1C6C SS=1C6C CS=1C6C IP=0106 NV UP EI PL NZ NA PO NC 1C6C:0103 BE0002 MOV SI,0200 -t [Enter] AX=0000 BX=0000 CX=0010 DX=0000 SP=FFEE BP=0000 SI=0200 DI=0000 DS=1C6C ES=1C6C SS=1C6C CS=1C6C IP=0106 NV UP EI PL NZ NA PO NC 1C6C:0106 BF0003 MOV DI,0300 -t [Enter] AX=0000 BX=0000 CX=0010 DX=0000 SP=FFEE BP=0000 SI=0200 DI=0300 DS=1C6C ES=1C6C SS=1C6C CS=1C6C IP=0109 NV UP EI PL NZ NA PO NC 1C6C:0109 F3 REPZ 1C6C:010A A4 MOVSB -d 300 L10 [Enter]
在还未搬移之前,先看看 1C6C:0300 处的內容,再追踪。
1C6C:0300 E8 A3 F6 74 08 49 46 FE-06 D7 DC EB EF E8 C3 F9 ...t.IF......... -t [Enter] AX=0000 BX=0000 CX=000F DX=0000 SP=FFEE BP=0000 SI=0201 DI=0301 DS=1C6C ES=1C6C SS=1C6C CS=1C6C IP=0109 NV UP EI PL NZ NA PO NC 1C6C:0109 F3 REPZ 1C6C:010A A4 MOVSB -d 300 L10 [Enter] 1C6C:0300 49 A3 F6 74 08 49 46 FE-06 D7 DC EB EF E8 C3 F9 I..t.IF.........
在搬移一次之后,再看看 1C6C:0300处的內容,发现上面已经和原來不一样了 (红色部份)。这是因为 movsb已经把第零个字节搬到 1C6C:0300 处,而覆蓋了原來的內容。而 CX也減少一,SI﹑DI 也各增加一而指向下一个位址。好!再追踪看看。
-t [Enter]
AX=0000 BX=0000 CX=000E DX=0000 SP=FFEE BP=0000 SI=0202 DI=0302
DS=1C6C ES=1C6C SS=1C6C CS=1C6C IP=0109 NV UP EI PL NZ NA PO NC
1C6C:0109 F3 REPZ
1C6C:010A A4 MOVSB
您有沒有发现,在搬移完之前,IP 都指向 REP MOVSB 指令 ( 即 REPMOVSB 所在位址)。要追踪这么多次,太麻烦了,干脆直接执行到搬移字串到结束。
-g 10b [Enter] AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0210 DI=0310 DS=1C6C ES=1C6C SS=1C6C CS=1C6C IP=010B NV UP EI PL NZ NA PO NC 1C6C:010B 06 PUSH ES -d 200 L10 [Enter] 1C6C:0200 49 20 6C 65 61 72 6E 20-61 73 73 65 6D 62 6C 79 I learn assembly -d 300 L 10 [Enter] 1C6C:0300 49 20 6C 65 61 72 6E 20-61 73 73 65 6D 62 6C 79 I learn assembly
搬移结束后,1C6C:0200 和 1C6C:0300 处的內容均相同,所以 MOVSB事实上是把原來字串复制到要搬移之处,而原字串是原封不动的。
MOVSW 的作用方式都和 MOVSB 相同,所不同的是 MOVSW每次搬移一个字,所以每次搬运完 SI﹑DI 會增加 2,而 CX仍然減少一。