第三节 指示性语句 / 第四节 汇编语言程序举例一,程序开始和结束二,段定义三,变量定义四,ASSUME语句 // 第 7次课
一个完整汇编程序举例了解 DOS的返回,装入功能五,表达式及表达式中的操作符
汇编语言程序例一 完整汇编结构六,过程定义 (第六节程序设计介绍 )
七,等值定义 (第六节程序设计介绍 )
汇编语言程序例二 (第六节程序设计介绍 )
一个 完整的汇编语言程序 举例例 将 BL寄存器的内容按二进制形式显示出来
1 0 1 0 0 1 1 0(BL)
MOV CX,8 ;显示字符个数为 8
next,SHL BL,1 ;将显示位移至 CF中
JC one ;CF=1?
MOV DL,30H ;CF=0,将 0的 ASCII放在 DL中
JMP exit
one,MOV DL,31H ;CF=1,将 1的 ASCII放在 DL中
exit,MOV AH,2
INT 21H ;调用 DOS功能显示
DEC CX ;循环次数减 1
JNZ next ;判断是否结束
、、、
31 30 31 30 30 31 31 30
第二章 介绍过的程序段:
code SEGMENT
ASSUME CS,code
start:
...
...
...
...
code ENDS
END start
MOV CX,8 ;显示字符个数为 8
next,SHL BL,1 ;将显示位移至 CF中
JC one ;CF=1?
MOV DL,30H ;CF=0,将 0的 ASCII放在 DL中
JMP exit
one,MOV DL,31H ;CF=1,将 1的 ASCII放在 DL中
exit,MOV AH,2
INT 21H ;调用 DOS功能显示
DEC CX ;循环次数减 1
JNZ next ;判断是否结束
D:\>MASM SBL;? 汇编成 ShowBL.obj
Microsoft (R) Macro Assembler Version 5.10
Copyright (C) Microsoft Corp 1981,1988,All rights reserved.
48912 + 447243 Bytes symbol space free
0 Warning Errors
0 Severe Errors
D:\>LINK SBL;? 连接成 ShowBL.exe
Microsoft (R) Overlay Linker Version 3.61
Copyright (C) Microsoft Corp 1983-1987,All rights reserved.
LINK,warning L4021,no stack segment
D:\>SBL? 装载并执行 ShowBL.exe
请猜想执行的结果?
D:\>DEBUG SBL.exe? ;用 DEBUG装入程序
-U?
0B5E:0000 B90800 MOV CX,0008
0B5E:0003 D0E3 SHL BL,1
0B5E:0005 7205 JB 000C
0B5E:0007 B230 MOV DL,30
0B5E:0009 EB03 JMP 000E
0B5E:000B 90 NOP
0B5E:000C B231 MOV DL,31
0B5E:000E B402 MOV AH,02
0B5E:0010 CD21 INT 21
0B5E:0012 49 DEC CX
0B5E:0013 75EE JNZ 0003
0B5E:0015 09E8 OR AX,BP
0B5E:0017 96 XCHG SI,AX
0B5E:0018 00F8 ADD AL,BH
0B5E:001A B262 MOV DL,62
0B5E:001C FFFF DI
0B5E:001D EB0A JMP 0029
-
hello.exe
用户程序与用户程序相连的内存内容被看作程序时死机
▲ 复习 DOS系统的启动过程执行用户程序后,
若要返回 DOS状态,
即在屏幕上出现 DOS提示符,
等待输入新的命令,
应在用户程序的最后安排完成此功能的程序段 。
FF FF,0000 H
1
2
4
3
ROM
系统检测程序
IO,SY S 模块
COM MAN D,CO M
MS DOS,SY S 模块用户程序空 间引导程序
1K B 中断向量表
RA M
内 存
ROM BIO S
DO S
IO,SY S
COM MAN D,CO M
MS DOS,SY S
引导程序磁 盘
EDIT,EX E
MA SM,EX E
LINK,E XE
DE BUG.e x e
应用程序其他系统程序
he llo,asm
he llo,obj
he llo,exe
通常采用调用
DOS 系统功能完成 。
调用 DOS系统的 4CH 功能,返回 DOS
方法,在要返回 DOS 处,安排指令:
MOV AH,4CH
INT 21H
执行完 4CH的功能调用,即返回 DOS 。
例 code SEGMENT
ASSUME CS,code
start:,、,;程序主体部分
、、、
、、、
MOV AH,4CH ;返回 DOS
INT 21H
code ENDS
END start
code SEGMENT
ASSUME CS,code
start:
...
...
...
...
MOV AH,4CH ;返回 DOS
INT 21H
code ENDS
END start
MOV CX,8 ;显示字符个数为 8
next,SHL BL,1 ;将显示位移至 CF中
JC one ;CF=1?
MOV DL,30H ;CF=0,将 0的 ASCII放在 DL中
JMP exit
one,MOV DL,31H ;CF=1,将 1的 ASCII放在 DL中
exit,MOV AH,2
INT 21H ;调用 DOS功能显示
DEC CX ;循环次数减 1
JNZ next ;判断是否结束
MOV BL,53H ;设置一个测试 53h
D:\>MASM ShowBL; 汇编成 ShowBL.obj
Microsoft (R) Macro Assembler Version 5.10
Copyright (C) Microsoft Corp 1981,1988,All rights reserved.
48912 + 447243 Bytes symbol space free
0 Warning Errors
0 Severe Errors
D:\>LINK ShowBL; 连接成 ShowBL.exe
Microsoft (R) Overlay Linker Version 3.61
Copyright (C) Microsoft Corp 1983-1987,All rights reserved.
LINK,warning L4021,no stack segment
D:\>ShowBL 装载并执行 ShowBL.exe
01010011
D:\masm>
D:\>DEBUG ShowBL.exe? ;用 DEBUG装入程序
-U?
0B5E:0000 B90800 MOV CX,0008
0B5E:0003 D0E3 SHL BL,1
0B5E:0005 7205 JB 000C
0B5E:0007 B230 MOV DL,30
0B5E:0009 EB03 JMP 000E
0B5E:000B 90 NOP
0B5E:000C B231 MOV DL,31
0B5E:000E B402 MOV AH,02
0B5E:0010 CD21 INT 21
0B5E:0012 49 DEC CX
0B5E:0013 75EE JNZ 0003
0B5F:0015 B44C MOV AH,4C
0B5F:0017 CD21 INT 21
-
code SEGMENT
ASSUME CS,code
start:
… ;程序主体部分
...
...
...
MOV AH,4CH ;返回 DOS
INT 21H
code ENDS
END start
一个完整汇编程序的基本框架,
DOS的装入功能 (又称 EXEC系统功能 )
可执行文件,exe,应装入内存方能执行 。
由 DOS的装入功能完成 。
在 DOS的提示符后输入可执行文件的文件名,
按回车键,DOS系统即调用装入功能,
将可执行程序装入内存 。
内 存
256K B RO M
000 0,0000H
004 0,0000H
A000:0000H
C800:0000H
FE00:0000H
FE00:1FFF H
640K B R AM
基本内存显示器显示缓存区
ROM BIO S
系统检测程序
IO,SY S 模块
CO MMAND,CO M 常驻 模块
MS DOS,SY S 模块用户程序空间
CO MMAND,CO M 暂驻 模块
DO S 工作区
BIO S 工作区
1K B 中断向量表
128K B R AM
保留区
DO S
其他系统程序磁 盘应用程序
IO,SY S
COM MAN D,CO M
MS DOS,SY S
引导程序
EDIT,EX E
MA SM,EX E
LINK,E XE
DE BUG.e x e
hel lo.asm
hel lo.o bj
hel lo.e xe
sc ans.asm
sc ans.obj
sc ans.e xe
完成以下操作:
确定内存可用部分,
以便存放要执行的,exe 文件。
建立程序段前缀 PSP
( Program Segment Prefix)
◢ 程序段前缀大小 100H,
即 256个字节。
◢ 存放进程间的控制信息。
◢ PSP最开始的两个字节 CD 20,
是一条 INT 20H指令。
装入可执行程序,exe
000 0,0 000H
可用内存空间内 存
FF FF,0 00 0 H
ROM BIO S
系统检测程序
COM M AN D,COM
DO S 系统
1K B 中断向量表
CD 20
,、、
,、、
,、、
hel lo,exe
xxx x,0 000H
xxx x,0 0FFH
程序段前缀用户程序
DOS的装入功能
修改以下寄存器的值
◢ DS,ES设置为程序段前缀所在内存的段值;
(DS)=xxxxH
(ES)=xxxxH
◢ SS,SP设置为由连接程序传过来的值;
◢ CS,IP设置为程序的入口地址,
即伪操作 END后跟的符号名对应的物理地址;
此时 CS:IP 指向用户程序,
开始执行用户程序 。
000 0,0 000H
可用内存空间内 存
FF FF,0 00 0 H
ROM BIO S
系统检测程序
COM M AN D,COM
DO S 系统
1K B 中断向量表
CD 20
,、、
,、、
,、、
hel lo,exe
xxx x,0 000H
xxx x,0 0FFH
程序段前缀
CS,I P
D:\>DEBUG ShowBL.exe
-R? ;查看当前寄存器内容
AX=0000 BX=0000 CX=001B DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B51 ES=0B51 SS=0B61 CS=0B61 IP=0000 NV UP EI PL NZ NA PO NC
0B61:0000 B353 MOV BL,53
-U? ;查看程序代码
0B61:0000 B353 MOV BL,53
0B61:0002 B90800 MOV CX,0008
…...
0B61:0017 B44C MOV AH,4C
0B61:0019 CD21 INT 21
-D DS:0 L20? ;查看此时数据段内容 (程序段前缀 )
0B51:0000 CD 20 FF 9F 00 9A F0 FE-1D F0 4F 03 5A 05 8A 03
0B51:0010 5A 05 17 03 5A 05 49 05-01 01 01 00 02 FF FF FF
-U DS:0 L5? ;反汇编当前数据段内容 (程序段前缀 )
0B51:0000 CD20 INT 20
0B51:0002 FF9F009A CALL FAR [BX+9A00]
-
在 DEBUG下查看 ShowBL.exe的装入情况,
-R? ;查看当前寄存器内容
AX=0000 BX=0000 CX=001B DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B51 ES=0B51 SS=0B61 CS=0B61 IP=0000 NV UP EI PL NZ NA PO NC
B353 MOV BL,53
- U CS:0? ;查看程序
0B61:0000 B353 MOV BL,53
0B61:0002 B90800 MOV CX,0008
0B61:0005 D0E3 SHL BL,1
0B61:0007 7205 JB 000E
…….
0B61:0017 B44C MOV AH,4C
0B61:0019 CD21 INT 21
…….
-G? ;执行程序
01010011
Program terminated normally
-
注意:
不能破坏程序段前缀内容,
否则无法返回 DOS,造成死机 。
讲义中介绍的第二种返回 DOS的方法 不作学习要求 。
(在老的教材或参考书中使用该法,新版的书中很少使用,
新版的教材 P98的例程可以不看,采用的是第二种方法 )。
想要掌握的同学可自学。
第二种 DOS返回方法,调用 20H类型的中断程序
◢ 20H 中断程序的功能:
处理程序结束,返回系统 。
◢ 调用 20H中断程序是有条件的:
要求当前的 CS应为程序段前缀在内存的段值问题:
如何保证执行到 INT 20H时,
当前 CS的值为程序段前缀在内存的段值?
xxxx,00 00 INT 20
采用下面的程序框架,
可保证执行 INT 20H时,
当前的 CS值为程序段前缀在内存的段值 。
code SEGMENT
ASSUME CS:code
main PROC FAR ;使 RET为远返回
start,PUSH DS ;入栈保存地址
MOV AX,0 ;程序段前缀的首地址
PUSH AX
、,;程序主体部分
、、
RET ;取程序段前缀首地址
main ENDP
code ENDS
END start
CD 20
xxxx
,、、
0000
xxxx,0
SS:S P
SS:S P
程序段前缀 P S P
PS P 的段值
PS P 的偏值用户程序
CS IP
注意:
1,不可在汇编语言程序的最后用 INT 20H返回 DOS。
原因是 20h中断子程的执行是有条件的 。
采用第二种返回 DOS的程序结构,才能满足该条件,
否则无法返回 。
2,不可在程序的最后用 INT 3返回 DOS。
原因是 3类型的中断子程实现断点设置,
只在 DEBUG下起作用 。
五,表达式及表达式中的操作符表达式
由常量,标号,变量和一些操作符构成 。
汇编程序对表达式进行运算后,得到一个确定的数值,
再把这个数值汇编到指令中 。
据表达式所表示的内容,分数字表达式,地址表达式 。
表达式是指令或伪操作的操作数 ;
表达式中的操作符由汇编程序完成例 MOV AX,12 - 4 ;MOV AX,8 ;数字表达式
LEA BX,[ string + 4 ] ;地址表达式表达式中的操作符
▲ 有以下几类,
1,算术运算符 ( +,-,*,/,MOD )
2,逻辑运算符 ( AND,OR,NOT,XOR )
3,关系运算符 ( EQ,NE,GT,GE,LT,LE )
真,FFFFH; 假,0
4,数值返回操作符 ( SEG,OFFSET )
5,类型操作 ( PTR )
6,地址记数器 ( $ )
例,
1,算术运算符 ( +,-,*,/,MOD(取余数 ) )
MOV AX,6 * 8 ← MOV AX,48
2,逻辑运算符 (AND,OR,NOT,XOR)
MOV AX,80h OR 70h ← MOV AX,0F0h
3,关系运算符 ( EQ,NE,GT,GE,LT,LE )
真,FFFFH; 假,0
MOV AX,1 GE 2 ← MOV AX,0
4,数值返回操作符 ( SEG,OFFSET )
SEG 取符号地址的段地址例 MOV AX,SEG yy
OFFSET 取符号地址的偏移地址例 MOV BX,OFFSET yy
bb SEGMENT
yy DB 6 dup (?)
bb ENDS
cc SEGMENT
ASSUME CS:cc,DS:aa,ES:bb
start,CLD
MOV AX,SEG yy
MOV ES,AX
MOV DI,OFFSET yy
MOV CX,6
……,
cc ENDS
END start
aa SEGMENT
xx DB 'Hello!’
aa ENDS
bb SEGMENT
yy DB 6 dup (?)
bb ENDS
cc SEGMENT
ASSUME CS:cc,DS:aa,ES:bb
start,CLD
MOV AX,aa
MOV DS,AX
LEA SI,xx
MOV AX,SEG yy
MOV ES,AX
MOV DI,OFFSET yy
MOV CX,6
REP MOVSB
MOV AH,4CH
INT 21H
cc ENDS
END start
D:\>DEBUG hello1.exe
-U ;查看程序代码
129F:0000 FC CLD
129F:0001 B89D12 MOV AX,129D
129F:0004 8ED8 MOV DS,AX
129F:0006 8D360000 LEA SI,[ 0000 ]
129F:000A B89E12 MOV AX,129E
129F:000D 8EC0 MOV ES,AX
129F:000F BF0000 MOV DI,0000
129F:0012 B90600 MOV CX,0006
129F:0015 F3 REPZ
129F:0016 A4 MOVSB
129F:0017 B44C MOV AH,4C
129F:0019 CD21 INT 21
、、、、、、
MOV AX,bb
LEA DI,yy
注意,SEG,OFFSET只能对符号地址操作
MOV AX,SEG [BX]
MOV BX,OFFSET [SI]
汇编语言程序举例 (第三节例一 )
(实验二 编程任务 4)
编写完整汇编语言程序,完成内存数据块传送功能 。
将某段中的字符串,Hello!”传送到另一段中 。
例一 编写完整汇编语言程序,完成内存数据块传送功能 。
将某段中的字符串,Hello!”传送到另一段中 。
开始建立传送方向
DS,SI ← 源串首地址
ES,DI ←目的串首地址
CX ← 串长度串传送返回 D O S
利用变量定义字符串和缓冲区
aa SEGMENT ; 数据段 1
xx DB 'Hello!’ ; 定义源串
aa ENDS
bb SEGMENT ;数据段 2
yy DB 6 dup (?) ; 定义目的缓冲区
bb ENDS
cc SEGMENT ;代码段
ASSUME CS:cc,DS:aa,ES:bb ;指示指令中标号,变量所在段
start,CLD ;设置传送方向
MOV AX,aa ;DS,SI ← 源串首地址
MOV DS,AX
LEA SI,xx
MOV AX,SEG yy ;ES,DI← 目的首地址
MOV ES,AX
MOV DI,OFFSET yy
MOV CX,6 ;CX ← 串的长度
REP MOVSB ;串传送
MOV AH,4CH ;调用 4CH系统功能,返回 DOS
INT 21H
cc ENDS
END start ;指示程序结束和程序入口
D:\>EDIT hello.asm ;编写源程序
D:\>MASM hello ; ;汇编源程序
Microsoft (R) Macro Assembler Version 5.10
Copyright (C) Microsoft Corp 1981,1988,All rights reserved.
49860 + 421241 Bytes symbol space free
0 Warning Errors
0 Severe Errors
D:\>LINK hello ; ;连接程序
Microsoft (R) Overlay Linker Version 3.61
Copyright (C) Microsoft Corp 1983-1987,All rights reserved.
LINK,warning L4021,no stack segment
D:\>hello ;执行程序
D:\>
警告性错误:无堆栈段此错误可忽略
D:\>DEBUG hello.exe? ;利用 DEBUG查看结果
-U? ;查看程序代码
129F:0000 FC CLD
129F:0001 B89D12 MOV AX,129D
129F:0004 8ED8 MOV DS,AX
129F:0006 8D360000 LEA SI,[ 0000 ]
129F:000A B89E12 MOV AX,129E
129F:000D 8EC0 MOV ES,AX
129F:000F BF0000 MOV DI,0000
129F:0012 B90600 MOV CX,0006
129F:0015 F3 REPZ
129F:0016 A4 MOVSB
129F:0017 B44C MOV AH,4C
129F:0019 CD21 INT 21
、、、、、、
-D 129D:0 L20? ;执行程序前,查看源串内容
129D:0000 48 65 6C 6C 6F 21 00 00-00 00 00 00 00 00 00 00 Hello!..........
129D:0010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00,...............
-D 129E:0 L20? ;执行程序前,查看目的串
129E:0000 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00,...............
129E:0010 FC B8 9D 12 8E D8 8D 36-00 00 B8 9E 12 8E C0 BF,......6........
-
CLD
MOV AX,aa
MOV DS,AX
LEA SI,xx
MOV AX,SEG yy
MOV ES,AX
MOV DI,OFFSET
yy
MOV CX,6
REP MOVSB
MOV AH,4CH
INT 21H
-G ; 执行程序
Program terminated normally
-D 129E,0 L20 ; 查看目的串
129E:0000 48 65 6C 6C 6F 21 00 00-00 00 00 00 00 00 00 00 Hello!..........
129E:0010 FC B8 9D 12 8E D8 8D 36-00 00 B8 9E 12 8E C0 BF,......6........
-D 129D,0 L50 ; 从源串重新查看
129D:0000 48 65 6C 6C 6F 21 00 00-00 00 00 00 00 00 00 00 Hello!..........
129D:0010 48 65 6C 6C 6F 21 00 00-00 00 00 00 00 00 00 00 Hello!..........
129D:0020 FC B8 9D 12 8E D8 8D 36-00 00 B8 9E 12 8E C0 BF,......6........
129D:0030 00 00 B9 06 00 F3 A4 B4-4C CD 21 09 E8 08 00 03,.......L.!.....
129D:0040 F1 E8 03 00 3C 0D C3 AC-E8 EC F8 75 04 3C 3B 75,...<......u.<;u
-
问题思考,(实验课上讨论 )
1,一个段的大小为多少? 一定是 64K吗?
根据 DEBUG下查看的结果,
画出程序各段在内存的存放情况 。
2,假如将程序中的 MOV CX,6 改为 MOV CX,100H
程序执行的结果会如何? 试用 DEBUG观察结果 。
-U? ;查看程序代码
129F:0000 FC CLD
129F:0001 B89D12 MOV AX,129D
129F:0004 8ED8 MOV DS,AX
129F:0006 8D360000 LEA SI,[ 0000 ]
129F:000A B89E12 MOV AX,129E
129F:000D 8EC0 MOV ES,AX
129F:000F BF0000 MOV DI,0000
129F:0012 B90600 MOV CX,0006
129F:0015 F3 REPZ
129F:0016 A4 MOVSB
129F:0017 B44C MOV AH,4C
129F:0019 CD21 INT 21
、、、、、、
aa SEGMENT
xx DB 'Hello!’
aa ENDS
bb SEGMENT
yy DB 6 dup (?)
bb ENDS
cc SEGMENT
ASSUME CS:cc,DS:aa,ES:bb
start,CLD
MOV AX,aa
MOV DS,AX
LEA SI,xx
MOV AX,SEG yy
MOV ES,AX
MOV DI,OFFSET yy
MOV CX,6
REP MOVSB
MOV AH,4CH
INT 21H
cc ENDS
END start
3,可否在程序结束处用一条 RET返回指令,返回 DOS?
(实验课上讨论 )
aa SEGMENT ; 数据段 1
xx DB 'Hello!’ ; 定义源串
aa ENDS
bb SEGMENT ;数据段 2
yy DB 6 dup (?) ; 定义目的缓冲区
bb ENDS
cc SEGMENT ;代码段
ASSUME CS:cc,DS:aa,ES:bb ;指示指令中标号,变量所在段
start,CLD ;设置传送方向
MOV AX,aa ;DS,SI ← 源串首地址
MOV DS,AX
LEA SI,xx
MOV AX,SEG yy ;ES,DI ← 目的首地址
MOV ES,AX
MOV DI,OFFSET yy
MOV CX,6 ;CX ← 串的长度
REP MOVSB ;串传送
RET
cc ENDS
END start ;指示程序结束和程序入口
D:\>DEBUG hello.exe
- U
129F:0000 FC CLD
129F:0001 B89D12 MOV AX,129D
129F:0004 8ED8 MOV DS,AX
129F:0006 8D360000 LEA SI,[0000]
129F:000A B89E12 MOV AX,129E
129F:000D 8EC0 MOV ES,AX
129F:000F BF0000 MOV DI,0000
129F:0012 B90600 MOV CX,0006
129F:0015 F3 REPZ
129F:0016 A4 MOVSB
129F:0017 F3 RET
129F:0018 43 INC BX
129F:0019 50 PUSH AX
129F:001A FF36C601 PUSH [01C6]
、、、
-
hello.exe
用户程序与用户程序相连的内存内容被看作程序时
4,END 语句后没有起始地址,程序执行的后果?
(实验课上讨论 )
aa SEGMENT ; 数据段 1
xx DB 'Hello!’ ; 定义源串
aa ENDS
bb SEGMENT ;数据段 2
yy DB 6 dup (?) ; 定义目的缓冲区
bb ENDS
cc SEGMENT ;代码段
ASSUME CS:cc,DS:aa,ES:bb ;指示指令中标号,变量所在段
start,CLD ;设置传送方向
MOV AX,aa ;DS,SI ← 源串首地址
MOV DS,AX
LEA SI,xx
MOV AX,SEG yy ;ES,DI ← 目的首地址
MOV ES,AX
MOV DI,OFFSET yy
MOV CX,6 ;CX ← 串的长度
REP MOVSB ;串传送
MOV AH,4CH ;调用 4CH系统功能,返回 DOS
INT 21H
cc ENDS
END ; start ;指示程序结束和程序入口
5,如下操作为何查看不到结果?
(实验课上讨论 )
D:\>MASM hello; ;汇编源程序
D:\>LINK hello; ;连接程序
D:\>hello ;先在 DOS下运行程序
D:\>DEBUG ;再进入 DEBUG查看结果
- D 129E:0 L30 ;查看目的串
129E:0000 2A 75 05 80 0E 2D DA 02-3A 06 14 D4 75 C9 4E 32 *u...-..:...u.N2
129E:0010 C0 86 04 46 3C 0D 75 02-88 04 89 36 EB D8 89 0E,..F<.u....6....
129E:0020 E9 D8 C3 BE CE DC 8B 4C-05 8B 74 09 E8 08 00 03,......L..t.....
-D 129D:0 L30 ;查看源串
129D:0000 75 04 FE 06 29 DA 3C 3F-75 05 80 0E 2D DA 02 3C u...).<?u...-..<
129D:0010 2A 75 05 80 0E 2D DA 02-3A 06 14 D4 75 C9 4E 32 *u...-..:...u.N2
129D:0020 C0 86 04 46 3C 0D 75 02-88 04 89 36 EB D8 89 0E,..F<.u....6....
data1 SEGMENT ;数据段 1,(可据需要设定,也可无 )
…… ;变量定义
data1 ENDS
data2 SEGMENT ;数据段 2 (可据需要设定,也可无 )
……
data2 ENDS
code SEGMENT ;程序段
ASSUME CS,code,DS:data1,ES:data2
start:,、,;程序主体部分
、、、
、、、
、、、
MOV AH,4CH ;返回 DOS
INT 21H
code ENDS
END start
完整汇编语言程序框架:
一个完整汇编程序举例了解 DOS的返回,装入功能五,表达式及表达式中的操作符
汇编语言程序例一 完整汇编结构六,过程定义 (第六节程序设计介绍 )
七,等值定义 (第六节程序设计介绍 )
汇编语言程序例二 (第六节程序设计介绍 )
一个 完整的汇编语言程序 举例例 将 BL寄存器的内容按二进制形式显示出来
1 0 1 0 0 1 1 0(BL)
MOV CX,8 ;显示字符个数为 8
next,SHL BL,1 ;将显示位移至 CF中
JC one ;CF=1?
MOV DL,30H ;CF=0,将 0的 ASCII放在 DL中
JMP exit
one,MOV DL,31H ;CF=1,将 1的 ASCII放在 DL中
exit,MOV AH,2
INT 21H ;调用 DOS功能显示
DEC CX ;循环次数减 1
JNZ next ;判断是否结束
、、、
31 30 31 30 30 31 31 30
第二章 介绍过的程序段:
code SEGMENT
ASSUME CS,code
start:
...
...
...
...
code ENDS
END start
MOV CX,8 ;显示字符个数为 8
next,SHL BL,1 ;将显示位移至 CF中
JC one ;CF=1?
MOV DL,30H ;CF=0,将 0的 ASCII放在 DL中
JMP exit
one,MOV DL,31H ;CF=1,将 1的 ASCII放在 DL中
exit,MOV AH,2
INT 21H ;调用 DOS功能显示
DEC CX ;循环次数减 1
JNZ next ;判断是否结束
D:\>MASM SBL;? 汇编成 ShowBL.obj
Microsoft (R) Macro Assembler Version 5.10
Copyright (C) Microsoft Corp 1981,1988,All rights reserved.
48912 + 447243 Bytes symbol space free
0 Warning Errors
0 Severe Errors
D:\>LINK SBL;? 连接成 ShowBL.exe
Microsoft (R) Overlay Linker Version 3.61
Copyright (C) Microsoft Corp 1983-1987,All rights reserved.
LINK,warning L4021,no stack segment
D:\>SBL? 装载并执行 ShowBL.exe
请猜想执行的结果?
D:\>DEBUG SBL.exe? ;用 DEBUG装入程序
-U?
0B5E:0000 B90800 MOV CX,0008
0B5E:0003 D0E3 SHL BL,1
0B5E:0005 7205 JB 000C
0B5E:0007 B230 MOV DL,30
0B5E:0009 EB03 JMP 000E
0B5E:000B 90 NOP
0B5E:000C B231 MOV DL,31
0B5E:000E B402 MOV AH,02
0B5E:0010 CD21 INT 21
0B5E:0012 49 DEC CX
0B5E:0013 75EE JNZ 0003
0B5E:0015 09E8 OR AX,BP
0B5E:0017 96 XCHG SI,AX
0B5E:0018 00F8 ADD AL,BH
0B5E:001A B262 MOV DL,62
0B5E:001C FFFF DI
0B5E:001D EB0A JMP 0029
-
hello.exe
用户程序与用户程序相连的内存内容被看作程序时死机
▲ 复习 DOS系统的启动过程执行用户程序后,
若要返回 DOS状态,
即在屏幕上出现 DOS提示符,
等待输入新的命令,
应在用户程序的最后安排完成此功能的程序段 。
FF FF,0000 H
1
2
4
3
ROM
系统检测程序
IO,SY S 模块
COM MAN D,CO M
MS DOS,SY S 模块用户程序空 间引导程序
1K B 中断向量表
RA M
内 存
ROM BIO S
DO S
IO,SY S
COM MAN D,CO M
MS DOS,SY S
引导程序磁 盘
EDIT,EX E
MA SM,EX E
LINK,E XE
DE BUG.e x e
应用程序其他系统程序
he llo,asm
he llo,obj
he llo,exe
通常采用调用
DOS 系统功能完成 。
调用 DOS系统的 4CH 功能,返回 DOS
方法,在要返回 DOS 处,安排指令:
MOV AH,4CH
INT 21H
执行完 4CH的功能调用,即返回 DOS 。
例 code SEGMENT
ASSUME CS,code
start:,、,;程序主体部分
、、、
、、、
MOV AH,4CH ;返回 DOS
INT 21H
code ENDS
END start
code SEGMENT
ASSUME CS,code
start:
...
...
...
...
MOV AH,4CH ;返回 DOS
INT 21H
code ENDS
END start
MOV CX,8 ;显示字符个数为 8
next,SHL BL,1 ;将显示位移至 CF中
JC one ;CF=1?
MOV DL,30H ;CF=0,将 0的 ASCII放在 DL中
JMP exit
one,MOV DL,31H ;CF=1,将 1的 ASCII放在 DL中
exit,MOV AH,2
INT 21H ;调用 DOS功能显示
DEC CX ;循环次数减 1
JNZ next ;判断是否结束
MOV BL,53H ;设置一个测试 53h
D:\>MASM ShowBL; 汇编成 ShowBL.obj
Microsoft (R) Macro Assembler Version 5.10
Copyright (C) Microsoft Corp 1981,1988,All rights reserved.
48912 + 447243 Bytes symbol space free
0 Warning Errors
0 Severe Errors
D:\>LINK ShowBL; 连接成 ShowBL.exe
Microsoft (R) Overlay Linker Version 3.61
Copyright (C) Microsoft Corp 1983-1987,All rights reserved.
LINK,warning L4021,no stack segment
D:\>ShowBL 装载并执行 ShowBL.exe
01010011
D:\masm>
D:\>DEBUG ShowBL.exe? ;用 DEBUG装入程序
-U?
0B5E:0000 B90800 MOV CX,0008
0B5E:0003 D0E3 SHL BL,1
0B5E:0005 7205 JB 000C
0B5E:0007 B230 MOV DL,30
0B5E:0009 EB03 JMP 000E
0B5E:000B 90 NOP
0B5E:000C B231 MOV DL,31
0B5E:000E B402 MOV AH,02
0B5E:0010 CD21 INT 21
0B5E:0012 49 DEC CX
0B5E:0013 75EE JNZ 0003
0B5F:0015 B44C MOV AH,4C
0B5F:0017 CD21 INT 21
-
code SEGMENT
ASSUME CS,code
start:
… ;程序主体部分
...
...
...
MOV AH,4CH ;返回 DOS
INT 21H
code ENDS
END start
一个完整汇编程序的基本框架,
DOS的装入功能 (又称 EXEC系统功能 )
可执行文件,exe,应装入内存方能执行 。
由 DOS的装入功能完成 。
在 DOS的提示符后输入可执行文件的文件名,
按回车键,DOS系统即调用装入功能,
将可执行程序装入内存 。
内 存
256K B RO M
000 0,0000H
004 0,0000H
A000:0000H
C800:0000H
FE00:0000H
FE00:1FFF H
640K B R AM
基本内存显示器显示缓存区
ROM BIO S
系统检测程序
IO,SY S 模块
CO MMAND,CO M 常驻 模块
MS DOS,SY S 模块用户程序空间
CO MMAND,CO M 暂驻 模块
DO S 工作区
BIO S 工作区
1K B 中断向量表
128K B R AM
保留区
DO S
其他系统程序磁 盘应用程序
IO,SY S
COM MAN D,CO M
MS DOS,SY S
引导程序
EDIT,EX E
MA SM,EX E
LINK,E XE
DE BUG.e x e
hel lo.asm
hel lo.o bj
hel lo.e xe
sc ans.asm
sc ans.obj
sc ans.e xe
完成以下操作:
确定内存可用部分,
以便存放要执行的,exe 文件。
建立程序段前缀 PSP
( Program Segment Prefix)
◢ 程序段前缀大小 100H,
即 256个字节。
◢ 存放进程间的控制信息。
◢ PSP最开始的两个字节 CD 20,
是一条 INT 20H指令。
装入可执行程序,exe
000 0,0 000H
可用内存空间内 存
FF FF,0 00 0 H
ROM BIO S
系统检测程序
COM M AN D,COM
DO S 系统
1K B 中断向量表
CD 20
,、、
,、、
,、、
hel lo,exe
xxx x,0 000H
xxx x,0 0FFH
程序段前缀用户程序
DOS的装入功能
修改以下寄存器的值
◢ DS,ES设置为程序段前缀所在内存的段值;
(DS)=xxxxH
(ES)=xxxxH
◢ SS,SP设置为由连接程序传过来的值;
◢ CS,IP设置为程序的入口地址,
即伪操作 END后跟的符号名对应的物理地址;
此时 CS:IP 指向用户程序,
开始执行用户程序 。
000 0,0 000H
可用内存空间内 存
FF FF,0 00 0 H
ROM BIO S
系统检测程序
COM M AN D,COM
DO S 系统
1K B 中断向量表
CD 20
,、、
,、、
,、、
hel lo,exe
xxx x,0 000H
xxx x,0 0FFH
程序段前缀
CS,I P
D:\>DEBUG ShowBL.exe
-R? ;查看当前寄存器内容
AX=0000 BX=0000 CX=001B DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B51 ES=0B51 SS=0B61 CS=0B61 IP=0000 NV UP EI PL NZ NA PO NC
0B61:0000 B353 MOV BL,53
-U? ;查看程序代码
0B61:0000 B353 MOV BL,53
0B61:0002 B90800 MOV CX,0008
…...
0B61:0017 B44C MOV AH,4C
0B61:0019 CD21 INT 21
-D DS:0 L20? ;查看此时数据段内容 (程序段前缀 )
0B51:0000 CD 20 FF 9F 00 9A F0 FE-1D F0 4F 03 5A 05 8A 03
0B51:0010 5A 05 17 03 5A 05 49 05-01 01 01 00 02 FF FF FF
-U DS:0 L5? ;反汇编当前数据段内容 (程序段前缀 )
0B51:0000 CD20 INT 20
0B51:0002 FF9F009A CALL FAR [BX+9A00]
-
在 DEBUG下查看 ShowBL.exe的装入情况,
-R? ;查看当前寄存器内容
AX=0000 BX=0000 CX=001B DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B51 ES=0B51 SS=0B61 CS=0B61 IP=0000 NV UP EI PL NZ NA PO NC
B353 MOV BL,53
- U CS:0? ;查看程序
0B61:0000 B353 MOV BL,53
0B61:0002 B90800 MOV CX,0008
0B61:0005 D0E3 SHL BL,1
0B61:0007 7205 JB 000E
…….
0B61:0017 B44C MOV AH,4C
0B61:0019 CD21 INT 21
…….
-G? ;执行程序
01010011
Program terminated normally
-
注意:
不能破坏程序段前缀内容,
否则无法返回 DOS,造成死机 。
讲义中介绍的第二种返回 DOS的方法 不作学习要求 。
(在老的教材或参考书中使用该法,新版的书中很少使用,
新版的教材 P98的例程可以不看,采用的是第二种方法 )。
想要掌握的同学可自学。
第二种 DOS返回方法,调用 20H类型的中断程序
◢ 20H 中断程序的功能:
处理程序结束,返回系统 。
◢ 调用 20H中断程序是有条件的:
要求当前的 CS应为程序段前缀在内存的段值问题:
如何保证执行到 INT 20H时,
当前 CS的值为程序段前缀在内存的段值?
xxxx,00 00 INT 20
采用下面的程序框架,
可保证执行 INT 20H时,
当前的 CS值为程序段前缀在内存的段值 。
code SEGMENT
ASSUME CS:code
main PROC FAR ;使 RET为远返回
start,PUSH DS ;入栈保存地址
MOV AX,0 ;程序段前缀的首地址
PUSH AX
、,;程序主体部分
、、
RET ;取程序段前缀首地址
main ENDP
code ENDS
END start
CD 20
xxxx
,、、
0000
xxxx,0
SS:S P
SS:S P
程序段前缀 P S P
PS P 的段值
PS P 的偏值用户程序
CS IP
注意:
1,不可在汇编语言程序的最后用 INT 20H返回 DOS。
原因是 20h中断子程的执行是有条件的 。
采用第二种返回 DOS的程序结构,才能满足该条件,
否则无法返回 。
2,不可在程序的最后用 INT 3返回 DOS。
原因是 3类型的中断子程实现断点设置,
只在 DEBUG下起作用 。
五,表达式及表达式中的操作符表达式
由常量,标号,变量和一些操作符构成 。
汇编程序对表达式进行运算后,得到一个确定的数值,
再把这个数值汇编到指令中 。
据表达式所表示的内容,分数字表达式,地址表达式 。
表达式是指令或伪操作的操作数 ;
表达式中的操作符由汇编程序完成例 MOV AX,12 - 4 ;MOV AX,8 ;数字表达式
LEA BX,[ string + 4 ] ;地址表达式表达式中的操作符
▲ 有以下几类,
1,算术运算符 ( +,-,*,/,MOD )
2,逻辑运算符 ( AND,OR,NOT,XOR )
3,关系运算符 ( EQ,NE,GT,GE,LT,LE )
真,FFFFH; 假,0
4,数值返回操作符 ( SEG,OFFSET )
5,类型操作 ( PTR )
6,地址记数器 ( $ )
例,
1,算术运算符 ( +,-,*,/,MOD(取余数 ) )
MOV AX,6 * 8 ← MOV AX,48
2,逻辑运算符 (AND,OR,NOT,XOR)
MOV AX,80h OR 70h ← MOV AX,0F0h
3,关系运算符 ( EQ,NE,GT,GE,LT,LE )
真,FFFFH; 假,0
MOV AX,1 GE 2 ← MOV AX,0
4,数值返回操作符 ( SEG,OFFSET )
SEG 取符号地址的段地址例 MOV AX,SEG yy
OFFSET 取符号地址的偏移地址例 MOV BX,OFFSET yy
bb SEGMENT
yy DB 6 dup (?)
bb ENDS
cc SEGMENT
ASSUME CS:cc,DS:aa,ES:bb
start,CLD
MOV AX,SEG yy
MOV ES,AX
MOV DI,OFFSET yy
MOV CX,6
……,
cc ENDS
END start
aa SEGMENT
xx DB 'Hello!’
aa ENDS
bb SEGMENT
yy DB 6 dup (?)
bb ENDS
cc SEGMENT
ASSUME CS:cc,DS:aa,ES:bb
start,CLD
MOV AX,aa
MOV DS,AX
LEA SI,xx
MOV AX,SEG yy
MOV ES,AX
MOV DI,OFFSET yy
MOV CX,6
REP MOVSB
MOV AH,4CH
INT 21H
cc ENDS
END start
D:\>DEBUG hello1.exe
-U ;查看程序代码
129F:0000 FC CLD
129F:0001 B89D12 MOV AX,129D
129F:0004 8ED8 MOV DS,AX
129F:0006 8D360000 LEA SI,[ 0000 ]
129F:000A B89E12 MOV AX,129E
129F:000D 8EC0 MOV ES,AX
129F:000F BF0000 MOV DI,0000
129F:0012 B90600 MOV CX,0006
129F:0015 F3 REPZ
129F:0016 A4 MOVSB
129F:0017 B44C MOV AH,4C
129F:0019 CD21 INT 21
、、、、、、
MOV AX,bb
LEA DI,yy
注意,SEG,OFFSET只能对符号地址操作
MOV AX,SEG [BX]
MOV BX,OFFSET [SI]
汇编语言程序举例 (第三节例一 )
(实验二 编程任务 4)
编写完整汇编语言程序,完成内存数据块传送功能 。
将某段中的字符串,Hello!”传送到另一段中 。
例一 编写完整汇编语言程序,完成内存数据块传送功能 。
将某段中的字符串,Hello!”传送到另一段中 。
开始建立传送方向
DS,SI ← 源串首地址
ES,DI ←目的串首地址
CX ← 串长度串传送返回 D O S
利用变量定义字符串和缓冲区
aa SEGMENT ; 数据段 1
xx DB 'Hello!’ ; 定义源串
aa ENDS
bb SEGMENT ;数据段 2
yy DB 6 dup (?) ; 定义目的缓冲区
bb ENDS
cc SEGMENT ;代码段
ASSUME CS:cc,DS:aa,ES:bb ;指示指令中标号,变量所在段
start,CLD ;设置传送方向
MOV AX,aa ;DS,SI ← 源串首地址
MOV DS,AX
LEA SI,xx
MOV AX,SEG yy ;ES,DI← 目的首地址
MOV ES,AX
MOV DI,OFFSET yy
MOV CX,6 ;CX ← 串的长度
REP MOVSB ;串传送
MOV AH,4CH ;调用 4CH系统功能,返回 DOS
INT 21H
cc ENDS
END start ;指示程序结束和程序入口
D:\>EDIT hello.asm ;编写源程序
D:\>MASM hello ; ;汇编源程序
Microsoft (R) Macro Assembler Version 5.10
Copyright (C) Microsoft Corp 1981,1988,All rights reserved.
49860 + 421241 Bytes symbol space free
0 Warning Errors
0 Severe Errors
D:\>LINK hello ; ;连接程序
Microsoft (R) Overlay Linker Version 3.61
Copyright (C) Microsoft Corp 1983-1987,All rights reserved.
LINK,warning L4021,no stack segment
D:\>hello ;执行程序
D:\>
警告性错误:无堆栈段此错误可忽略
D:\>DEBUG hello.exe? ;利用 DEBUG查看结果
-U? ;查看程序代码
129F:0000 FC CLD
129F:0001 B89D12 MOV AX,129D
129F:0004 8ED8 MOV DS,AX
129F:0006 8D360000 LEA SI,[ 0000 ]
129F:000A B89E12 MOV AX,129E
129F:000D 8EC0 MOV ES,AX
129F:000F BF0000 MOV DI,0000
129F:0012 B90600 MOV CX,0006
129F:0015 F3 REPZ
129F:0016 A4 MOVSB
129F:0017 B44C MOV AH,4C
129F:0019 CD21 INT 21
、、、、、、
-D 129D:0 L20? ;执行程序前,查看源串内容
129D:0000 48 65 6C 6C 6F 21 00 00-00 00 00 00 00 00 00 00 Hello!..........
129D:0010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00,...............
-D 129E:0 L20? ;执行程序前,查看目的串
129E:0000 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00,...............
129E:0010 FC B8 9D 12 8E D8 8D 36-00 00 B8 9E 12 8E C0 BF,......6........
-
CLD
MOV AX,aa
MOV DS,AX
LEA SI,xx
MOV AX,SEG yy
MOV ES,AX
MOV DI,OFFSET
yy
MOV CX,6
REP MOVSB
MOV AH,4CH
INT 21H
-G ; 执行程序
Program terminated normally
-D 129E,0 L20 ; 查看目的串
129E:0000 48 65 6C 6C 6F 21 00 00-00 00 00 00 00 00 00 00 Hello!..........
129E:0010 FC B8 9D 12 8E D8 8D 36-00 00 B8 9E 12 8E C0 BF,......6........
-D 129D,0 L50 ; 从源串重新查看
129D:0000 48 65 6C 6C 6F 21 00 00-00 00 00 00 00 00 00 00 Hello!..........
129D:0010 48 65 6C 6C 6F 21 00 00-00 00 00 00 00 00 00 00 Hello!..........
129D:0020 FC B8 9D 12 8E D8 8D 36-00 00 B8 9E 12 8E C0 BF,......6........
129D:0030 00 00 B9 06 00 F3 A4 B4-4C CD 21 09 E8 08 00 03,.......L.!.....
129D:0040 F1 E8 03 00 3C 0D C3 AC-E8 EC F8 75 04 3C 3B 75,...<......u.<;u
-
问题思考,(实验课上讨论 )
1,一个段的大小为多少? 一定是 64K吗?
根据 DEBUG下查看的结果,
画出程序各段在内存的存放情况 。
2,假如将程序中的 MOV CX,6 改为 MOV CX,100H
程序执行的结果会如何? 试用 DEBUG观察结果 。
-U? ;查看程序代码
129F:0000 FC CLD
129F:0001 B89D12 MOV AX,129D
129F:0004 8ED8 MOV DS,AX
129F:0006 8D360000 LEA SI,[ 0000 ]
129F:000A B89E12 MOV AX,129E
129F:000D 8EC0 MOV ES,AX
129F:000F BF0000 MOV DI,0000
129F:0012 B90600 MOV CX,0006
129F:0015 F3 REPZ
129F:0016 A4 MOVSB
129F:0017 B44C MOV AH,4C
129F:0019 CD21 INT 21
、、、、、、
aa SEGMENT
xx DB 'Hello!’
aa ENDS
bb SEGMENT
yy DB 6 dup (?)
bb ENDS
cc SEGMENT
ASSUME CS:cc,DS:aa,ES:bb
start,CLD
MOV AX,aa
MOV DS,AX
LEA SI,xx
MOV AX,SEG yy
MOV ES,AX
MOV DI,OFFSET yy
MOV CX,6
REP MOVSB
MOV AH,4CH
INT 21H
cc ENDS
END start
3,可否在程序结束处用一条 RET返回指令,返回 DOS?
(实验课上讨论 )
aa SEGMENT ; 数据段 1
xx DB 'Hello!’ ; 定义源串
aa ENDS
bb SEGMENT ;数据段 2
yy DB 6 dup (?) ; 定义目的缓冲区
bb ENDS
cc SEGMENT ;代码段
ASSUME CS:cc,DS:aa,ES:bb ;指示指令中标号,变量所在段
start,CLD ;设置传送方向
MOV AX,aa ;DS,SI ← 源串首地址
MOV DS,AX
LEA SI,xx
MOV AX,SEG yy ;ES,DI ← 目的首地址
MOV ES,AX
MOV DI,OFFSET yy
MOV CX,6 ;CX ← 串的长度
REP MOVSB ;串传送
RET
cc ENDS
END start ;指示程序结束和程序入口
D:\>DEBUG hello.exe
- U
129F:0000 FC CLD
129F:0001 B89D12 MOV AX,129D
129F:0004 8ED8 MOV DS,AX
129F:0006 8D360000 LEA SI,[0000]
129F:000A B89E12 MOV AX,129E
129F:000D 8EC0 MOV ES,AX
129F:000F BF0000 MOV DI,0000
129F:0012 B90600 MOV CX,0006
129F:0015 F3 REPZ
129F:0016 A4 MOVSB
129F:0017 F3 RET
129F:0018 43 INC BX
129F:0019 50 PUSH AX
129F:001A FF36C601 PUSH [01C6]
、、、
-
hello.exe
用户程序与用户程序相连的内存内容被看作程序时
4,END 语句后没有起始地址,程序执行的后果?
(实验课上讨论 )
aa SEGMENT ; 数据段 1
xx DB 'Hello!’ ; 定义源串
aa ENDS
bb SEGMENT ;数据段 2
yy DB 6 dup (?) ; 定义目的缓冲区
bb ENDS
cc SEGMENT ;代码段
ASSUME CS:cc,DS:aa,ES:bb ;指示指令中标号,变量所在段
start,CLD ;设置传送方向
MOV AX,aa ;DS,SI ← 源串首地址
MOV DS,AX
LEA SI,xx
MOV AX,SEG yy ;ES,DI ← 目的首地址
MOV ES,AX
MOV DI,OFFSET yy
MOV CX,6 ;CX ← 串的长度
REP MOVSB ;串传送
MOV AH,4CH ;调用 4CH系统功能,返回 DOS
INT 21H
cc ENDS
END ; start ;指示程序结束和程序入口
5,如下操作为何查看不到结果?
(实验课上讨论 )
D:\>MASM hello; ;汇编源程序
D:\>LINK hello; ;连接程序
D:\>hello ;先在 DOS下运行程序
D:\>DEBUG ;再进入 DEBUG查看结果
- D 129E:0 L30 ;查看目的串
129E:0000 2A 75 05 80 0E 2D DA 02-3A 06 14 D4 75 C9 4E 32 *u...-..:...u.N2
129E:0010 C0 86 04 46 3C 0D 75 02-88 04 89 36 EB D8 89 0E,..F<.u....6....
129E:0020 E9 D8 C3 BE CE DC 8B 4C-05 8B 74 09 E8 08 00 03,......L..t.....
-D 129D:0 L30 ;查看源串
129D:0000 75 04 FE 06 29 DA 3C 3F-75 05 80 0E 2D DA 02 3C u...).<?u...-..<
129D:0010 2A 75 05 80 0E 2D DA 02-3A 06 14 D4 75 C9 4E 32 *u...-..:...u.N2
129D:0020 C0 86 04 46 3C 0D 75 02-88 04 89 36 EB D8 89 0E,..F<.u....6....
data1 SEGMENT ;数据段 1,(可据需要设定,也可无 )
…… ;变量定义
data1 ENDS
data2 SEGMENT ;数据段 2 (可据需要设定,也可无 )
……
data2 ENDS
code SEGMENT ;程序段
ASSUME CS,code,DS:data1,ES:data2
start:,、,;程序主体部分
、、、
、、、
、、、
MOV AH,4CH ;返回 DOS
INT 21H
code ENDS
END start
完整汇编语言程序框架: