移动代码段:
rep movsw
mov ax,#BOOTSEG
mov ds,ax
mov ax,#INITSEG
mov es,ax
mov cx,#256
sub si,si
sub di,di
cld
rep
movsw
jmpi go,INITSEG
【linux中bootsection.s用这段代码完成moves itself out of
theway to address Ox90000,and jumps there】
先说搬移字串。搬移字串指令有两种,分别是
MOVSB 和 MOVSW,先说 MOVSB。MOVSB
的英文是 move string
byte,意思是搬移一个字节,它是把 DS:SI
所指地址的一个字节搬移到 ES:DI
所指的地址上,搬移后原来的内容不变,但是原来
ES:DI 所指的内容会被覆盖而且在搬移之后 SI 和 DI
会自动的指向下一个要搬移的地址。
一般而言,通常程序设计师一般并不会只搬一个字节,通常都会重复许多次,如果要重复的话,就得把重复次数
( 也就是字串长度 ) 先记录在 CX 寄存器,并且在
MOVSB 之前加上 REP 指令,REP 是重复 (repeat)
的意思。这种写法很是奇怪,一般而言汇编语言源文件的每一行都只有一个指令,但
REP MOVSB
却可以在同一行写两个指令,当然分开写也是一样的。
SUB (subtract)
指令的汇编格式:SUB dst,src
指令的基本功能:(dst)
重复执行串 REP
指令的汇编格式:REP (CX)=重复次数
指令的基本功能:①
(CX)=0时,串指令执行完毕,否则执行② ~ ④
② (CX)←(CX)-1③ 执行串指令(MOVS或STOS)④
重复执行①
串传送 MOVSB / MOVSW (move string
byte/word)
指令的汇编格式:MOVSB
MOVSW
指令的基本功能:(ES:DI)
(SI)
(DI)
指令对条件码的影响:不影响条件码。
指令的特殊要求:源串必须在数据段中,目的串必须在附加段中,串处理指令隐含的寻址方式是SI和DI寄存器的间接寻址方式。源串允许使用段跨越前缀来指定段。
MOVSB?MOVSW 和 REP 指令
先说搬移字串。搬移字串指令有两种,分?是 MOVSB
和 MOVSW,先说 MOVSB。MOVSB 的英文是 move MOVSB。MOVSB
的英文是 movstring
byte,意思是搬移一个字节,它是把 DS:SI
所指位址的一个位元组搬移到 ES:DI
所指的位址上,搬移后原?的?容不变,但是原来
ES:DI 所指的?容会被覆?而且在搬移之后 SI 和 DI
会自动地址向下一个要搬移的位址。
一般而言,通常程序设计师只搬一个字节,通常都会重复很多次,如果要重复的话,就得把重复次数先存储在
CX 寄存器,并在 MOVSB 之前加上 REP 指令。
MOVSB。MOVSB 的英文是 mov
下面演示一下用 DEBUG 来观察 REP MOVSB
执行情形(网友小木偶的演示程序):
C:\WINDOWS>debug [Enter] - MOVSB?MOVSW 和 REP 指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]
-MOVSB。MOVSB 的英文是 mova 200 [Enter] 1C6C:0200 db "I learn
assembly" [Enter] 1C6C:0210 [Enter]
?是 MOVSB 和 MOVSW,先说
上面的程式片段是把位于 1C6C:0200 的『I learn
assembly』字串移搬到 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 -?是 MOVSB 和 MOVSW,先说 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]
e string byte,意思是搬移一
在还未搬移之前,先看看 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 MOVSB。MOVSB 的英文是
mov49 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
指令 ( 即 REP MOVSB 所在位址
)。要追踪这么多次,太麻烦了,干脆直接执行到搬移字串到结束。
?是 MOVSB 和 MOVSW,先说
-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
事实上是把原?字串复制到要搬移之处,而原字串是原封不动的。
MOVSB?MOVSW 和 REP 指
MOVSW 的作用方式都和 MOVSB 相同,所不同的是 MOVSW
每次搬移一个字,所以每次搬运完 SI?DI ?增加 2,而
CX 仍然?少一。