目录
1. DF 标志
标志寄存器的第 10 位是 DF(Direction Flag),方向标志位,在串行处理指令中,控制每次操作后 si,di 的增减。
df = 0 时,每次操作后 si,di 递增。
df = 1 时,每次操作后 si,di 递减
1.1 cld 指令
cld (clear df) 指令,清空 df 标志位,执行该指令后,df = 0.
指令格式为:cld ;设置 df = 0, 正向传送
1.2 std 指令
std (set df) 指令,设置 df 标志位,执行该指令后,df = 1
指令格式为:std ;设置 df = 1, 逆向传送
tips:
si (source index,源变址寄存器):用于存放偏移地址
di (destination index, 目的变址寄存器):用于存放偏移地址
1.3 示例
assume cs:code
code segment
start:
cld ;设置 df = 0,在 debug 中,用 UP 表示 df = 0
std ;设置 df = 1,在 debug 中,用 DN (down) 表示 df = 1
mov ax, 4c00h
int 21h
code ends
end start
2. movsb 指令
2.1 movsb 指令功能
movsb (move string byte) 指令,即按 字节 传送数据的字符串传送指令。功能是将 ds:si 指向的内存字节单元的数据送入 es:di 指向的内存字节单元中,然后根据标志寄存器中的 df 标志位的值,如果 df = 0,si 和 di 递增,如果 df = 1,si 和 di 则递减。
2.2 movsb 指令 CPU 工作原理
在 8086 CPU 中执行 movsb 指令,相当于执行以下指令
(1)mov al, [si]
mov [di], al
(2)如果 df = 0
inc si
inc di
如果 df = 1
dec si
dec di
2.3 示例
assume cs:code, ds:data
data segment
db 'welcome to masm!'
db 16 dup (0)
data ends
code segment
start:
mov ax, data
mov ds, ax
mov si, 0 ;指向第一个字符串开始的首地址
mov es, ax
mov di, 16 ;指向目的首地址
cld ;设置 df = 0,正向传送
movsb ;es:[di] = ds:[si], 因为 df = 0,然后 (si) = (si) + 1, (di) = (di) + 1
;movsb 指令执行后,第二个字符串为 'w', si = 1, di = 17
std ;设置 df = 1,逆向传送
mov si, 15 ;指向第一个字符串的尾地址
mov di, 31 ;指向目的尾地址
movsb ;es:[di] = ds:[si], 因为 df = 1, 然后 (si) = (si) - 1, (di) = (di) -1
;movsb 指令执行后,第二个字符串为 'w',14个0,'!', si = 14, di = 30
mov ax, 4c00h
int 21h
code ends
end start
3. movsw 指令
3.1 movsw 指令功能
movsw (move string word) 指令,即按 字 传送数据的字符串传送指令。功能是将 ds:si 指向的内存字单元的数据送入 es:di 指向的内存字单元中,然后根据标志寄存器中的 df 标志位的值,如果 df = 0,si 和 di 都加 2,如果 df = 1,si 和 di 则都减 2。
3.2 movsw 指令 CPU 工作原理
在 8086 CPU 中执行 movsw 指令,相当于执行以下指令
(1)mov ax, [si]
mov [di], ax
(2)如果 df = 0
add si, 2
add di, 2
如果 df = 1
sub si, 2
sub di, 2
3.3 示例
assume cs:code, ds:data
data segment
db 'welcome to masm!'
db 16 dup (0)
data ends
code segment
start:
mov ax, data
mov ds, ax
mov si, 0 ;指向第一个字符串开始的首地址
mov es, ax
mov di, 16 ;指向目的首地址
cld ;设置 df = 0,正向传送
movsw ;mov ax ds:[si]; mov es:[di] ax, 因为 df = 0,然后 add si, 2; add di, 2
;movsw 指令执行后,第二个字符串为 'we', si = 2, di = 18
std ;设置 df = 1,逆向传送
mov si, 14 ;指向第一个字符串的倒数第二个字节地址
mov di, 30 ;指向目的倒数第二个字节地址
movsw ;mov ax ds:[si]; mov es:[di] ax, 因为 df = 1,然后 sub si, 2; sub di, 2
;movsw 指令执行后,第二个字符串为 'we',12个0,'m!', si = 12, di = 28
mov ax, 4c00h
int 21h
code ends
end start
4. rep
在汇编语言中,rep 的作用是根据 cx 的值,循环执行跟在其后的指令,直到 cx = 0 时为止。
5. rep movsb
5.1 rep movsb 指令功能
根据 cx 的值,循环将 ds:si 内存字节单元的数据送入 es:di 内存字节单元中,直到 cx = 0 时为止。
5.2 rep movsb 指令 CPU 工作原理
在 8086 CPU 中执行 rep movsb 指令,相当于执行以下指令
s: movsb
loop s
5.3 示例
assume cs:code, ds:data
data segment
db 'welcome to masm!' ;偏移地址:0-15
db 16 dup (0) ;偏移地址:16-31
db 16 dup (0) ;偏移地址:32-47
data ends
code segment
start:
mov ax, data
mov ds, ax
mov si, 0 ;指向第一个字符串开始的首地址
mov es, ax
mov di, 16 ;指向目的首地址
cld ;设置 df = 0,正向传送
mov cx, 16 ;要复制的字符串有16个字节
rep movsb
std ;设置 df = 1,逆向传送
mov cx, 16 ;要复制的字符串有16个字节
mov si, 15 ;指向第一个字符串的尾地址
mov di, 47 ;指向目的尾地址
rep movsb
mov ax, 4c00h
int 21h
code ends
end start
6. rep movsw
6.1 rep movsw 指令功能
根据 cx 的值,循环将 ds:si 内存字单元的数据送入 es:di 内存字单元中,直到 cx = 0 时为止。
6.2 rep movsw 指令 CPU 工作原理
在 8086 CPU 中执行 rep movsw 指令,相当于执行以下指令
s: movsw
loop s
6.3 示例
assume cs:code, ds:data
data segment
db 'welcome to masm!' ;偏移地址:0-15
db 16 dup (0) ;偏移地址:16-31
db 16 dup (0) ;偏移地址:32-47
data ends
code segment
start:
mov ax, data
mov ds, ax
mov si, 0 ;指向第一个字符串开始的首地址
mov es, ax
mov di, 16 ;指向目的首地址
cld ;设置 df = 0,正向传送
mov cx, 8 ;要复制的字符串有16个字节, movsw 从 ds:si 内存字单元(2个字节)的数据送入 es:di 内存字单元中,所以 cx = 8
rep movsw
std ;设置 df = 1,逆向传送
mov cx, 8 ;要复制的字符串有16个字节, movsw 从 ds:si 内存字单元(2个字节)的数据送入 es:di 内存字单元中,所以 cx = 8
mov si, 14 ;指向第一个字符串倒数第二个字节地址
mov di, 46 ;指向目的倒数第二个字节地址
rep movsw
mov ax, 4c00h
int 21h
code ends
end start