串操作指令 : 在 计算机中,大部分数据存放在主存中, 8086cpu 提供了一组处理主存中连续存放的数据串的指令 —— 串操作指令。串操作指令中,源操作数用寄存器 si 寻址,默认在数据段 ds 中,但允许段超越;目的操作数用寄存器 di 寻址,默认在附加段 es 中,不允许段超越。每执行一次串操作指令,作为源地址指针的 si 和作为目的地址指针的 di 将自动修改: +/-1 (对于字节串)或 +/-2 (对于字串)。地址指针时增加还是减少取决于方向标志 df 。在系统初始化后或者执行指令 cld 指令后, df=0, 此时地址指针增 1 或 2 ;在执行指令 std 后, df=1 ,此时地址指针减 1 或 2 。
数据传送类指令每次只能传送一个数据,若要传送大批数据就需要重复编程,这样就浪费了大量的时间和空间。为此 8086 提供了一组处理主存中连续存放数据串的指令,这就是串操作指令。
movs 串传送
cmps 串比较
scas 串扫描
lods 从串取
stos 存入串
ins 串输入
outs 串输出
与上述基本指令配使用的前缀有:
rep 重复
repe/repz 相等 / 为零则重复
repne/repnz 不相等 / 不为零则重复
1 .重复前缀指令 rep 、 repz 、 repnz
(1) rep :rep 前缀用在 movs 、 stos 、 lods 、 ins 和 outs 指令前。
格式: rep string primitive
其中 string primitive 可为 movs , lods 等指令。
功能:
(1) 如果 (cx)=0 ,则退出 rep ,否则往下执行。
(2)(cx)=(cx) - 1
(3) 执行其后的串指令
(4) 重复 (1)-(3)
(2) repz/repe: 该指令一般用在 cmps 、 scas 指令前。
格式: repe( 或 repz) string primitive
其中 string primitive 可为 cmps 或 scas 指令。
功能:
(1) 如果 (cx)=0 或 zf=0 时退出,否则往下执行。
(2)(cx)=(cx) - 1
(3) 执行其后的串指令
(4) 重复 (1)-(3)
与 rep 相比,除满足 (cx)=0 的条件可结束操作外,还增加了 zf=0 的条件,也就是说,如果两数相等就可继续比较,如果遇到了两数不相等可提前结束操作。
(3) repnz/repne : 该指令一般用在 cmps 、 scas 指令前。
格式: repe( 或 repz) string primitive
其中 string primitive 可为 cmps 或 scas 指令。
功能:
(1) 如果 (cx)=0 或 zf=1 时退出,否则往下执行。
(2)(cx)=(cx) - 1
(3) 执行其后的串指令
(4) 重复 (1)-(3)
与 rep 相比,除满足 (cx)=0 的条件可结束操作外,还增加了 zf=1 的条件,也就是说,如果两数不相等就可继续比较,如果遇到了两数相等可提前结束操作。
2传送指令 movs
语句格式:① movs dst , src
② movsb ——字节串传送
③ movsw ——字串传送
其中后两种明确注明是传送字节还是字 , 第一种格式则应在操作数中表明是字节还是字的操作 . 例如 :
movs es:byte ptr[di],ds:[si]
功能:将以 si 为指针的源串中的一个字节(或字)存储单元中的数据传送至以 di 为指针的目的地址中去,并自动修改指针,使之指向下一个字节(或字)存储单元。
即:①( ds : [si] )→ es : [di] 。
② 当 df=0 时,( si )和( di )增量。
当 df=1 时,( si )和( di )减量。
③当操作为字节操作时, (si) 、 (di) 增减量为 1 ,当操作为字操作时, (si) 、 (di) 增减量为 2 。
④当该指令与前缀 rep 联用时,则可将数据段中的整串数据传送到附加段中去,这里源串必须在数据段中,目的串必须在附加段中,但源串允许使用段跨越前缀来修改。在与 rep 联用时,还必须先把数据串的长度值送到计数寄存器中,以便控制指令结束。因此在执行该指令前,必做如下准备工作:
i. 把存放在数据段中的源串首地址 ( 如反向传送则应是末地址 ) 放入源变址寄存器中 ;
ii. 把将要存放数据串的附加段中的目的串首址 ( 反向传送时为末地址 ) 放入目的变址寄存器 ;
ⅲ . 把数据串长度放入计数寄存器 ;
ⅳ . 建立方向标志。
例:在数据段中有一个字符串,其长度为 17 ,要求把它们转送到附加段中的一个缓冲区中。
data segment
mess1 db ‘personal computer$'
data ends
extra segment
mess2 db 17 dup(?)
extra ends
code segment
assume cs:code,ds:data,es:extra
…
mov ax,data
mov ds,ax
mov ax,extra
mov es,ax
…
lea si,mess1
lea di,mess2
mov cx,17
cld
rep movsb
…
code ends
3 .串比较指令 cmps
语句格式:① cmps src , dst ——需指定操作类型字
② cmpsb ——字节串比较
③ cmpsw ——字串比较
功能:将 si 所指的源串中的一个字节(或字)存储单元中的数据与 di 所指的目的串中的一个字节(或字)存储单元中的数据相减,并根据相减的结果设置标志,但结果并不保存。
即:①( [si] )-( [di] )。
② 修改串指针,使之指向串中的下一个元素。当 df=0 时,( si )和( di )增量。当 df=1 时,( si )和( di )减量。
③当操作为字节操作时, (si) 、 (di) 增减量为 1 ,当操作为字操作时, (si) 、 (di) 增减量为 2 。
4 .串搜索指令 scas
语句格式:① scas dst
② scasb ——字节串搜索
③ scasw ——字串搜索
功能: al (字节)或 ax (字)中的内容与 di 所指的目的串中的一个字节(
字)存储单元中的数据相减,根据相减结果设置标志位,结果不保存,
即:① 字节操作:( al )-( [di] ),字操作:( ax )-( [di] )。
② 修改指针使之指向串中的下一个元素。当 df=0 时,( di )增量。当 df=1 时,( di )减量。
③当操作为字节操作时, (si) 、 (di) 增减量为 1 ,当操作为字操作时, (si) 、 (di) 增减量为 2 。
以上 3 , 4 两条串处理指令和 repe 或 repne 相结合,可以用来比较两个数据串,或从一个字符串中查找一个指定的字符。
当要求从一个字符串中查找一个指定的字符,可用指令 repnz scasb 。
当要求比较两个字符串,找出它们不相区配的位置,则可以使用指令 repe cmpsb 。
5 .从源串中取数指令 lods
语句格式:① lods src
② lodsb ——从字节串中取数
③ lodsw ——从字串中取数
功能:将 si 所指的源串中的一个字节(或字)存储单元中的数据取出来送入 al (或 ax )中。
即:
① 字节操作:( [si] )→ al ,字操作:( [si] )→ ax 。
② 修改指针 si ,使它指向串中的下一个元素。当 df=0 时,( si )增量。当 df=1 时,( si )减量。
③当操作为字节操作时, (si) 、 (di) 增减量为 1 ,当操作为字操作时, (si) 、 (di) 增减量为 2 。
6 .往目的串中存数指令 stos
语句格式:① stos dst
② stosb ——往字节串中存数
③ stosw ——往字串中存数
功能:将 al 或 ax 中的数据送入 di 所指的目的串中的字节(或字)存储单元中。
即:
① 字节操作:( al )→ [di] ,字操作:( ax )→ [di] 。
② 修改指针 di ,使之指向串中的下一个元素。当 df=0 时,( di )增量)。当 df=1 时,( di )减量。
③当操作为字节操作时, (si) 、 (di) 增减量为 1 ,当操作为字操作时, (si) 、 (di) 增减量为 2 。
对串处理指令,需注意:
(1) 串处理指令在不同的段之间传送或比较数据,如果需要在同一段内处理数据,可以在 ds 和 es 中设置同样的地址,或者在源操作数字段使用段跨越前缀来实现。例如:
movs [di] , es : [si]
(2) 当使用重复前缀时, (cx) 是每次减 1 的,因此对于字指令来说,预置时设置的值应该是字的个数而不是字节数。