df

Tutorial: 汇编基础 Category: C语言 Published: 2026-04-07 13:58:26 Views: 20 Likes: 0 Comments: 0
1. 关于字型的补充
yte:    8位无符号整数, b表字节
sbyte:  8位有符号整数, s表有符号
word:   16位无符号整数
sword:  16位有符号整数
dword:  32位无符号整数, d表双字
sdword: 32位有符号整数, sd表有符号双字
qword:  64位整数, q表四字
tbyte:  80位(10字节)整数, t表10字节
伪指令
DB:     8位整数
DW:     16位整数
DD:     32位整数或实数
DQ:     64位整数或实数
DT:     定义80位(10字节)整数

8位通用寄存器:AH,AL,BH,BL,CH,CL,DH,DL
16位通用寄存器:AX,BX,CX,DX,SI,DI,SP,BP
32位通用寄存器:EAX,EBX,ECX,EDX,ESI,EDI,ESP,EBP

其他通用寄存器只能利用32或者16位名称为访问:
3216位
ESI SI
EDI DI
EBP BP
ESP SP

寄存器
EAX:累加(Accumulator)寄存器, 常用于函数返回值
EBX:基址(Base)寄存器, 以它为基址访问内存
ECX:计数器(Counter)寄存器, 常用作字符串和循环操作里的计数器
EDX:数据(Data)寄存器, 常用于乘除法和I/O指针
ESI:源变址寄存器
EDI:目的变址寄存器
ESP:堆栈(Stack)指针(Pointer)寄存器, 指向堆栈顶部
EBP:基址(Base)指针(Pointer)寄存器, 指向当前堆栈底部
EIP:指令寄存器, 指向下一条指令的地址
2. MOVSB 字节串传送指令
功能:将DS:SI指向的内存单元的一个字节的数据送入ES:DI指向的内存单元中。然后
如果DF=0, 则SI自增1, DI自增1;
如果DF=1, 则SI自减1, DI自减1

详细操作:

((ES)*16+(DI))=((DS)*16+(SI))(字节)
如果DF=0, 则(SI)=(SI)+1,(DI)=(DI)+1
如果DF=1, 则(SI)=(SI)-1,(DI)=(DI)-1
3. MOVSW 字串传送指令
功能:将DS:SI指向的内存单元的一个字的数据送入ES:DI指向的内存单元中。然后
如果DF=0, 则SI自增2, DI自增2;
如果DF=1, 则SI自减2, DI自减2

详细操作:

((ES)*16+(DI))=((DS)*16+(SI))(字)
如果DF=0, 则(SI)=(SI)+2,(DI)=(DI)+2
如果DF=1, 则(SI)=(SI)-2,(DI)=(DI)-2
4. REP 重复指令(与串操作指令配合使用)
REP指令要与MOVSB或者MOVSW配合使用, 如下:

REP MOVSB/MOVSW

功能:重复执行MOVSB/MOVSW指令, 每执行一次, CX减1。直到减到0, 停止重复。
以上指令等价于:
S:  MOVSB/MOVSW
    LOOP S
REP实现了对于CX个连续单位(字节/字)的串操作, 需要提前对DF位和CX进行合理设置
DF提供方向信息, CX提供长度信息
5. CLD/STD DF 方向标志位置位指令
CLD——将DF清0

STD——将DF置1
6. DF 标志位 direction flag 方向标志位
在串操作中, 指示串操作方向的标志位。

如果DF=0, 则SI、DI在串操作后自增
如果DF=1, 则SI、DI在串操作后自减
7. 综合练习
assume cs:code, ss:stack, ds:data

data segment
           db 128 dup (0)
data ends

stack segment stack
            db 128 dup (0)
stack ends

; 0E34:0000 B82C0E        MOV     AX,0E2C
; 0E34:0003 8ED0          MOV     SS,AX
; 0E34:0005 BC8000        MOV     SP,0080
; 0E34:0008 E81200        CALL    001D
; 0E34:000B B8004C        MOV     AX,4C00
; 0E34:000E CD21          INT     21
; 0E34:0010 B80010        MOV     AX,1000
; 0E34:0013 B80010        MOV     AX,1000
; 0E34:0016 B80010        MOV     AX,1000
; 0E34:0019 B80010        MOV     AX,1000
; 0E34:001C 90            NOP
; 0E34:001D 8CCB          MOV     BX,CS
; 0E34:001F 8EDB          MOV     DS,BX
; -u
; 0E34:0021 BE1000        MOV     SI,0010
; 0E34:0024 BB0000        MOV     BX,0000
; 0E34:0027 8EC3          MOV     ES,BX
; 0E34:0029 BF007E        MOV     DI,7E00
; 0E34:002C B90C00        MOV     CX,000C
; 0E34:002F FC            CLD
; 0E34:0030 F3            REPZ
; 0E34:0031 A4            MOVSB
; 0E34:0032 C3            RET

