第七周 匯編語(yǔ)言程序設(shè)計(jì)
大家好,又是我,沉迷學(xué)習(xí)無(wú)法自拔的小笨蛋康sir。
這個(gè)文集(點(diǎn)我)將會(huì)同步更新我觀看吳寧老師的《微機(jī)原理與接口技術(shù)》教學(xué)視頻寫的筆記,學(xué)習(xí)筆記,大概每周一章。
有問(wèn)題大家可以在評(píng)論下面留言討論,歡迎糾錯(cuò)!
歡迎收藏閱讀,動(dòng)動(dòng)小手給個(gè)硬幣點(diǎn)個(gè)贊。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ——@正能量的康sir
也可移步我的博客(https://blog.csdn.net/qq_33956508)會(huì)更新一些其它技術(shù)類文章。

第35講 匯編語(yǔ)言源程序
主要內(nèi)容
匯編程序與匯編語(yǔ)言源程序
匯編語(yǔ)言語(yǔ)句類型與格式
匯編語(yǔ)言語(yǔ)句中的操作數(shù)
1. 匯編語(yǔ)言源程序與匯編程序
匯編語(yǔ)言源程序——用助記符編寫
匯編程序——源程序的編譯程序
匯編語(yǔ)言源程序——>匯編程序——>機(jī)器語(yǔ)言目標(biāo)程序
匯編語(yǔ)言程序設(shè)計(jì)與執(zhí)行過(guò)程
輸入?yún)R編語(yǔ)言源程序(EDIT) ---源文件.ASM
匯編(MASM)----目標(biāo)文件.OBJ
鏈接(LINK)----可執(zhí)行文件.EXE
調(diào)試(TD)-----最終程序
2.匯編語(yǔ)言語(yǔ)句類型和格式
匯編語(yǔ)言語(yǔ)句類型:
指令性語(yǔ)句->CPU執(zhí)行的語(yǔ)句,能夠生成目標(biāo)代碼
指示性語(yǔ)句->CPU不執(zhí)行,而由匯編程序執(zhí)行的語(yǔ)句,不生成目標(biāo)代碼
匯編語(yǔ)言語(yǔ)句格式:
指令性語(yǔ)句格式:
[標(biāo)號(hào):][前綴] 助記符 [操作數(shù)],[操作數(shù)][;注釋]
(助記符就是操作碼,不可缺少,[ ]中是可以沒(méi)有的)
(標(biāo)號(hào)Label是指令的符號(hào)地址,標(biāo)號(hào)后要有冒號(hào))
指示性語(yǔ)句格式:
[名字] 偽指令助記符 操作數(shù)[,操作數(shù),…][;注釋]
(指示性語(yǔ)句中至少有一個(gè)操作數(shù))
(名字,變量的符號(hào)地址,后面不加冒號(hào))
3匯編語(yǔ)言語(yǔ)句中的操作數(shù)
寄存器
存儲(chǔ)器單元
常量
變量或標(biāo)號(hào)
表達(dá)式
常量:
數(shù)字常量,1234…
字符常量,用單引號(hào)引起的字符或字符串,’A’ ’a’ ’ABCD’
例
MOV AL,’A’ ?AL=41H
定義字符串:’ABCD’匯編時(shí)被譯成對(duì)應(yīng)的ASCII碼 41H,42H,43H,44H
標(biāo)號(hào)(也叫 變量):
內(nèi)存單元的符號(hào)地址,為存儲(chǔ)器操作數(shù)
標(biāo)號(hào)的屬性:
段值 變量所在段的段地址
偏移量 變量所指單元的偏移地址
類型 字節(jié)型\字型\雙字類型
標(biāo)號(hào)的命名
不能與指令助記符或偽指令重名(注意 匯編語(yǔ)言不區(qū)分大小寫 所以變量也不能是小寫的注記符或偽指令)
不允許由數(shù)字打頭
字符個(gè)數(shù)不超過(guò) 31 個(gè)。
? ? ? ?

? ? ? ?
表達(dá)式:
算數(shù)運(yùn)算
邏輯運(yùn)算
關(guān)系運(yùn)算
取值運(yùn)算和屬性運(yùn)算
其他運(yùn)算
取值運(yùn)算符
用于分析存儲(chǔ)器操作數(shù)的屬性
獲取變量的屬性值
OFFSET 取得其后變量或標(biāo)號(hào)的偏移地址. (用LEA也可以做到)
SEG 取得其后變量或標(biāo)號(hào)的段地址
例:
MOV AX,SEG DATA
MOV DS,AX
MOV BX,OFFSET DATA等價(jià)于LEA BX,DATA
屬性運(yùn)算符
用于指定其后存儲(chǔ)器操作數(shù)的類型
運(yùn)算符PTR
例子
MOV BYTE PTR[BX],12H
指定存儲(chǔ)器操作數(shù)[BX]是字節(jié)型
第36講 數(shù)據(jù)定義偽指令
偽指令
由匯編程序執(zhí)行的”指令系統(tǒng)”
作用:
定義變量
分配存儲(chǔ)器
定義邏輯段
指示程序開(kāi)始和結(jié)束
定義過(guò)程等.
幫助計(jì)算機(jī)理解助記符指令編寫的匯編語(yǔ)言源程序
常用偽指令:
數(shù)據(jù)定義偽指令
符號(hào)定義偽指令
段定義偽指令
結(jié)束偽指令
過(guò)程定義偽指令
宏命令偽指令
數(shù)據(jù)定義偽指令
用于定義數(shù)據(jù)區(qū)中變量的類型及其所占內(nèi)存空間大小
格式:[變量名] 偽指令助記符 操作數(shù),… ;[注釋]
變量名:符號(hào)地址
偽指令助記符:定義變量類型
操作數(shù):變量值,可以是常數(shù),表達(dá)式或字符串。其大小不能超過(guò)偽指令助記符所限定的范圍
變量的類型及其操作數(shù)的個(gè)數(shù)決定了該變量所在內(nèi)存空間的大小
1. 數(shù)據(jù)定義偽指令助記符
? DB(Define Byte):定義的變量為字節(jié)型 指向的每一個(gè)操作數(shù)占1個(gè)字節(jié)單元
? DW (Define Word) :定義的變量為字類型 指向的每一個(gè)操作數(shù)占1個(gè)字單元
? DD (Define Double Word) :定義的變量為雙字型
? DQ (Define Quadword) :定義的變量為4字型
? DT (Define Tenbytes) :定義的變量為10字節(jié)型
例
DATA1 DB 11H,22H,33H,44H
DATA2 DW 11H,22H,3344H
DATA3 DD 11H*2,22H,33445566H
以上變量在內(nèi)存中的存放形式?
? ? ? ?

? ? ? ?
數(shù)據(jù)定義偽指令的幾點(diǎn)說(shuō)明
數(shù)據(jù)定義偽指令決定所定義變量的類型;
定義字符串必須用DB偽指令
例: DATA1 DB ‘ABCD’ ,66H
? ? ? ?

? ? ? ?
2. 重復(fù)操作符
當(dāng)同樣的操作數(shù)重復(fù)多次時(shí),可以使用重復(fù)操作符。
作用:為一個(gè)數(shù)據(jù)區(qū)的各單元設(shè)置相同的初值
格式:[變量名] 偽指令助記符 n DUP(初值 [,初值,… ] )
n:重復(fù)次數(shù)
(初值 [,初值,… ] ):重復(fù)的內(nèi)容
例: M1 DB 10 DUP(0)
常用于聲明一個(gè)數(shù)據(jù)區(qū)
3. “?”的作用
表示隨機(jī)值,用于預(yù)留存儲(chǔ)空間
例:
? MEM1 DB 34H, ’A’ ,? 隨機(jī)數(shù)占1個(gè)字節(jié)單元
? DW 20 DUP(?) 預(yù)留40個(gè)字節(jié)單元,每單元為隨機(jī)值
數(shù)據(jù)定義偽指令例
? M1 DB ‘How are you?’
? M2 DW 3 DUP(11H),3344H
DB 4 DUP(?)
? M3 DB 3 DUP(22H,11H,?)
? ? ? ?