code segment
      start:
               mov  ax, stack
               mov  ss, ax
               mov  sp, 128

               call cpy_Boot

               mov  ax, 4c00h
               int  21h

      ; ------------------------------
      ; 充当数据 B80010
      Boot:                                        ; 0010
               mov  ax,1000H
               mov  ax,1000H
               mov  ax,1000H
               mov  ax,1000H

      Boot_end:                                    ; 001C
               nop
      ; ------------------------------
      cpy_Boot:                                    ; 001D
               mov  bx,cs
               mov  ds,bx
               mov  si,OFFSET Boot

               mov  bx,0
               mov  es,bx
               mov  di,7E00H

               mov  cx,OFFSET Boot_end - Boot      ; 001c - 0010 = 0c = 12byte, 获取到数据在哪里=> 4行 B80010  MOV AX,1000
               cld                                 ; 将DF清0
      ; 将DS:SI指向的内存单元的一个字节的数据送入ES:DI指向的内存单元中
      ; 如果DF=0, 则SI自增1, DI自增1
      ; 如果DF=1, 则SI自减1, DI自减1

      ; AX=0E2C  BX=0000  CX=000C  DX=0000  SP=007E  BP=0000  SI=0010  DI=7E00
      ; DS=0E34  ES=0000  SS=0E2C  CS=0E34  IP=0030   NV UP EI PL NZ NA PO NC
      ; 0E34:0030 F3            REPZ
      ; 0E34:0031 A4            MOVSB

      ; -d ds:10
      ; 0E34:0010  B8 00 10 B8 00 10 B8 00-10 B8 00 10(12bytes) 90 8C CB 8E   ................

      ; -u ds:10
      ; 0E34:0010 B80010        MOV     AX,1000
      ; 0E34:0013 B80010        MOV     AX,1000
      ; 0E34:0016 B80010        MOV     AX,1000
      ; 0E34:0019 B80010        MOV     AX,1000
      ; 0E34:001C 90            NOP
      ; 0E34:001D 8CCB          MOV     BX,CS

      ; -d es:7e00
      ; 0000:7E00  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
               rep  movsb                          ; 直到 cx = 0
      ; -d es:7e00
      ; 0000:7E00  B8 00 10 B8 00 10 B8 00-10 B8 00 00 00 00 00 00   ................

      ; -r   ; 当CX = 0 时
      ; AX=0E2C  BX=0000  CX=0001  DX=0000  SP=007E  BP=0000  SI=001B  DI=7E0B
      ; DS=0E34  ES=0000  SS=0E2C  CS=0E34  IP=0030   NV UP EI PL NZ NA PO NC
      ; 0E34:0030 F3            REPZ
      ; 0E34:0031 A4            MOVSB
      ; -t

      ; AX=0E2C  BX=0000  CX=0000  DX=0000  SP=007E  BP=0000  SI=001C  DI=7E0C
      ; DS=0E34  ES=0000  SS=0E2C  CS=0E34  IP=0032   NV UP EI PL NZ NA PO NC
      ; 0E34:0032 C3            RET
      ; -d es:7e00
      ; 0000:7E00  B8 00 10 B8 00 10 B8 00-10 B8 00 10 00 00 00 00   ................

      ; -u es:7e00
      ; 0000:7E00 B80010        MOV     AX,1000
      ; 0000:7E03 B80010        MOV     AX,1000
      ; 0000:7E06 B80010        MOV     AX,1000
      ; 0000:7E09 B80010        MOV     AX,1000
               ret

code ends

end start
8. 使用 rep movsb、cld 实现数据正向传送
assume cs:code, ss:stack, ds:data
; =================================================================
data segment
           db 'Welcome to masm!'
           db 16 dup (0)
data ends
; =================================================================
stack segment stack
            db 128 dup (0)
stack ends
; =================================================================
code segment
      start:mov ax, stack
            mov ss, ax
            mov sp, 128

            mov ax, data
            mov ds, ax
            mov si, 0
            mov es, ax
            mov di, 16

            mov cx, 16
            cld                ; 将DF设置为0, 正向传送
            rep movsb

            mov ax, 4c00h
            int 21h

code ends

end start
9. 使用 rep movsb、cld 实现数据反向传送
assume cs:code, ss:stack, ds:data
; =================================================================
data segment
	     db 16 dup (0)
data ends
; =================================================================
stack segment stack
	      db 128 dup (0)
stack ends
; =================================================================
code segment
	start:mov ax, stack
	      mov ss, ax
	      mov sp, 128

	      mov ax, 0F000H
	      mov ds, ax
	      mov si, 0FFFFH

	      mov ax, data
	      mov es, ax
	      mov di, 15

	      mov cx, 16
	      std
	      rep movsb

	      mov ax, 4c00h
	      int 21h

code ends

end start
10. CLI/STI 中断标志位 IF
CLI: 清除标志位IF, 即设置为0(DI), 禁止中断发生

STI: 设置标志位IF, 即设置为1(EI), 允许中断发生


- 在改变SS:SP之前,必须用cli指令屏蔽中断,然后等操作执行完立即用sti指令恢复
- SS:SP需要设置在空闲的内存地址,不要建立在其他的程序(尤其是系统的)代码区
Prev: cmp Next: 逻辑指令