? ? ? ?
第37講 符號(hào)與段定義偽指令
一、符號(hào)定義偽指令
? 將表達(dá)式的值賦給一個(gè)名字。當(dāng)源程序中需多次引用某一表達(dá)式時(shí),可以利用EQU偽指令,用一個(gè)符號(hào)代替表達(dá)式,以便于程序維護(hù)。
? 格式:
? 符號(hào)名 EQU 表達(dá)式
(EQU說(shuō)明的表達(dá)式不占用內(nèi)存空間)
(類似于c語(yǔ)言中的#define)
? 操作:
? 用符號(hào)名取代后邊的表達(dá)式,不可重新定義
? 例:
? CONSTANT EQU 100
后面的程序就可以用CONSTANT代替100了
二、段定義偽指令
? 在匯編語(yǔ)言源程序中定義邏輯段
? 說(shuō)明邏輯段的起始和結(jié)束
? 說(shuō)明不同程序模塊中同類邏輯段之間的聯(lián)系形態(tài)
? 格式:
段名 SEGMENT [定位類型] [組合類型] [’類別’]
┇(中間的是內(nèi)容,可以是代碼,可以是數(shù)據(jù),看是什么段了)
段名 ENDS
段名 邏輯段的段基地址
定位類型 說(shuō)明邏輯段的起點(diǎn)。(默認(rèn)以節(jié)為邊界,被16整除)
組合類型 裝入內(nèi)存時(shí)各邏輯段的組合方式(默認(rèn)不組合)
類別 鏈接時(shí)不同程序模塊中的同類邏輯段將被裝入連續(xù)存儲(chǔ)區(qū)。
段定義偽指令例
DATA SEGMENT
MEM1 DB 11H,22H
MEM2 DB ‘Hello!’
MEM3 DW 2 DUP(?)
DATA ENDS
DATA段名代表邏輯段的段地址
MEM1\ MEM2 \MEM 3變量在邏輯段中的位置就代表了它的偏移地址
DW、DB表示變量的類型
DATA段名也代表邏輯段的段地址
三、設(shè)定段寄存器偽指令
說(shuō)明所定義邏輯段的性質(zhì)。設(shè)定段寄存器為指令助記符
格式:
? ASSUME 段寄存器名:段名[,段寄存器名:段名,…]
因?yàn)橐粋€(gè)程序模塊里有四種邏輯段,每個(gè)段寄存器對(duì)應(yīng)每種邏輯段,所以可以用段寄存器來(lái)定義邏輯段性質(zhì)。
例如ASSUME CS:代碼段名字 代碼段一定有
定義數(shù)據(jù)段 ASSUME DS:段名
有串操作聲明附加段 ASSUME ES:段名
堆棧聲明堆棧段 ? ASSUME SS:段名
四、結(jié)束偽指令
? 表示源程序結(jié)束
? 格式: END [標(biāo)號(hào)]
匯編語(yǔ)言源程序結(jié)構(gòu):
數(shù)據(jù)段名 SEGMENT
…
數(shù)據(jù)段名 ENDS
附加段名 SEGMENT
…
附加段名 ENDS
堆棧段名 SEGMENT
…
堆棧段名 ENDS
代碼段名 SEGMENT
…
代碼段名 ENDS
END
一定有代碼段,大多需要定義數(shù)據(jù)段,有串操作需要定義附加段,有PUSH\POP\過(guò)程中斷等需要堆棧的需要定義堆棧段
一個(gè)完整源程序結(jié)構(gòu)例:
DSEG SEGMENT
DATA1 DB 1, 2, 3 DUP (?)
DATA2 DW 1234H
DSEG ENDS
ESEG SEGMENT
DB 20 DUP(?)
ESEG ENDS
SSEG SEGMENT STACK ‘STACK‘
DB 200 DUP (?)
SSEG ENDS
CSEG SEGMENT
ASSUME CS: CSEG, DS: DSEG,
ES: ESEG. SS: SSEG;這里可以換行,但是上一句的逗號(hào)不能缺省
START: MOV AX, DSEG;因?yàn)楫?dāng)目的操作數(shù)是段寄存器時(shí),源操作數(shù)不能是立即數(shù),所以通過(guò)AX.
MOV DS, AX
MOV AX, ESEG
MOV ES, AX
MOV AX, SSEG
MOV SS, AX;這幾行叫做段寄存器的初始化,將段地址送給相應(yīng)的段寄存器
……省略的地方才是前面學(xué)的那些源代碼程序
CSEG ENDS
END START
第38講 其它偽指令
過(guò)程定義偽指令
宏定義偽指令
調(diào)整偏移量偽指令
過(guò)程定義偽指令
? 用于定義一個(gè)過(guò)程體
? 格式:
過(guò)程名 PROC [ NEAR / FAR ]
┇
RET
過(guò)程名 ENDP
過(guò)程名:過(guò)程入口的符號(hào)地址
若為近過(guò)程,NEAR可省略。(沒(méi)有的話默認(rèn)NEAR)
過(guò)程體的最后一條指令必須是RET
過(guò)程定義及調(diào)用例:
定義延時(shí)子程序
DELAY PROC
PUSH BX
PUSH CX;這兩條參數(shù)保護(hù)。和后面POP搭配起來(lái)
MOV BL,2
NEXT:MOV CX,4167
W10M: LOOP W10M
DEC BL
JNZ NEXT
POP CX
POP BX
RET
DELAY ENDP
調(diào)用延時(shí)子程序
CALL DELAY
宏命令偽指令
? 宏:源程序中由匯編程序識(shí)別的具有獨(dú)立功能的一段程序代碼
? 當(dāng)源程序中需要多次使用同一個(gè)程序段時(shí),可以將該程序段定義為一個(gè)宏
? 格式:宏命令名 MACRO <形式參數(shù)>
┇
┇(省略掉的地方是宏體)
ENDM
形式參數(shù) 通過(guò)參數(shù)傳遞方式引用宏
宏定義與宏調(diào)用例
定義宏:
DADD MACRO X,Y,Z
MOV AX,X
ADD AX,Y
MOV Z,AX
ENDM
宏調(diào)用:
DADD DATA1,DATA2,SUM
匯編后源程序中的宏展開(kāi):
MOV AX,DATA1
? ADD AX,DATA2
? MOV SUM,AX
調(diào)整偏移量偽指令
規(guī)定程序或變量在邏輯段中的起始地址。
(默認(rèn)情況下,程序或變量在邏輯段中的起始偏移地址為0。利用ORG指令,可以改變)
格式: ORG 表達(dá)式 ? ?(表達(dá)式的計(jì)算值為非負(fù)常數(shù))
例:
DATA SEGMENT
ORG 1200H
BUFF DB 1,2; 變量BUFF的偏移地址=1200H
DATA ENDS
第39講 系統(tǒng)功能調(diào)用
BIOS、DOS功能調(diào)用
BIOS:駐留在ROM中的基本輸入/輸出系統(tǒng). 加電自檢,裝入引導(dǎo),主要I/O設(shè)備處理程序及接口控制
DOS:磁盤操作系統(tǒng)
DOS功能/BIOS功能調(diào)用是調(diào)用系統(tǒng)內(nèi)核子程序
DOS功能與BIOS功能均通過(guò)中斷方式調(diào)用,所以調(diào)用BIOS和調(diào)用DOS可以說(shuō)成BIOS中斷、DOS中斷
DOS軟中斷
DOS中斷包括:設(shè)備管理,目錄管理,文件管理,其它
用中斷類型碼區(qū)分
DOS軟中斷:類型碼為21H
關(guān)于DOS軟中斷說(shuō)明:
? 包含多個(gè)子功能的功能包;
? 各子功能用功能號(hào)區(qū)分;
? 用軟中斷指令調(diào)用,中斷類型碼固定為21H
DOS功能調(diào)用的基本步驟
將調(diào)用參數(shù)(入口參數(shù)/出口參數(shù))裝入指定的寄存器;
? 將功能號(hào)裝入AH;
? 按中斷類型號(hào)調(diào)用DOS中斷;
? 檢查返回參數(shù)是否正確。
? 調(diào)用格式:
MOV AH,功能號(hào)
<置相應(yīng)參數(shù)>
INT 21H
1. 單字符輸入
? 調(diào)用方法:
MOV AH,01
INT 21H
? 輸入的字符在AL中
例子
GET_KEY: MOV AH,1
INT 21H
CMP AL,’Y’;(交互式應(yīng)答程序)
JZ YES
CMP AL,’N’
JZ NO
JMP GET_KEY
YES: ┇
NO: ┇
2. 字符串輸入
? 接收由鍵盤輸入一串字符
? 輸入的字符串存儲(chǔ)在內(nèi)存指導(dǎo)區(qū)域中(字符輸入緩沖區(qū))
? 用戶自定義緩沖區(qū)格式:
? ? ? ?

? ? ? ?
(敲入的字符從第三個(gè)單元開(kāi)始放。存放鍵入的字符數(shù)比最大少一個(gè),ODH回車要占用一個(gè)字符位置)
?字符串輸入功能號(hào):10
?緩存區(qū)須定義在數(shù)據(jù)段
?方法:
AH 功能號(hào)
DS:DX 字符串在內(nèi)存中的存放地址。緩沖區(qū)必須定義在數(shù)據(jù)段,規(guī)定偏移地址必須送給DX
INT 21H
輸入字符串程序段
DAT1 DB 20,?,20 DUP(?); 在數(shù)據(jù)段中定義
┇
LEA DX,DAT1
MOV AH,0AH
INT 21H
輸入緩沖區(qū)
定義后的輸入緩沖區(qū)初始狀態(tài):(敲入的字符從第三個(gè)單元開(kāi)始放。20個(gè)字節(jié)只能輸入19個(gè)字符哦,因?yàn)榛剀?DH占一個(gè))
? ? ? ?

? ? ? ?
3. 單字符顯示輸出
AH 功能號(hào)2
DL 待輸出字符
INT 21H
例:
MOV AH,2
MOV DL,41H
INT 21H
執(zhí)行結(jié)果:屏幕顯示A
4. 字符串輸出顯示
AH 功能號(hào)09H
DS:DX 待輸出字符串的偏移地址
INT 21H
注意點(diǎn):
? 被顯示的字符串必須以‘$’結(jié)束;
? 所顯示的內(nèi)容不應(yīng)出現(xiàn)非可見(jiàn)的ASCII碼;
? 若考慮輸出格式需要,在定義字符串后,加上回車符和換行符。
字符串輸出顯示例
DATA SEGMENT
MESS1 DB ‘Input String:’, 0DH,0AH,’$’
DATA ENDS
CODE SEGMENT
┇
MOV AH,09
MOV DX,OFFSET MESS1
INT 21H
┇
(0DH回車 ?光標(biāo)會(huì)在字符后面閃爍
0AH換行
ODH 和0AH 下一行閃爍)
? ? ? ?

? ? ? ?
5. 返回操作系統(tǒng)(DOS)功能
? 功能號(hào): 4CH
? 調(diào)用格式:
MOV AH,4CH
INT 21H
? 功能:
? 程序執(zhí)行完該2條語(yǔ)句后能正常返回OS
? 常位于程序結(jié)尾處。
DOS功能調(diào)用小結(jié)
? 通過(guò)中斷指令調(diào)用。1個(gè)中斷類型碼對(duì)應(yīng)1個(gè)功能程序包;
? 每個(gè)程序包中的子功能通過(guò)功能號(hào)區(qū)分,調(diào)用時(shí)功能號(hào)須送AH;
? 注意不同子功能的入口/出口參數(shù)要求;
DOS和BIOS中斷均可能影響AX (需要用PUSH\POP保護(hù)數(shù)據(jù))
第40講 匯編語(yǔ)言程序設(shè)計(jì)示例詳解
實(shí)例4:
DATA SEGMENT
STR1 DB ‘HELLO WORLD!‘
STR2 DB ‘HELLO WOOLD!’
COUNT DW 12;16位
FLAG DB ?
DATA ENDS
CODE SEGMENT
ASSUME CS: CODE, DS: DATA, ES: DATA;DATA既是數(shù)據(jù)段又是邏輯段
START: MOV AX, DATA
MOV DS, AX
MOV ES, AX
LEA BX, FLAG
LEA SI, STR1
LEA DI, STR2
MOV CX,COUNT
CLD
REPE CMPSB
JZ NEXT1
MOV Byte PTR[BⅪ],00H
JMP STOP
NEXT1: MOV Byte PTR(BX], OFFH
STOP:……
問(wèn) 當(dāng)程序執(zhí)行到STOP時(shí)
SI\DU\CX\FLAG\ZF的值
SI=9,DI=0015H,CX=3,FLAG=0,ZF=0
開(kāi)始SI=0 DI=12=0CH
到R和O不同的位置是9次
SI=0+9=9
DI=12+9=21=0015H
遇到不同的,結(jié)果不為0,ZF=0
00H給了BX,FLAG=0
CX=12-9=3
? ? ? ?

? ? ? ?
實(shí)例5
DATA SEGMENT
SUM DB 8 DUP (0)
DATA ENDS
CODE SEGMENT
ASSUME CS: CODE, DS: DATA
START: MOV AX, DATA
MOV DS, AX
LEA BX, SUM
MOV DX, 380H
IN AL, DX
MOV CX, 8
NEXT: ROR AL, 1;不含CF的循環(huán)右移指令
JNC NEXT1
MOV Byte PTR[BX], 0FFH
JMP NEXT2
NEXT1: MOV Byte PTR [BX], 0
NEXT2: INC BX
LOOP NEXT
……
如果從380H端口輸入的是45H,則程序執(zhí)行完后:
BX=(8)
AL=(45H)
SUM0-SUM7的內(nèi)容是(FF,0,FF,0,0,0,FF,0)
AL=01000101 最低位存入CF,存入最高位 AL=10100010
因?yàn)镃F=1 JNC不會(huì)轉(zhuǎn)向NEXT1
[BX]的內(nèi)容FFH
NEXT2 BX+1
循環(huán)8次NEXT
去NEXT
CF=0,AL=01010001
跳到NEXT1
[BX]的內(nèi)容FFH
。。。
匯編語(yǔ)言程序設(shè)計(jì)小結(jié)
匯編語(yǔ)言程序設(shè)計(jì)一般步驟
? 根據(jù)實(shí)際問(wèn)題抽象出數(shù)學(xué)模型
? 確定算法
? 畫程序流程圖
? 分配內(nèi)存工作單元和寄存器
? 程序編碼
? 調(diào)試
內(nèi)容提要
? 匯編語(yǔ)言源程序的結(jié)構(gòu)
? 匯編語(yǔ)言語(yǔ)句---變量、表達(dá)式中的運(yùn)算符
? 偽指令
? DOS功能調(diào)用:5個(gè)子功能的應(yīng)用
? 簡(jiǎn)單匯編語(yǔ)言源程序的設(shè)計(jì)
注意點(diǎn)
? 變量的定義與應(yīng)用:明確所定義變量在內(nèi)存中的分布
? 存儲(chǔ)區(qū)的定義:不能定義沒(méi)有變量的存儲(chǔ)區(qū)
? 完整的匯編語(yǔ)言源程序結(jié)構(gòu):定義邏輯段,說(shuō)明段的含義,初始化段寄存器
? 偽指令:數(shù)據(jù)定義方式
? 字符及字符串的輸入和顯示輸出:字符輸入緩沖區(qū)的定義,輸出字符串的定義
? 匯編語(yǔ)言程序結(jié)構(gòu):順序結(jié)構(gòu)、循環(huán)結(jié)構(gòu)(使用LOOP指令或條件轉(zhuǎn)移指令實(shí)現(xiàn)) 、分支結(jié)構(gòu)(一般用條件轉(zhuǎn)移指令實(shí)現(xiàn))
? 子程序結(jié)構(gòu):子程序的定義和調(diào)用方式
例:
? 定義20B的字符輸入緩沖區(qū)BUFF以及20B的字節(jié)變量DATA;
? 顯示字符串輸入提示信息,然后從鍵盤接收字符‘Hello,my friends!’;
? 將BUFFER中的字符串按從左到右的方向傳送到DATA中。
分析:
字符串顯示輸出 字符串輸入 串操作指令
DSEG SEGMENT
MESS DB ‘Please input string:’,0DH,0AH,’$’
BUFF DB 20,?,20 DUP (?)
DATA DB 20 Dup(?)
DSEG ENDS
CSEG SEGMENT
ASSUME CS:CSEG,DS:DSEG,ES:ESEG
START:MOV AX,DSEG
MOV DS,AX
MOV ES,AX
AGAIN:LEA DX,MESS
?MOV AH,9
?INT 21H
LEA DX,BUFF
MOV AH,10
INT 21H
XOR CX,CX
MOV CL,BUFF+1;BUFF+1的地址是存放放字符串實(shí)際長(zhǎng)度值的單元
LEA DI,DATA
LEA SI,BUFF+2;開(kāi)始存字符串內(nèi)容的地方
CLD
REP MOVSB
MOV AH,4CH
INT 21H
CSEG ENDS
END SATRT