由于本专业不要学汇编,所以想自学,但还没接触过汇编,特来求教……希望大家给我指点迷津,先谢谢了!!
我想在寒假把汇编学完,但是寒假回家了就不能上网了,查资料什么的都不方便,所以现在想做点准备工作。
现在的问题是我该怎么准备?需要什么编辑器吗?
15 个解决方案
#1
王爽的 汇编语言 pdf文档 可以在手机上看
不过手机上看不方便
不过手机上看不方便
#2
我也是自动化毕业的,学完c。就学的汇编啊,单片机也用汇编扁的啊。
#3
咱也才入门,看的大灰狼的《零基础汇编视频》,感觉不错,听着不迷糊。楼主可以试试。
之后看的《WinASMRadASM系列培训》,刚看感觉这个写windows程序和用c非常像,除了语法是汇编的,其他流程和C的基本就一样。也非常容易入门。
之后看的《WinASMRadASM系列培训》,刚看感觉这个写windows程序和用c非常像,除了语法是汇编的,其他流程和C的基本就一样。也非常容易入门。
#4
我有电脑但不能联网
呵呵……
#5
可能不同学校安排不同吧!!
#6
给你的建议:
1.先去你的图书馆里面去借一本《 IBM PC 汇编语言程序设计》 或 王爽。
2.有空上一下 看雪论坛,里面有很多工具都是很有用的,而且它基本上是中国最好的了,里面有很多大牛。
3.一定要动手做实验,当你写汇编像用C一样顺手时,你就算是入门了。
本来有很多书都很好的,想介绍一下给你的,就是不知道你们图书馆有没有
《汇编语言程序设计教程》:清大的,比较适合用来入门
《天书夜读 从汇编到到Windows内核编程》理解前面几章用汇编和用C差不多了
其实CSDN上一搜教程一大堆,
我用了大概半个月把一个系统的教程看完了,结果什么都不会编(这个不是打击楼主)。后来都是要等到老师
上课,然后做了一些实验才懂了, 原来汇编也不过如此。
但是自学的话,会遇到很多问题,例如一个最简音的问题:用什么工具,这个工具怎么用。这个可能就要花掉半个月的时间去熟悉,所以 楼主一定要有心理准备,一定要有心理准备去刻服种种问题,不然只凭一时的热度,很难学下去的(不是打击楼主,都是我之前的切身体会)。
最后祝楼主好运吧
1.先去你的图书馆里面去借一本《 IBM PC 汇编语言程序设计》 或 王爽。
2.有空上一下 看雪论坛,里面有很多工具都是很有用的,而且它基本上是中国最好的了,里面有很多大牛。
3.一定要动手做实验,当你写汇编像用C一样顺手时,你就算是入门了。
本来有很多书都很好的,想介绍一下给你的,就是不知道你们图书馆有没有
《汇编语言程序设计教程》:清大的,比较适合用来入门
《天书夜读 从汇编到到Windows内核编程》理解前面几章用汇编和用C差不多了
其实CSDN上一搜教程一大堆,
我用了大概半个月把一个系统的教程看完了,结果什么都不会编(这个不是打击楼主)。后来都是要等到老师
上课,然后做了一些实验才懂了, 原来汇编也不过如此。
但是自学的话,会遇到很多问题,例如一个最简音的问题:用什么工具,这个工具怎么用。这个可能就要花掉半个月的时间去熟悉,所以 楼主一定要有心理准备,一定要有心理准备去刻服种种问题,不然只凭一时的热度,很难学下去的(不是打击楼主,都是我之前的切身体会)。
最后祝楼主好运吧
#7
http://topic.csdn.net/u/20100106/16/fc962cad-600f-4a6e-91ac-9431deb4092d.html?24723
看一下这个贴吧,学汇编的基本上都会看过这几个教程的
看一下这个贴吧,学汇编的基本上都会看过这几个教程的
#8
非常感谢6楼的建议!!!但我具体用什么工具呢
#9
工具:其实用debug 就可以编,但比较多人用的是MASM611(这个是dos 界面,自学的话可能不大会用)
还是去看雪那里去下载吧,里面的那个RedASM就挺好用的。
http://www.pediy.com/tools.htm
这里面就什么工具都齐啦
还是去看雪那里去下载吧,里面的那个RedASM就挺好用的。
http://www.pediy.com/tools.htm
这里面就什么工具都齐啦
#10
花点时间,吃点苦
#11
入门级实验,贴出来给大家看一下吧
实习一 调试工具的使用方法训练(2学时)
1.实验目的
掌握调试工具DEBUG的使用方法,理解汇编指令、存储单元和寄存器等有关概念,能够对简单的汇编语言程序进行调试。
2.实验内容
(1)学习调试工具DEBUG的使用方法,熟悉DEBUG常用命令的功能和用法。
(2)利用DEBUG调试简单的汇编语言程序,体会汇编指令的功能、寄存器的作用、存储单元地址与内容的概念和作用、以及程序的执行过程。
3.实验要求
(1)掌握DEBUG的常用命令和基本的程序调试方法
(2)熟悉和掌握指令系统常用指令的功能和用法,能熟练运用DEBUG调试工具调试简单的程序,并初步掌握使用DOS系统功能调用的方法。
4.重点与难点
存储器和寄存器的概念、各寄存器的用途、常用指令的功能和用法、用DEBUG调试程序的方法。
5.实验结果验收
熟练运用DEBUG调试工具完成本实习6.2节要求的程序设计和调试
6.实验指导
6.1 调试工具DEBUG简介
DEBUG是DOS操作系统为汇编语言程序设计者和系统管理员提供的一个通用调试工具,利用DEBUG可以读写、传送、比较、查找和显示存储器单元内容,设置程序起始执行地址或断点,执行程序或分段执行程序,跟踪程序执行,显示处理器状态,汇编或反汇编程序等。用DEBUG编程简单、方便和直观,可以直接查看程序执行情况,便于熟悉和理解指令,掌握基本编程技巧。
DEBUG只使用十六进制表示数据(十六进制数后不加“H”),屏幕的显示数据形式如下:
1400:0100 24 65 6E 64 73 0D 0A 20-20 63 6F 64 65 20 20 24 *ends..code *
1400:0110 73 65 67 6D 65 6E 74 0D-0A 20 20 20 20 20 20 24 segment.. *
1400:0170 24 61 78 2c 30 0D 0A 09-20 20 20 20 70 75 73 68 *ax,0 push
屏幕每行显示内容分为三部分,一行共显示十六个字节单元的内容。第一部分是本行所显示的16个字节数据在存储器中的起始存放地址;第二部分是以十六进制显示的16个字节数据;第三部分是将本行所显示字节数据看作ASCII码时显示的字符,若某字节数据对应不可显示的ASCII码,则显示一个“.”字符代替该字节数据的显示字符。
DEBUG只有十几条单字母命令,功能强且易掌握,常用DEBUG命令如下:
1)DEBUG的进入和退出
进入DEBUG时,如果要同时装入某程序,键入下面的命令:
H:> DEBUG <文件名> [<参数>]
其中文件名指定要装入的程序目标码文件,其扩展名可以是.COM或.EXE。<参数>是由被装入程序接收的参数。此外,也可以用下面的方式进入DEBUG:
H:> DEBUG
-
“-”是DEBUG的命令提示符,表明已进入DEBUG状态。在“-”提示符之后,可以键入DEBUG命令。
退出DEBUG时,键入如下命令从DEBUG状态返回DOS:
-Q
2)汇编与反汇编命令
汇编命令A和反汇编命令U是常使用的DEBUG命令。
① 汇编命令A
格式:A [<起始地址>]
功能:逐行汇编程序,主要用于小段程序的汇编。
说明:使用A命令汇编程序,不允许程序中出现标号和伪指令,但MS-DOS的DEBUG允许使用DB和DW这两条伪指令。如果未给出起始地址,汇编后的程序代码从指令指针寄存器IP的值指定的地址开始存放。按两次回车键可退出汇编命令A的状态。
例1-1 汇编一段程序,该程序的功能是在屏幕上输出一个大写字母A。
-A 100
1141:0100 MOV DL,41
1141:0102 MOV AH,02
1141:0104 INT 21
1141:0106 INT 20
② 反汇编命令U
格式:U [<地址范围>]
功能:在指定的地址范围内,将二进制机器指令逐条翻译为汇编语言符号指令。
例1-2 将例1-1中汇编的程序进行反汇编
-U 100 107
1141:0100 B241 MOV DL,41
1141:0102 B402 MOV AH,02
1141:0104 CD21 INT 21
1141:0106 CD20 INT 20
3)执行程序命令
在DEBUG下,可以完整地执行程序、分段执行程序或单步执行程序。
① 执行程序命令G
格式:G [=<程序起始地址>] [<断点>…]
功能:完整地或分段执行程序。
说明:G命令可以从头至尾完整地执行程序,如果G命令带有有断点参数,则执行到断点地址时暂停并显示当前各寄存器状态,断点最多允许设置100个。程序正常结束时显示“Program terminated normally”。
例1-3 执行例1-1中汇编的程序。
-G =100
A
Program terminated normally
② 跟踪执行命令P和T
格式:P [=<地址>] [<跟踪条数>]
T [=<地址>] [<跟踪条数>]
功能:跟踪命令P和T可以逐条跟踪指令的执行,以便调试程序。
说明:每条指令执行后都将显示各寄存器的当前值。P命令与T命令的差别是,P命令按程序书写的指令为单位,一次跟踪完一条书写指令(执行一组相关的指令),而T命令按存储单元中存放的指令为单位,一次跟踪一条指令的执行。
例1-4 用P命令跟踪例1-1中的程序。
设程序执行前的各寄存器初值如下,然后开始用P命令跟踪例1-1程序:
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1141 ES=1141 SS=1141 CS=1141 IP=0100 NV UP EI PL NZ NA PO NC
1141:0100 B241 MOV DL,41
-P =100
AX=0000 BX=0000 CX=0000 DX=0041 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1141 ES=1141 SS=1141 CS=1141 IP=0102 NV UP EI PL NZ NA PO NC
1141:0102 B402 MOV AH,02
-P
AX=0200 BX=0000 CX=0000 DX=0041 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1141 ES=1141 SS=1141 CS=1141 IP=0104 NV UP EI PL NZ NA PO NC
1141:0104 CD21 INT 21
-P
A
AX=0241 BX=0000 CX=0000 DX=0041 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1141 ES=1141 SS=1141 CS=1141 IP=0106 NV UP EI PL NZ NA PO NC
1141:0106 CD20 INT 20
-P
Program terminated normally
用P命令只需跟踪执行4次,程序就执行完毕。如果用T命令逐条指令跟踪执行,则将跟踪进入DOS功能调用的软中断服务程序中。
4)显示寄存器命令R
格式:R [<寄存器>]
功能:显示或修改寄存器内容。
说明:当R命令后面不指定寄存器时,显示所有寄存器的内容。
例1-5 显示所有寄存器内容
-R
AX=0100 XB=0000 CX=2000 DX=00000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=07E1 ES=07E1 SS=07E1 CS=07E1 IP=0114 NV UP DI PL NZ NA PO NC
例1-6 修改寄存器内容
要修改某寄存器内容,可在R命令后键入寄存器名,DEBUG将显示出这个寄存器的值,然后键入新值就可修改该寄存器内容。例如修改AX寄存器的内容:
-R AX
AX 4500
:3000
用RF命令可显示和修改标志寄存器FR中的标志位,无论修改哪一位标志位,只需要键入该标志位的表示符号(各标志位的符号表示如表1.1所示),并且标志位值的键入顺序可任意。
例1-7 修改FR寄存器的零标志位和进位标志位。
-RF
NV UP EI PL ZR NA PE CY - NZ NC (修改零标志和进位标志)
-RF
NV UP EI PL NZ NA PE NC - (显示修改结果)
表1.1 标志寄存器各标志位符号及意义
标 志 位 符号表示
=1 =0
OF 溢出(是/否) OV NV
DF 方向(减/增) DN UP
IF 中断(开/关) EI DI
SF 符号(负/正) NG PL
ZF 零(是/否) ZR NZ
AF 辅助进位(是/否) AC NA
PF 奇偶(偶/奇) PE PO
CF 进位(是/否) CY NC
5)存储器单元访问命令
① 显示存储器单元命令D
格式:D [<地址范围>]
功能:显示指定地址范围内的存储区数据,包括十六进制数据形式及其对应的ASCII码字符显示。
例1-8 显示110H到116H存储器单元的内容。
-D 110 116
1540:0110 73 65 67 6D 65 6E 74 segment
② 写存储器单元命令E
格式:E <地址> [<字符串>]
功能:逐个修改指定单元内容或将字节串写入指定的一组连续单元。
例1-9 将字节串string写入以142H为起始地址的存储器区。
-E 142 string
例1-10 逐个单元向彩显视频缓冲区写入41H、42H、41H、42H,彩显视频缓冲区的段地址为B800H,数据写入后立即显示出大写的ABAB。
-E B800:70
B800:0070 30.41 07.00 30.42 07.00 30.41 07.f0 30.42 07.f0
B800:0078 20.
注意,“.”前为存储器单元原内容,“.”后为键入的数据,按空格键继续修改下一个存储器单元。例中前两个AB为正常显示,后两个AB为反相、闪烁显示。
③ 填充命令F
格式:F <地址范围> <要填入的字节或字节串>
功能:在指定地址范围内写入数据。
例1-11 联用R命令和F命令在彩显视频缓冲区中写入一串小写字母a。
-R DS (修改DS,使DS指向彩显缓冲区B8000H)
DS 0000
:B800
-F 0000 0050 61 (在0到50H单元内填满a)
6)读写磁盘命令
读写磁盘有两种方式,一种是按扇区读写,直接使用读写命令即可,另一种是按文件名读写。后一种方法首先要指定读写文件名及待读写数据的字节数,再键入读写命令。
① 按文件名读写
文件名定义命令N
格式:N <文件名> [<文件名>…]
功能:为读写磁盘文件定义文件名。
说明:可以指定多个文件名
例1-12 定义要读写的文件为FILE.COM
-N FILE.COM
② 写盘命令W
格式:W [<地址> [<盘符> <相对扇区号> <扇区数>]
功能:将指定存储区单元内容写入指定盘的扇区或盘文件。
例1-13 把例1-1中的程序存入盘文件DEMO.COM中。
写盘文件操作步骤如下:
-N DEMO.COM (定义文件名)
-R BX (在BX:CX中设置待写数据的字节数)
BX 0000
:
-R CX
CX 0000
:8 (写8个字节到DEMO.COM文件中)
-W 100 (执行写盘文件操作,从100H单元开始取8个字节写盘文件)
Writing 0008 bytes
-
③ 读盘命令L
格式:L [<地址> [<盘符> <相对扇区号> <扇区数>]]
功能:将指定盘文件或扇区的内容读入存储器单元中。
说明:<地址>项为存放读入数据的存储区单元地址,其余项与W命令说明类似。
例1-14 从B盘相对扇区10H(16)开始,读64H(100)个连续扇区的数据,存入起始地址为400H:100H的存储区。
-L 400:100 1 10 64
例1-15 读入文件DEMO.COM,再反汇编该程序。
H:>DEBUG
-N DEMO.COM
-L 100
-U 100 107
1156:0100 B241 MOV DL,41
1156:0102 B402 MOV AH,02
1156:0104 CD21 INT 21
1156:0106 CD20 INT 20
7)其他命令
除以上常用命令外,DEBUG还提供了存储区数据比较命令C、数据查找命令S、数据移动命令M和十六进制数运算命令H等。表1.2列出了DEBUG的全部命令以便于查阅。
表1.2 DEBUG命令表
命令及其功能 格 式
A(Assemble)
汇编源程序 A[<地址>]
U(Unassemble)
对二进制指令代码进行反汇编 U[<地址范围>]
T(Trace)
跟踪执行程序并显示寄存器内容 T[=<地址>][<跟踪条数>]
P(Proceed)
跟踪执行一组相关的指令 P[=<地址>][<跟踪条数>]
D(Dump)
显示存储区数据 D[<地址>]或D[<地址范围>]
E(Enter)
修改存储区数据 E<地址>[<字符串>]
F(Fill)
将成组数据填入存储区 F<地址范围><要填入的字节或字节串>
G(Go)
运行程序 G[=<起始地址>][<断点地址>…]
R(Register)
显示和修改寄存器内容 R[<寄存器>]
N(Name)
定义文件名 N<文件名>[<文件名>…]
续表
命令及其功能 格 式
L(Load)
装入文件或磁盘扇区 L[<地址>][<盘符><相对扇区号><扇区数>]
W(Write)
写文件或写磁盘扇区 W[<地址>[<盘符><相对扇区号><扇区数>]]
M(Move)
传送存储区数据块 M<源地址范围><目的地址>
I(Input)
读/显示端口 I<端口号>
O(Output)
输出数据到端口 O<端口号><字节>
H(Hexarithmetic)
十六进制加减法运算 H<数值><数值>
C(Compare)
比较存储区数据 C<源地址范围><目的地址>
S(Search)
检索字节或字符串 S<地址范围><要检索的字节或字节串>
Q(Quit)
退出DEBUG Q
6.2 实习题
(1)下面的例子可用于调试程序的实验,并且作为几个常用DOS系统功能调用的示范。
① 将大写字母A转换为小写字母a
-A 200
MOV DL,41 ;A->DL
OR DL,20 ;A->a
MOV AH,2 ;功能号-> AH
INT 21 ;调用DOS功能调用2号功能,显示一个字符
INT 20 ;退出程序执行,返回DOS
-G =200
思考并尝试修改程序,实现如下功能:将大写字母B转换为小写字母b。
② 从键盘输入一个字符并回显
-A 220
MOV AH,1 ;功能号-> AH
INT 21 ;调用DOS功能调用1号功能,从键盘接收一个字符
MOV DL,AL ;将接收的字符送DL,准备显示
MOV AH,2 ;功能号-> AH
INT 21 ;调用DOS功能调用2号功能,显示一个字符
INT 20 ;退出程序执行,返回DOS
-G =220
③ 显示字符串
-E 120 ‘How do you do?$’
-A 100
MOV DX,120 ;待显示的字符串地址->DX
MOV AH,9 ;功能号-> AH
INT 21 ;调用DOS功能调用9号功能,显示一个字符串
INT 20 ;退出程序执行,返回DOS
-G =100
思考并尝试修改程序:如果将字符串存放在300H开始的存储区,应该怎样修改程序?
(2)从BX所指的内存单元开始连续存放着两个字数据(被减数和减数),按寄存器间接寻址方式写出指令序列,取得被减数和减数,求两数之差,并将差存放于减数之后。要求计算:
① 3580H-3000H ② 3-5
提示:先用DEBUG的E命令将被减数和减数写入内存某一块存储区(例如以200H为起始地址的存储区),然后在A命令状态下写程序,将数据存储区地址(200H)送入BX寄存器,利用寄存器间接寻址方式访问存储单元中的被减数和减数,再计算差和存放差。
思考并动手尝试:如何查看程序执行结果?
(3)写一指令序列完成以下操作:
① AX寄存器的低6位清0 ② BX寄存器的高4位置1
③ CX寄存器的低8位求反
(4)要求使用串操作指令编写一程序段,先将以400H为起始地址的存储区(40个字节单元)初始化为空格,然后将以500H为起始地址的存储区中的15个字符,传送到以400H为起始地址的存储区中。
(5)利用DEBUG的调试功能,体会、熟悉和掌握指令系统常用指令的使用方法及功能。
实习一 调试工具的使用方法训练(2学时)
1.实验目的
掌握调试工具DEBUG的使用方法,理解汇编指令、存储单元和寄存器等有关概念,能够对简单的汇编语言程序进行调试。
2.实验内容
(1)学习调试工具DEBUG的使用方法,熟悉DEBUG常用命令的功能和用法。
(2)利用DEBUG调试简单的汇编语言程序,体会汇编指令的功能、寄存器的作用、存储单元地址与内容的概念和作用、以及程序的执行过程。
3.实验要求
(1)掌握DEBUG的常用命令和基本的程序调试方法
(2)熟悉和掌握指令系统常用指令的功能和用法,能熟练运用DEBUG调试工具调试简单的程序,并初步掌握使用DOS系统功能调用的方法。
4.重点与难点
存储器和寄存器的概念、各寄存器的用途、常用指令的功能和用法、用DEBUG调试程序的方法。
5.实验结果验收
熟练运用DEBUG调试工具完成本实习6.2节要求的程序设计和调试
6.实验指导
6.1 调试工具DEBUG简介
DEBUG是DOS操作系统为汇编语言程序设计者和系统管理员提供的一个通用调试工具,利用DEBUG可以读写、传送、比较、查找和显示存储器单元内容,设置程序起始执行地址或断点,执行程序或分段执行程序,跟踪程序执行,显示处理器状态,汇编或反汇编程序等。用DEBUG编程简单、方便和直观,可以直接查看程序执行情况,便于熟悉和理解指令,掌握基本编程技巧。
DEBUG只使用十六进制表示数据(十六进制数后不加“H”),屏幕的显示数据形式如下:
1400:0100 24 65 6E 64 73 0D 0A 20-20 63 6F 64 65 20 20 24 *ends..code *
1400:0110 73 65 67 6D 65 6E 74 0D-0A 20 20 20 20 20 20 24 segment.. *
1400:0170 24 61 78 2c 30 0D 0A 09-20 20 20 20 70 75 73 68 *ax,0 push
屏幕每行显示内容分为三部分,一行共显示十六个字节单元的内容。第一部分是本行所显示的16个字节数据在存储器中的起始存放地址;第二部分是以十六进制显示的16个字节数据;第三部分是将本行所显示字节数据看作ASCII码时显示的字符,若某字节数据对应不可显示的ASCII码,则显示一个“.”字符代替该字节数据的显示字符。
DEBUG只有十几条单字母命令,功能强且易掌握,常用DEBUG命令如下:
1)DEBUG的进入和退出
进入DEBUG时,如果要同时装入某程序,键入下面的命令:
H:> DEBUG <文件名> [<参数>]
其中文件名指定要装入的程序目标码文件,其扩展名可以是.COM或.EXE。<参数>是由被装入程序接收的参数。此外,也可以用下面的方式进入DEBUG:
H:> DEBUG
-
“-”是DEBUG的命令提示符,表明已进入DEBUG状态。在“-”提示符之后,可以键入DEBUG命令。
退出DEBUG时,键入如下命令从DEBUG状态返回DOS:
-Q
2)汇编与反汇编命令
汇编命令A和反汇编命令U是常使用的DEBUG命令。
① 汇编命令A
格式:A [<起始地址>]
功能:逐行汇编程序,主要用于小段程序的汇编。
说明:使用A命令汇编程序,不允许程序中出现标号和伪指令,但MS-DOS的DEBUG允许使用DB和DW这两条伪指令。如果未给出起始地址,汇编后的程序代码从指令指针寄存器IP的值指定的地址开始存放。按两次回车键可退出汇编命令A的状态。
例1-1 汇编一段程序,该程序的功能是在屏幕上输出一个大写字母A。
-A 100
1141:0100 MOV DL,41
1141:0102 MOV AH,02
1141:0104 INT 21
1141:0106 INT 20
② 反汇编命令U
格式:U [<地址范围>]
功能:在指定的地址范围内,将二进制机器指令逐条翻译为汇编语言符号指令。
例1-2 将例1-1中汇编的程序进行反汇编
-U 100 107
1141:0100 B241 MOV DL,41
1141:0102 B402 MOV AH,02
1141:0104 CD21 INT 21
1141:0106 CD20 INT 20
3)执行程序命令
在DEBUG下,可以完整地执行程序、分段执行程序或单步执行程序。
① 执行程序命令G
格式:G [=<程序起始地址>] [<断点>…]
功能:完整地或分段执行程序。
说明:G命令可以从头至尾完整地执行程序,如果G命令带有有断点参数,则执行到断点地址时暂停并显示当前各寄存器状态,断点最多允许设置100个。程序正常结束时显示“Program terminated normally”。
例1-3 执行例1-1中汇编的程序。
-G =100
A
Program terminated normally
② 跟踪执行命令P和T
格式:P [=<地址>] [<跟踪条数>]
T [=<地址>] [<跟踪条数>]
功能:跟踪命令P和T可以逐条跟踪指令的执行,以便调试程序。
说明:每条指令执行后都将显示各寄存器的当前值。P命令与T命令的差别是,P命令按程序书写的指令为单位,一次跟踪完一条书写指令(执行一组相关的指令),而T命令按存储单元中存放的指令为单位,一次跟踪一条指令的执行。
例1-4 用P命令跟踪例1-1中的程序。
设程序执行前的各寄存器初值如下,然后开始用P命令跟踪例1-1程序:
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1141 ES=1141 SS=1141 CS=1141 IP=0100 NV UP EI PL NZ NA PO NC
1141:0100 B241 MOV DL,41
-P =100
AX=0000 BX=0000 CX=0000 DX=0041 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1141 ES=1141 SS=1141 CS=1141 IP=0102 NV UP EI PL NZ NA PO NC
1141:0102 B402 MOV AH,02
-P
AX=0200 BX=0000 CX=0000 DX=0041 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1141 ES=1141 SS=1141 CS=1141 IP=0104 NV UP EI PL NZ NA PO NC
1141:0104 CD21 INT 21
-P
A
AX=0241 BX=0000 CX=0000 DX=0041 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1141 ES=1141 SS=1141 CS=1141 IP=0106 NV UP EI PL NZ NA PO NC
1141:0106 CD20 INT 20
-P
Program terminated normally
用P命令只需跟踪执行4次,程序就执行完毕。如果用T命令逐条指令跟踪执行,则将跟踪进入DOS功能调用的软中断服务程序中。
4)显示寄存器命令R
格式:R [<寄存器>]
功能:显示或修改寄存器内容。
说明:当R命令后面不指定寄存器时,显示所有寄存器的内容。
例1-5 显示所有寄存器内容
-R
AX=0100 XB=0000 CX=2000 DX=00000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=07E1 ES=07E1 SS=07E1 CS=07E1 IP=0114 NV UP DI PL NZ NA PO NC
例1-6 修改寄存器内容
要修改某寄存器内容,可在R命令后键入寄存器名,DEBUG将显示出这个寄存器的值,然后键入新值就可修改该寄存器内容。例如修改AX寄存器的内容:
-R AX
AX 4500
:3000
用RF命令可显示和修改标志寄存器FR中的标志位,无论修改哪一位标志位,只需要键入该标志位的表示符号(各标志位的符号表示如表1.1所示),并且标志位值的键入顺序可任意。
例1-7 修改FR寄存器的零标志位和进位标志位。
-RF
NV UP EI PL ZR NA PE CY - NZ NC (修改零标志和进位标志)
-RF
NV UP EI PL NZ NA PE NC - (显示修改结果)
表1.1 标志寄存器各标志位符号及意义
标 志 位 符号表示
=1 =0
OF 溢出(是/否) OV NV
DF 方向(减/增) DN UP
IF 中断(开/关) EI DI
SF 符号(负/正) NG PL
ZF 零(是/否) ZR NZ
AF 辅助进位(是/否) AC NA
PF 奇偶(偶/奇) PE PO
CF 进位(是/否) CY NC
5)存储器单元访问命令
① 显示存储器单元命令D
格式:D [<地址范围>]
功能:显示指定地址范围内的存储区数据,包括十六进制数据形式及其对应的ASCII码字符显示。
例1-8 显示110H到116H存储器单元的内容。
-D 110 116
1540:0110 73 65 67 6D 65 6E 74 segment
② 写存储器单元命令E
格式:E <地址> [<字符串>]
功能:逐个修改指定单元内容或将字节串写入指定的一组连续单元。
例1-9 将字节串string写入以142H为起始地址的存储器区。
-E 142 string
例1-10 逐个单元向彩显视频缓冲区写入41H、42H、41H、42H,彩显视频缓冲区的段地址为B800H,数据写入后立即显示出大写的ABAB。
-E B800:70
B800:0070 30.41 07.00 30.42 07.00 30.41 07.f0 30.42 07.f0
B800:0078 20.
注意,“.”前为存储器单元原内容,“.”后为键入的数据,按空格键继续修改下一个存储器单元。例中前两个AB为正常显示,后两个AB为反相、闪烁显示。
③ 填充命令F
格式:F <地址范围> <要填入的字节或字节串>
功能:在指定地址范围内写入数据。
例1-11 联用R命令和F命令在彩显视频缓冲区中写入一串小写字母a。
-R DS (修改DS,使DS指向彩显缓冲区B8000H)
DS 0000
:B800
-F 0000 0050 61 (在0到50H单元内填满a)
6)读写磁盘命令
读写磁盘有两种方式,一种是按扇区读写,直接使用读写命令即可,另一种是按文件名读写。后一种方法首先要指定读写文件名及待读写数据的字节数,再键入读写命令。
① 按文件名读写
文件名定义命令N
格式:N <文件名> [<文件名>…]
功能:为读写磁盘文件定义文件名。
说明:可以指定多个文件名
例1-12 定义要读写的文件为FILE.COM
-N FILE.COM
② 写盘命令W
格式:W [<地址> [<盘符> <相对扇区号> <扇区数>]
功能:将指定存储区单元内容写入指定盘的扇区或盘文件。
例1-13 把例1-1中的程序存入盘文件DEMO.COM中。
写盘文件操作步骤如下:
-N DEMO.COM (定义文件名)
-R BX (在BX:CX中设置待写数据的字节数)
BX 0000
:
-R CX
CX 0000
:8 (写8个字节到DEMO.COM文件中)
-W 100 (执行写盘文件操作,从100H单元开始取8个字节写盘文件)
Writing 0008 bytes
-
③ 读盘命令L
格式:L [<地址> [<盘符> <相对扇区号> <扇区数>]]
功能:将指定盘文件或扇区的内容读入存储器单元中。
说明:<地址>项为存放读入数据的存储区单元地址,其余项与W命令说明类似。
例1-14 从B盘相对扇区10H(16)开始,读64H(100)个连续扇区的数据,存入起始地址为400H:100H的存储区。
-L 400:100 1 10 64
例1-15 读入文件DEMO.COM,再反汇编该程序。
H:>DEBUG
-N DEMO.COM
-L 100
-U 100 107
1156:0100 B241 MOV DL,41
1156:0102 B402 MOV AH,02
1156:0104 CD21 INT 21
1156:0106 CD20 INT 20
7)其他命令
除以上常用命令外,DEBUG还提供了存储区数据比较命令C、数据查找命令S、数据移动命令M和十六进制数运算命令H等。表1.2列出了DEBUG的全部命令以便于查阅。
表1.2 DEBUG命令表
命令及其功能 格 式
A(Assemble)
汇编源程序 A[<地址>]
U(Unassemble)
对二进制指令代码进行反汇编 U[<地址范围>]
T(Trace)
跟踪执行程序并显示寄存器内容 T[=<地址>][<跟踪条数>]
P(Proceed)
跟踪执行一组相关的指令 P[=<地址>][<跟踪条数>]
D(Dump)
显示存储区数据 D[<地址>]或D[<地址范围>]
E(Enter)
修改存储区数据 E<地址>[<字符串>]
F(Fill)
将成组数据填入存储区 F<地址范围><要填入的字节或字节串>
G(Go)
运行程序 G[=<起始地址>][<断点地址>…]
R(Register)
显示和修改寄存器内容 R[<寄存器>]
N(Name)
定义文件名 N<文件名>[<文件名>…]
续表
命令及其功能 格 式
L(Load)
装入文件或磁盘扇区 L[<地址>][<盘符><相对扇区号><扇区数>]
W(Write)
写文件或写磁盘扇区 W[<地址>[<盘符><相对扇区号><扇区数>]]
M(Move)
传送存储区数据块 M<源地址范围><目的地址>
I(Input)
读/显示端口 I<端口号>
O(Output)
输出数据到端口 O<端口号><字节>
H(Hexarithmetic)
十六进制加减法运算 H<数值><数值>
C(Compare)
比较存储区数据 C<源地址范围><目的地址>
S(Search)
检索字节或字符串 S<地址范围><要检索的字节或字节串>
Q(Quit)
退出DEBUG Q
6.2 实习题
(1)下面的例子可用于调试程序的实验,并且作为几个常用DOS系统功能调用的示范。
① 将大写字母A转换为小写字母a
-A 200
MOV DL,41 ;A->DL
OR DL,20 ;A->a
MOV AH,2 ;功能号-> AH
INT 21 ;调用DOS功能调用2号功能,显示一个字符
INT 20 ;退出程序执行,返回DOS
-G =200
思考并尝试修改程序,实现如下功能:将大写字母B转换为小写字母b。
② 从键盘输入一个字符并回显
-A 220
MOV AH,1 ;功能号-> AH
INT 21 ;调用DOS功能调用1号功能,从键盘接收一个字符
MOV DL,AL ;将接收的字符送DL,准备显示
MOV AH,2 ;功能号-> AH
INT 21 ;调用DOS功能调用2号功能,显示一个字符
INT 20 ;退出程序执行,返回DOS
-G =220
③ 显示字符串
-E 120 ‘How do you do?$’
-A 100
MOV DX,120 ;待显示的字符串地址->DX
MOV AH,9 ;功能号-> AH
INT 21 ;调用DOS功能调用9号功能,显示一个字符串
INT 20 ;退出程序执行,返回DOS
-G =100
思考并尝试修改程序:如果将字符串存放在300H开始的存储区,应该怎样修改程序?
(2)从BX所指的内存单元开始连续存放着两个字数据(被减数和减数),按寄存器间接寻址方式写出指令序列,取得被减数和减数,求两数之差,并将差存放于减数之后。要求计算:
① 3580H-3000H ② 3-5
提示:先用DEBUG的E命令将被减数和减数写入内存某一块存储区(例如以200H为起始地址的存储区),然后在A命令状态下写程序,将数据存储区地址(200H)送入BX寄存器,利用寄存器间接寻址方式访问存储单元中的被减数和减数,再计算差和存放差。
思考并动手尝试:如何查看程序执行结果?
(3)写一指令序列完成以下操作:
① AX寄存器的低6位清0 ② BX寄存器的高4位置1
③ CX寄存器的低8位求反
(4)要求使用串操作指令编写一程序段,先将以400H为起始地址的存储区(40个字节单元)初始化为空格,然后将以500H为起始地址的存储区中的15个字符,传送到以400H为起始地址的存储区中。
(5)利用DEBUG的调试功能,体会、熟悉和掌握指令系统常用指令的使用方法及功能。
#12
实习二 指令系统的应用与程序调试方法(2学时)
1.实验目的
综合应用指令与伪指令编写简单完整的宏汇编语言程序,掌握常用的运算符、伪指令及宏汇编语言程序的结构,理解内存分段管理的方法和原理,熟悉调试宏汇编语言程序的上机过程及方法,掌握基本的循环程序设计方法。
2.实验内容
使用汇编程序ML(或MASM)、连接程序LINK及DEBUG调试简单的宏汇编语言程序,综合应用指令完成基本的循环程序设计。
3.实验要求
综合应用指令与伪指令编写简单完整的宏汇编语言程序,并熟悉汇编、连接及调试的方法和过程,完成实现简单功能的循环程序。
4.重点
掌握常用运算符和伪指令的功能与用法,能正确地编写分段结构的宏汇编语言程序。
5.实验结果验收
(1)编写四段结构和二段结构的宏汇编语言程序并调试成功
(2)编写具有一定实用功能的循环程序并输出程序执行结果
6.实验指导
6.1上机步骤
编辑、汇编、连接、运行汇编语言程序的步骤如下:
1)编辑源程序文件
用EDIT或者任何一种文本编辑工具(如UltraEdit32等)建立源程序文件,注意汇编语言程序源文件扩展名必须是“.ASM”。例如,用EDIT建立源程序文件FILE.ASM的命令如下:
H:> EDIT FILE.ASM
执行上述命令将出现一个编辑窗口,在此窗口内进行源程序编辑。按“Alt”键可以下拉出菜单选择需要的操作功能。按热键“X”,再按“Enter”键,将保存源文件并退出EDIT编辑窗口。
2)汇编源程序
① 用MASM 6.X版汇编程序进行汇编
H:> ML /c FILE.ASM (只产生目标文件,不进行连接)
或
H:> ML FILE (产生目标文件并自动进行连接,产生可执行文件)
② 用MASM 5.X版汇编程序进行汇编
H:> MASM FILE
Microsoft(R) Macro Assembler Version 5. 01
Copyright(C) Microsoft Corp 1981-1985, 1987. All right reserved.
Object filename [FILE.OBJ]:
Source Listing [NUL.LST]:
cross reference [NUL.CRF]:
0 Warning Errors
0 Sever Errors
汇编无错后,可进行目标文件的连接。
2) 连接
H:> LINK FILE
Microsoft(R) Overlay Linker Version 5.03
Copyright(C) Microsoft Corp 1983-1987. All right reserved.
Run File [FILE.EXE]:
List File [FILE.MAP]:
Libraries [.LIB]:
Definitions File[NUL.DEF]:
3)运行程序
H:> FILE
6.2 四段结构的宏汇编语言程序示例
(1)完整的段定义
例2-1 下面是一个简单的汇编语言源程序,该程序以完整的段定义格式定义了数据段、附加段、堆栈段和代码段,功能是完成字符串传送,将40个星号“*”从数据段传送到附加段。
data segment ;定义数据段
sbuffer db 40 dup (*)
data ends ;数据段结束
extra segment ;定义附加段
dbuffer db 40 dup (?)
extra ends ;附加段结束
stack segment para stack ‘stack’ ;定义堆栈段
db 100 dup(0)
stack ends ;堆栈段结束
code segment ;定义代码段
main proc far ;定义主过程开始
assume cs:code,ds:data,es:extra,ss:stack
start: push ds ;程序执行的起始地址
sub ax,ax
push ax
mov ax,data ;设置数据段地址,初始化DS段寄存器
mov ds,ax
mov ax,extra ;设置附加段地址,初始化ES段寄存器
mov es,ax
lea si,sbuffer ;源字符串存储区首址送SI寄存器
lea di,dbuffer ;目的存储区首址送DI寄存器
cld ;设置方向标志(DF=0)
mov cx,40 ;源字符串长度送CX寄存器
rep movsb ;字符串传送
ret ;返回DOS
main endp ;主过程结束
code ends ;代码段结束
end start ;源程序结束
(2)简化的段定义
例2-2 下面是例2-1源程序的简化段定义格式。
.model small ;定义存储模式
.data ;定义数据段
sbuffer db 40 dup (*)
.data? ;定义data?数据段
dbuffer db 40 dup (?)
.stack 100 ;定义堆栈段(100字节)
.code ;定义代码段
.startup ;定义程序起始点
mov ax,@data ;设置附加段地址,初始化ES段寄存器
mov es,ax
lea si,sbuffer ;源字符串存储区首址送SI寄存器
lea di,dbuffer ;目的存储区首址送DI寄存器
cld ;设置方向标志(DF=0)
mov cx,40 ;源字符串长度送CX寄存器
rep movsb ;字符串传送
.exit 0 ;返回DOS
end ;源程序结束
(3)汇编(同时产生列表文件)、连接并运行
将上述简化段定义源程序建立为源文件stars40.asm后,汇编命令如下:
H:> ML /c /Fl /Sg stars40.asm
上述命令将产生目标文件stars40.obj和列表文件stars40.lst。其中选项/c要求只汇编不连接,选项/Fl要求产生列表文件,选项/Sg要求在列表文件中列出由汇编程序根据伪指令所产生的机器指令。列表文件内容如下:
Microsoft (R) Macro Assembler Version 6.14.8444 03/08/03 15:48:45
stars40.asm Page 1 - 1
.model small
0000 .data
0000 0028 [ sbuffer db 40 dup ('*')
2A
]
0000 .data?
0000 0028 [ dbuffer db 40 dup (?)
00
]
.stack 100
0000 .code
.startup
0000 *@Startup:
0000 BA ---- R * mov dx, DGROUP
0003 8E DA * mov bx, ss
0007 2B DA * sub bx, dx
0009 D1 E3 * shl bx, 001h
000B D1 E3 * shl bx, 001h
000D D1 E3 * shl bx, 001h
000F D1 E3 * shl bx, 001h
0011 FA * cli
0012 8E D2 * mov ss, dx
0014 03 E3 * add sp, bx
0016 FB * sti
0017 B8 ---- R mov ax,@data
001A 8E C0 mov es,ax
001C 8D 36 0000 R lea si,sbuffer
0020 8D 3E 0000 R lea di,dbuffer
0024 FC cld
0025 B9 0028 mov cx,40
0028 F3/ A4 rep movsb
.exit 0
002A B8 4C00 * mov ax, 04C00h
002D CD 21 * int 021h
end
Microsoft (R) Macro Assembler Version 6.14.8444 03/08/03 15:48:45
stars40.asm Symbols 2 - 1
Segments and Groups:
N a m e Size Length Align Combine Class
DGROUP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . GROUP
_DATA . . . . . . . . . . . . . 16 Bit 0028 Word Public 'DATA'
_BSS . . . . . . . . . . . . . . 16 Bit 0028 Word Public 'BSS'
STACK . . . . . . . . . . . . 16 Bit 0064 Para Stack 'STACK'
_TEXT . . . . . . . . . . . . . 16 Bit 002F Word Public 'CODE'
Symbols:
N a m e Type Value Attr
@CodeSize . . . . . . . . . . . Number 0000h
@DataSize . . . . . . . . . . . Number 0000h
@Interface . . . . . . . . . . . Number 0000h
@Model . . . . . . . . . . . . . Number 0002h
@Startup . . . . . . . . . . . . L Near 0000 _TEXT
@code . . . . . . . . . . . . . Text _TEXT
@data . . . . . . . . . . . . . Text DGROUP
@fardata? . . . . . . . . . . . Text FAR_BSS
@fardata . . . . . . . . . . . . Text FAR_DATA
@stack . . . . . . . . . . . . . Text DGROUP
dbuffer . . . . . . . . . . . . Byte 0000 _BSS
sbuffer . . . . . . . . . . . . Byte 0000 _DATA
0 Warnings
0 Errors
对stars40.obj文件进行连接,产生可执行文件stars40.exe,连接命令如下:
H:>LINK stars40
运行可执行文件stars40.exe,命令如下:
H:> stars40
(4)用DEBUG调试和分析stars40.asm程序
① 进入DEBUG时装入stars40.exe程序,如图2.1所示,执行命令:debug stars40.exe。
图2.1 进入DEBUG并装入stars40.exe程序
进入DEBUG后,用r命令显示出装入stars40.exe程序时各寄存器的初值,可供分析代码段、数据段、附加段及堆栈段的存储区分配位置和大小。注意数据段地址为DS=0B90,代码段地址为CS=0BA0。
② 用d命令从DS:0地址开始显示存储区内容(图2.2),前256个字节(存储区地址为0B90H:00H~0B90H:FFH)是程序段前缀(PSP),其中00H-01H字节存放的是INT 20H指令的代码(CD 20),用于结束程序执行,返回DOS(教材第四章详细讨论PSP)。
图2.2 显示程序段前缀(PSP)
③ 继续显示存储区内容(图2.3),可以看到从0B90H:0100H单元开始是代码段存储区,该地址为代码段第一条指令的地址,等价于CS:IP中的段地址和偏移地址0BA0H:0000H。
图2.3 显示源数据区和目的存储区
可以用u命令进行反汇编(如图2.4所示),验证代码段存储区中的指令。从0BA0H:0H单元(等价于0B90H:0100H单元)开始存放着代码段二进制指令,反汇编后得到符号汇编指令(参考前边的列表文件),其中前12条指令是由.startup伪指令展开的一组指令,主要完成初始化DS段寄存器、调整SS和SP寄存器的功能。
图2.4 反汇编列出源代码
④ 从0B90H:0130H单元开始是数据段(见图2.3),数据段中定义了40(28H)个字节的源数据区sbuffer,并初始化为40个“*”,其ASCII码为2AH。从0B90H:0158H单元开始定义了40个字节的目的存储区dbuffer。在程序执行前,dbuffer还没有从sbuffer传送来的40个“*”。
⑤ 用g命令从0BA0H:0000H地址开始执行程序stars40.exe,再执行d命令显示存储区内容,如图2.5所示,从窗口中可以看出,程序执行后,在0B90H:0158H单元开始的目的存储区dbuffer中,已经存放了由0B90H:0130H单元开始的sbuffer传送来的40个“*”。
图2.5 执行]程序并显示dbuffer中的执行结果
⑥ 要进一步分析程序执行过程,可用p命令逐条跟踪程序的执行,如图2.6和2.7所示。
图2.6 开始单步跟踪程序的执行
图2.7 继续跟踪程序的执行
当各个段寄存器初始化完成后(即执行完 mov es,ax指令后),DS=ES=0BA3H,SS:SP调整为0BA3H:00C4H。这是因为对于.small存储模式,规定数据段、附加段、堆栈段共占一段(<=64KB)存储区。0BA3H是相对段内偏移地址为0的段地址,而0B90H是从程序段前缀(PSP)起点开始计数的段地址,二者的关系为0B90H:0130H=0BA3H:0000H,转换为物理地址时是相同的地址,代表相同的存储单元。此外,从程序的执行过程可以看到,源数据区sbuffer(偏移地址为0)和目的存储区dbuffer(偏移地址为28H)是接着连续分配单元的。
当执行了串传送指令repz movsb后,dbuffer存入40个“*”。用d命令从0BA3H:0000H地址开始显示存储单元内容,出现80个“*”,其中sbuffer和dbuffer各存有40个“*”,如图2.8所示,该窗口中的显示结果与图2.3(见该图从0B90H:0130H地址开始的存储单元内容)的显示结果相同。
图2.8 显示目的存储区中的串传送指令执行结果
由于stars40.exe程序没有输出操作,所以程序运行后在屏幕上没有执行结果显示。但是在DEBUG中执行该程序时,可以跟踪执行并查看内存单元数据,因此能看到程序的执行结果,由此也可以体会DEBUG的调试功能。
6.3 实习题
(1)修改例2-1程序,输出传送到目的缓冲区dbuffer中的字符串。
修改提示:
① DS应指向附加段
② dbuffer中的字符串应加字符串结束符$
③ 执行DOS功能调用的9号子功能输出dbuffer中的字符串
(2)写程序,输出演示系统的欢迎词,输出格式的最低要求如下:
***********************************************
* *
* 英文(中文)欢迎词 *
* *
***********************************************
提示:通过编写与调试该程序,掌握两段结构的程序设计、输出数据的格式编排(由ASCII码0AH和0DH控制换行和回车操作)、DOS功能调用,熟悉宏汇编程序调试的上机过程。
(3)编程计算3550H-2320H,按16进制输出计算所得的差1230H。再输出3550H-2321H的差,检验程序的正确性。
提示:考虑依次将1230H(即0001 0010 0011 0000B)从高位到低位,每4位二进制数一组分离出来,再将4位二进制数转换为ASCII码,利用DOS系统功能调用的2号子功能输出,就得到16进制数据的输出效果。本题要求综合应用移位操作、逻辑操作等指令,并利用条件转移指令实现简单的循环程序,程序流程如图2.9所示。
1.实验目的
综合应用指令与伪指令编写简单完整的宏汇编语言程序,掌握常用的运算符、伪指令及宏汇编语言程序的结构,理解内存分段管理的方法和原理,熟悉调试宏汇编语言程序的上机过程及方法,掌握基本的循环程序设计方法。
2.实验内容
使用汇编程序ML(或MASM)、连接程序LINK及DEBUG调试简单的宏汇编语言程序,综合应用指令完成基本的循环程序设计。
3.实验要求
综合应用指令与伪指令编写简单完整的宏汇编语言程序,并熟悉汇编、连接及调试的方法和过程,完成实现简单功能的循环程序。
4.重点
掌握常用运算符和伪指令的功能与用法,能正确地编写分段结构的宏汇编语言程序。
5.实验结果验收
(1)编写四段结构和二段结构的宏汇编语言程序并调试成功
(2)编写具有一定实用功能的循环程序并输出程序执行结果
6.实验指导
6.1上机步骤
编辑、汇编、连接、运行汇编语言程序的步骤如下:
1)编辑源程序文件
用EDIT或者任何一种文本编辑工具(如UltraEdit32等)建立源程序文件,注意汇编语言程序源文件扩展名必须是“.ASM”。例如,用EDIT建立源程序文件FILE.ASM的命令如下:
H:> EDIT FILE.ASM
执行上述命令将出现一个编辑窗口,在此窗口内进行源程序编辑。按“Alt”键可以下拉出菜单选择需要的操作功能。按热键“X”,再按“Enter”键,将保存源文件并退出EDIT编辑窗口。
2)汇编源程序
① 用MASM 6.X版汇编程序进行汇编
H:> ML /c FILE.ASM (只产生目标文件,不进行连接)
或
H:> ML FILE (产生目标文件并自动进行连接,产生可执行文件)
② 用MASM 5.X版汇编程序进行汇编
H:> MASM FILE
Microsoft(R) Macro Assembler Version 5. 01
Copyright(C) Microsoft Corp 1981-1985, 1987. All right reserved.
Object filename [FILE.OBJ]:
Source Listing [NUL.LST]:
cross reference [NUL.CRF]:
0 Warning Errors
0 Sever Errors
汇编无错后,可进行目标文件的连接。
2) 连接
H:> LINK FILE
Microsoft(R) Overlay Linker Version 5.03
Copyright(C) Microsoft Corp 1983-1987. All right reserved.
Run File [FILE.EXE]:
List File [FILE.MAP]:
Libraries [.LIB]:
Definitions File[NUL.DEF]:
3)运行程序
H:> FILE
6.2 四段结构的宏汇编语言程序示例
(1)完整的段定义
例2-1 下面是一个简单的汇编语言源程序,该程序以完整的段定义格式定义了数据段、附加段、堆栈段和代码段,功能是完成字符串传送,将40个星号“*”从数据段传送到附加段。
data segment ;定义数据段
sbuffer db 40 dup (*)
data ends ;数据段结束
extra segment ;定义附加段
dbuffer db 40 dup (?)
extra ends ;附加段结束
stack segment para stack ‘stack’ ;定义堆栈段
db 100 dup(0)
stack ends ;堆栈段结束
code segment ;定义代码段
main proc far ;定义主过程开始
assume cs:code,ds:data,es:extra,ss:stack
start: push ds ;程序执行的起始地址
sub ax,ax
push ax
mov ax,data ;设置数据段地址,初始化DS段寄存器
mov ds,ax
mov ax,extra ;设置附加段地址,初始化ES段寄存器
mov es,ax
lea si,sbuffer ;源字符串存储区首址送SI寄存器
lea di,dbuffer ;目的存储区首址送DI寄存器
cld ;设置方向标志(DF=0)
mov cx,40 ;源字符串长度送CX寄存器
rep movsb ;字符串传送
ret ;返回DOS
main endp ;主过程结束
code ends ;代码段结束
end start ;源程序结束
(2)简化的段定义
例2-2 下面是例2-1源程序的简化段定义格式。
.model small ;定义存储模式
.data ;定义数据段
sbuffer db 40 dup (*)
.data? ;定义data?数据段
dbuffer db 40 dup (?)
.stack 100 ;定义堆栈段(100字节)
.code ;定义代码段
.startup ;定义程序起始点
mov ax,@data ;设置附加段地址,初始化ES段寄存器
mov es,ax
lea si,sbuffer ;源字符串存储区首址送SI寄存器
lea di,dbuffer ;目的存储区首址送DI寄存器
cld ;设置方向标志(DF=0)
mov cx,40 ;源字符串长度送CX寄存器
rep movsb ;字符串传送
.exit 0 ;返回DOS
end ;源程序结束
(3)汇编(同时产生列表文件)、连接并运行
将上述简化段定义源程序建立为源文件stars40.asm后,汇编命令如下:
H:> ML /c /Fl /Sg stars40.asm
上述命令将产生目标文件stars40.obj和列表文件stars40.lst。其中选项/c要求只汇编不连接,选项/Fl要求产生列表文件,选项/Sg要求在列表文件中列出由汇编程序根据伪指令所产生的机器指令。列表文件内容如下:
Microsoft (R) Macro Assembler Version 6.14.8444 03/08/03 15:48:45
stars40.asm Page 1 - 1
.model small
0000 .data
0000 0028 [ sbuffer db 40 dup ('*')
2A
]
0000 .data?
0000 0028 [ dbuffer db 40 dup (?)
00
]
.stack 100
0000 .code
.startup
0000 *@Startup:
0000 BA ---- R * mov dx, DGROUP
0003 8E DA * mov bx, ss
0007 2B DA * sub bx, dx
0009 D1 E3 * shl bx, 001h
000B D1 E3 * shl bx, 001h
000D D1 E3 * shl bx, 001h
000F D1 E3 * shl bx, 001h
0011 FA * cli
0012 8E D2 * mov ss, dx
0014 03 E3 * add sp, bx
0016 FB * sti
0017 B8 ---- R mov ax,@data
001A 8E C0 mov es,ax
001C 8D 36 0000 R lea si,sbuffer
0020 8D 3E 0000 R lea di,dbuffer
0024 FC cld
0025 B9 0028 mov cx,40
0028 F3/ A4 rep movsb
.exit 0
002A B8 4C00 * mov ax, 04C00h
002D CD 21 * int 021h
end
Microsoft (R) Macro Assembler Version 6.14.8444 03/08/03 15:48:45
stars40.asm Symbols 2 - 1
Segments and Groups:
N a m e Size Length Align Combine Class
DGROUP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . GROUP
_DATA . . . . . . . . . . . . . 16 Bit 0028 Word Public 'DATA'
_BSS . . . . . . . . . . . . . . 16 Bit 0028 Word Public 'BSS'
STACK . . . . . . . . . . . . 16 Bit 0064 Para Stack 'STACK'
_TEXT . . . . . . . . . . . . . 16 Bit 002F Word Public 'CODE'
Symbols:
N a m e Type Value Attr
@CodeSize . . . . . . . . . . . Number 0000h
@DataSize . . . . . . . . . . . Number 0000h
@Interface . . . . . . . . . . . Number 0000h
@Model . . . . . . . . . . . . . Number 0002h
@Startup . . . . . . . . . . . . L Near 0000 _TEXT
@code . . . . . . . . . . . . . Text _TEXT
@data . . . . . . . . . . . . . Text DGROUP
@fardata? . . . . . . . . . . . Text FAR_BSS
@fardata . . . . . . . . . . . . Text FAR_DATA
@stack . . . . . . . . . . . . . Text DGROUP
dbuffer . . . . . . . . . . . . Byte 0000 _BSS
sbuffer . . . . . . . . . . . . Byte 0000 _DATA
0 Warnings
0 Errors
对stars40.obj文件进行连接,产生可执行文件stars40.exe,连接命令如下:
H:>LINK stars40
运行可执行文件stars40.exe,命令如下:
H:> stars40
(4)用DEBUG调试和分析stars40.asm程序
① 进入DEBUG时装入stars40.exe程序,如图2.1所示,执行命令:debug stars40.exe。
图2.1 进入DEBUG并装入stars40.exe程序
进入DEBUG后,用r命令显示出装入stars40.exe程序时各寄存器的初值,可供分析代码段、数据段、附加段及堆栈段的存储区分配位置和大小。注意数据段地址为DS=0B90,代码段地址为CS=0BA0。
② 用d命令从DS:0地址开始显示存储区内容(图2.2),前256个字节(存储区地址为0B90H:00H~0B90H:FFH)是程序段前缀(PSP),其中00H-01H字节存放的是INT 20H指令的代码(CD 20),用于结束程序执行,返回DOS(教材第四章详细讨论PSP)。
图2.2 显示程序段前缀(PSP)
③ 继续显示存储区内容(图2.3),可以看到从0B90H:0100H单元开始是代码段存储区,该地址为代码段第一条指令的地址,等价于CS:IP中的段地址和偏移地址0BA0H:0000H。
图2.3 显示源数据区和目的存储区
可以用u命令进行反汇编(如图2.4所示),验证代码段存储区中的指令。从0BA0H:0H单元(等价于0B90H:0100H单元)开始存放着代码段二进制指令,反汇编后得到符号汇编指令(参考前边的列表文件),其中前12条指令是由.startup伪指令展开的一组指令,主要完成初始化DS段寄存器、调整SS和SP寄存器的功能。
图2.4 反汇编列出源代码
④ 从0B90H:0130H单元开始是数据段(见图2.3),数据段中定义了40(28H)个字节的源数据区sbuffer,并初始化为40个“*”,其ASCII码为2AH。从0B90H:0158H单元开始定义了40个字节的目的存储区dbuffer。在程序执行前,dbuffer还没有从sbuffer传送来的40个“*”。
⑤ 用g命令从0BA0H:0000H地址开始执行程序stars40.exe,再执行d命令显示存储区内容,如图2.5所示,从窗口中可以看出,程序执行后,在0B90H:0158H单元开始的目的存储区dbuffer中,已经存放了由0B90H:0130H单元开始的sbuffer传送来的40个“*”。
图2.5 执行]程序并显示dbuffer中的执行结果
⑥ 要进一步分析程序执行过程,可用p命令逐条跟踪程序的执行,如图2.6和2.7所示。
图2.6 开始单步跟踪程序的执行
图2.7 继续跟踪程序的执行
当各个段寄存器初始化完成后(即执行完 mov es,ax指令后),DS=ES=0BA3H,SS:SP调整为0BA3H:00C4H。这是因为对于.small存储模式,规定数据段、附加段、堆栈段共占一段(<=64KB)存储区。0BA3H是相对段内偏移地址为0的段地址,而0B90H是从程序段前缀(PSP)起点开始计数的段地址,二者的关系为0B90H:0130H=0BA3H:0000H,转换为物理地址时是相同的地址,代表相同的存储单元。此外,从程序的执行过程可以看到,源数据区sbuffer(偏移地址为0)和目的存储区dbuffer(偏移地址为28H)是接着连续分配单元的。
当执行了串传送指令repz movsb后,dbuffer存入40个“*”。用d命令从0BA3H:0000H地址开始显示存储单元内容,出现80个“*”,其中sbuffer和dbuffer各存有40个“*”,如图2.8所示,该窗口中的显示结果与图2.3(见该图从0B90H:0130H地址开始的存储单元内容)的显示结果相同。
图2.8 显示目的存储区中的串传送指令执行结果
由于stars40.exe程序没有输出操作,所以程序运行后在屏幕上没有执行结果显示。但是在DEBUG中执行该程序时,可以跟踪执行并查看内存单元数据,因此能看到程序的执行结果,由此也可以体会DEBUG的调试功能。
6.3 实习题
(1)修改例2-1程序,输出传送到目的缓冲区dbuffer中的字符串。
修改提示:
① DS应指向附加段
② dbuffer中的字符串应加字符串结束符$
③ 执行DOS功能调用的9号子功能输出dbuffer中的字符串
(2)写程序,输出演示系统的欢迎词,输出格式的最低要求如下:
***********************************************
* *
* 英文(中文)欢迎词 *
* *
***********************************************
提示:通过编写与调试该程序,掌握两段结构的程序设计、输出数据的格式编排(由ASCII码0AH和0DH控制换行和回车操作)、DOS功能调用,熟悉宏汇编程序调试的上机过程。
(3)编程计算3550H-2320H,按16进制输出计算所得的差1230H。再输出3550H-2321H的差,检验程序的正确性。
提示:考虑依次将1230H(即0001 0010 0011 0000B)从高位到低位,每4位二进制数一组分离出来,再将4位二进制数转换为ASCII码,利用DOS系统功能调用的2号子功能输出,就得到16进制数据的输出效果。本题要求综合应用移位操作、逻辑操作等指令,并利用条件转移指令实现简单的循环程序,程序流程如图2.9所示。
#13
看了一下,感觉非常有用,谢谢你啊!
知道它有多难了,看来还有好长的路要走啊……一定要好好学
知道它有多难了,看来还有好长的路要走啊……一定要好好学
#14
分享是CSDN的宗旨
#15
#1
王爽的 汇编语言 pdf文档 可以在手机上看
不过手机上看不方便
不过手机上看不方便
#2
我也是自动化毕业的,学完c。就学的汇编啊,单片机也用汇编扁的啊。
#3
咱也才入门,看的大灰狼的《零基础汇编视频》,感觉不错,听着不迷糊。楼主可以试试。
之后看的《WinASMRadASM系列培训》,刚看感觉这个写windows程序和用c非常像,除了语法是汇编的,其他流程和C的基本就一样。也非常容易入门。
之后看的《WinASMRadASM系列培训》,刚看感觉这个写windows程序和用c非常像,除了语法是汇编的,其他流程和C的基本就一样。也非常容易入门。
#4
我有电脑但不能联网
呵呵……
#5
可能不同学校安排不同吧!!
#6
给你的建议:
1.先去你的图书馆里面去借一本《 IBM PC 汇编语言程序设计》 或 王爽。
2.有空上一下 看雪论坛,里面有很多工具都是很有用的,而且它基本上是中国最好的了,里面有很多大牛。
3.一定要动手做实验,当你写汇编像用C一样顺手时,你就算是入门了。
本来有很多书都很好的,想介绍一下给你的,就是不知道你们图书馆有没有
《汇编语言程序设计教程》:清大的,比较适合用来入门
《天书夜读 从汇编到到Windows内核编程》理解前面几章用汇编和用C差不多了
其实CSDN上一搜教程一大堆,
我用了大概半个月把一个系统的教程看完了,结果什么都不会编(这个不是打击楼主)。后来都是要等到老师
上课,然后做了一些实验才懂了, 原来汇编也不过如此。
但是自学的话,会遇到很多问题,例如一个最简音的问题:用什么工具,这个工具怎么用。这个可能就要花掉半个月的时间去熟悉,所以 楼主一定要有心理准备,一定要有心理准备去刻服种种问题,不然只凭一时的热度,很难学下去的(不是打击楼主,都是我之前的切身体会)。
最后祝楼主好运吧
1.先去你的图书馆里面去借一本《 IBM PC 汇编语言程序设计》 或 王爽。
2.有空上一下 看雪论坛,里面有很多工具都是很有用的,而且它基本上是中国最好的了,里面有很多大牛。
3.一定要动手做实验,当你写汇编像用C一样顺手时,你就算是入门了。
本来有很多书都很好的,想介绍一下给你的,就是不知道你们图书馆有没有
《汇编语言程序设计教程》:清大的,比较适合用来入门
《天书夜读 从汇编到到Windows内核编程》理解前面几章用汇编和用C差不多了
其实CSDN上一搜教程一大堆,
我用了大概半个月把一个系统的教程看完了,结果什么都不会编(这个不是打击楼主)。后来都是要等到老师
上课,然后做了一些实验才懂了, 原来汇编也不过如此。
但是自学的话,会遇到很多问题,例如一个最简音的问题:用什么工具,这个工具怎么用。这个可能就要花掉半个月的时间去熟悉,所以 楼主一定要有心理准备,一定要有心理准备去刻服种种问题,不然只凭一时的热度,很难学下去的(不是打击楼主,都是我之前的切身体会)。
最后祝楼主好运吧
#7
http://topic.csdn.net/u/20100106/16/fc962cad-600f-4a6e-91ac-9431deb4092d.html?24723
看一下这个贴吧,学汇编的基本上都会看过这几个教程的
看一下这个贴吧,学汇编的基本上都会看过这几个教程的
#8
非常感谢6楼的建议!!!但我具体用什么工具呢
#9
工具:其实用debug 就可以编,但比较多人用的是MASM611(这个是dos 界面,自学的话可能不大会用)
还是去看雪那里去下载吧,里面的那个RedASM就挺好用的。
http://www.pediy.com/tools.htm
这里面就什么工具都齐啦
还是去看雪那里去下载吧,里面的那个RedASM就挺好用的。
http://www.pediy.com/tools.htm
这里面就什么工具都齐啦
#10
花点时间,吃点苦
#11
入门级实验,贴出来给大家看一下吧
实习一 调试工具的使用方法训练(2学时)
1.实验目的
掌握调试工具DEBUG的使用方法,理解汇编指令、存储单元和寄存器等有关概念,能够对简单的汇编语言程序进行调试。
2.实验内容
(1)学习调试工具DEBUG的使用方法,熟悉DEBUG常用命令的功能和用法。
(2)利用DEBUG调试简单的汇编语言程序,体会汇编指令的功能、寄存器的作用、存储单元地址与内容的概念和作用、以及程序的执行过程。
3.实验要求
(1)掌握DEBUG的常用命令和基本的程序调试方法
(2)熟悉和掌握指令系统常用指令的功能和用法,能熟练运用DEBUG调试工具调试简单的程序,并初步掌握使用DOS系统功能调用的方法。
4.重点与难点
存储器和寄存器的概念、各寄存器的用途、常用指令的功能和用法、用DEBUG调试程序的方法。
5.实验结果验收
熟练运用DEBUG调试工具完成本实习6.2节要求的程序设计和调试
6.实验指导
6.1 调试工具DEBUG简介
DEBUG是DOS操作系统为汇编语言程序设计者和系统管理员提供的一个通用调试工具,利用DEBUG可以读写、传送、比较、查找和显示存储器单元内容,设置程序起始执行地址或断点,执行程序或分段执行程序,跟踪程序执行,显示处理器状态,汇编或反汇编程序等。用DEBUG编程简单、方便和直观,可以直接查看程序执行情况,便于熟悉和理解指令,掌握基本编程技巧。
DEBUG只使用十六进制表示数据(十六进制数后不加“H”),屏幕的显示数据形式如下:
1400:0100 24 65 6E 64 73 0D 0A 20-20 63 6F 64 65 20 20 24 *ends..code *
1400:0110 73 65 67 6D 65 6E 74 0D-0A 20 20 20 20 20 20 24 segment.. *
1400:0170 24 61 78 2c 30 0D 0A 09-20 20 20 20 70 75 73 68 *ax,0 push
屏幕每行显示内容分为三部分,一行共显示十六个字节单元的内容。第一部分是本行所显示的16个字节数据在存储器中的起始存放地址;第二部分是以十六进制显示的16个字节数据;第三部分是将本行所显示字节数据看作ASCII码时显示的字符,若某字节数据对应不可显示的ASCII码,则显示一个“.”字符代替该字节数据的显示字符。
DEBUG只有十几条单字母命令,功能强且易掌握,常用DEBUG命令如下:
1)DEBUG的进入和退出
进入DEBUG时,如果要同时装入某程序,键入下面的命令:
H:> DEBUG <文件名> [<参数>]
其中文件名指定要装入的程序目标码文件,其扩展名可以是.COM或.EXE。<参数>是由被装入程序接收的参数。此外,也可以用下面的方式进入DEBUG:
H:> DEBUG
-
“-”是DEBUG的命令提示符,表明已进入DEBUG状态。在“-”提示符之后,可以键入DEBUG命令。
退出DEBUG时,键入如下命令从DEBUG状态返回DOS:
-Q
2)汇编与反汇编命令
汇编命令A和反汇编命令U是常使用的DEBUG命令。
① 汇编命令A
格式:A [<起始地址>]
功能:逐行汇编程序,主要用于小段程序的汇编。
说明:使用A命令汇编程序,不允许程序中出现标号和伪指令,但MS-DOS的DEBUG允许使用DB和DW这两条伪指令。如果未给出起始地址,汇编后的程序代码从指令指针寄存器IP的值指定的地址开始存放。按两次回车键可退出汇编命令A的状态。
例1-1 汇编一段程序,该程序的功能是在屏幕上输出一个大写字母A。
-A 100
1141:0100 MOV DL,41
1141:0102 MOV AH,02
1141:0104 INT 21
1141:0106 INT 20
② 反汇编命令U
格式:U [<地址范围>]
功能:在指定的地址范围内,将二进制机器指令逐条翻译为汇编语言符号指令。
例1-2 将例1-1中汇编的程序进行反汇编
-U 100 107
1141:0100 B241 MOV DL,41
1141:0102 B402 MOV AH,02
1141:0104 CD21 INT 21
1141:0106 CD20 INT 20
3)执行程序命令
在DEBUG下,可以完整地执行程序、分段执行程序或单步执行程序。
① 执行程序命令G
格式:G [=<程序起始地址>] [<断点>…]
功能:完整地或分段执行程序。
说明:G命令可以从头至尾完整地执行程序,如果G命令带有有断点参数,则执行到断点地址时暂停并显示当前各寄存器状态,断点最多允许设置100个。程序正常结束时显示“Program terminated normally”。
例1-3 执行例1-1中汇编的程序。
-G =100
A
Program terminated normally
② 跟踪执行命令P和T
格式:P [=<地址>] [<跟踪条数>]
T [=<地址>] [<跟踪条数>]
功能:跟踪命令P和T可以逐条跟踪指令的执行,以便调试程序。
说明:每条指令执行后都将显示各寄存器的当前值。P命令与T命令的差别是,P命令按程序书写的指令为单位,一次跟踪完一条书写指令(执行一组相关的指令),而T命令按存储单元中存放的指令为单位,一次跟踪一条指令的执行。
例1-4 用P命令跟踪例1-1中的程序。
设程序执行前的各寄存器初值如下,然后开始用P命令跟踪例1-1程序:
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1141 ES=1141 SS=1141 CS=1141 IP=0100 NV UP EI PL NZ NA PO NC
1141:0100 B241 MOV DL,41
-P =100
AX=0000 BX=0000 CX=0000 DX=0041 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1141 ES=1141 SS=1141 CS=1141 IP=0102 NV UP EI PL NZ NA PO NC
1141:0102 B402 MOV AH,02
-P
AX=0200 BX=0000 CX=0000 DX=0041 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1141 ES=1141 SS=1141 CS=1141 IP=0104 NV UP EI PL NZ NA PO NC
1141:0104 CD21 INT 21
-P
A
AX=0241 BX=0000 CX=0000 DX=0041 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1141 ES=1141 SS=1141 CS=1141 IP=0106 NV UP EI PL NZ NA PO NC
1141:0106 CD20 INT 20
-P
Program terminated normally
用P命令只需跟踪执行4次,程序就执行完毕。如果用T命令逐条指令跟踪执行,则将跟踪进入DOS功能调用的软中断服务程序中。
4)显示寄存器命令R
格式:R [<寄存器>]
功能:显示或修改寄存器内容。
说明:当R命令后面不指定寄存器时,显示所有寄存器的内容。
例1-5 显示所有寄存器内容
-R
AX=0100 XB=0000 CX=2000 DX=00000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=07E1 ES=07E1 SS=07E1 CS=07E1 IP=0114 NV UP DI PL NZ NA PO NC
例1-6 修改寄存器内容
要修改某寄存器内容,可在R命令后键入寄存器名,DEBUG将显示出这个寄存器的值,然后键入新值就可修改该寄存器内容。例如修改AX寄存器的内容:
-R AX
AX 4500
:3000
用RF命令可显示和修改标志寄存器FR中的标志位,无论修改哪一位标志位,只需要键入该标志位的表示符号(各标志位的符号表示如表1.1所示),并且标志位值的键入顺序可任意。
例1-7 修改FR寄存器的零标志位和进位标志位。
-RF
NV UP EI PL ZR NA PE CY - NZ NC (修改零标志和进位标志)
-RF
NV UP EI PL NZ NA PE NC - (显示修改结果)
表1.1 标志寄存器各标志位符号及意义
标 志 位 符号表示
=1 =0
OF 溢出(是/否) OV NV
DF 方向(减/增) DN UP
IF 中断(开/关) EI DI
SF 符号(负/正) NG PL
ZF 零(是/否) ZR NZ
AF 辅助进位(是/否) AC NA
PF 奇偶(偶/奇) PE PO
CF 进位(是/否) CY NC
5)存储器单元访问命令
① 显示存储器单元命令D
格式:D [<地址范围>]
功能:显示指定地址范围内的存储区数据,包括十六进制数据形式及其对应的ASCII码字符显示。
例1-8 显示110H到116H存储器单元的内容。
-D 110 116
1540:0110 73 65 67 6D 65 6E 74 segment
② 写存储器单元命令E
格式:E <地址> [<字符串>]
功能:逐个修改指定单元内容或将字节串写入指定的一组连续单元。
例1-9 将字节串string写入以142H为起始地址的存储器区。
-E 142 string
例1-10 逐个单元向彩显视频缓冲区写入41H、42H、41H、42H,彩显视频缓冲区的段地址为B800H,数据写入后立即显示出大写的ABAB。
-E B800:70
B800:0070 30.41 07.00 30.42 07.00 30.41 07.f0 30.42 07.f0
B800:0078 20.
注意,“.”前为存储器单元原内容,“.”后为键入的数据,按空格键继续修改下一个存储器单元。例中前两个AB为正常显示,后两个AB为反相、闪烁显示。
③ 填充命令F
格式:F <地址范围> <要填入的字节或字节串>
功能:在指定地址范围内写入数据。
例1-11 联用R命令和F命令在彩显视频缓冲区中写入一串小写字母a。
-R DS (修改DS,使DS指向彩显缓冲区B8000H)
DS 0000
:B800
-F 0000 0050 61 (在0到50H单元内填满a)
6)读写磁盘命令
读写磁盘有两种方式,一种是按扇区读写,直接使用读写命令即可,另一种是按文件名读写。后一种方法首先要指定读写文件名及待读写数据的字节数,再键入读写命令。
① 按文件名读写
文件名定义命令N
格式:N <文件名> [<文件名>…]
功能:为读写磁盘文件定义文件名。
说明:可以指定多个文件名
例1-12 定义要读写的文件为FILE.COM
-N FILE.COM
② 写盘命令W
格式:W [<地址> [<盘符> <相对扇区号> <扇区数>]
功能:将指定存储区单元内容写入指定盘的扇区或盘文件。
例1-13 把例1-1中的程序存入盘文件DEMO.COM中。
写盘文件操作步骤如下:
-N DEMO.COM (定义文件名)
-R BX (在BX:CX中设置待写数据的字节数)
BX 0000
:
-R CX
CX 0000
:8 (写8个字节到DEMO.COM文件中)
-W 100 (执行写盘文件操作,从100H单元开始取8个字节写盘文件)
Writing 0008 bytes
-
③ 读盘命令L
格式:L [<地址> [<盘符> <相对扇区号> <扇区数>]]
功能:将指定盘文件或扇区的内容读入存储器单元中。
说明:<地址>项为存放读入数据的存储区单元地址,其余项与W命令说明类似。
例1-14 从B盘相对扇区10H(16)开始,读64H(100)个连续扇区的数据,存入起始地址为400H:100H的存储区。
-L 400:100 1 10 64
例1-15 读入文件DEMO.COM,再反汇编该程序。
H:>DEBUG
-N DEMO.COM
-L 100
-U 100 107
1156:0100 B241 MOV DL,41
1156:0102 B402 MOV AH,02
1156:0104 CD21 INT 21
1156:0106 CD20 INT 20
7)其他命令
除以上常用命令外,DEBUG还提供了存储区数据比较命令C、数据查找命令S、数据移动命令M和十六进制数运算命令H等。表1.2列出了DEBUG的全部命令以便于查阅。
表1.2 DEBUG命令表
命令及其功能 格 式
A(Assemble)
汇编源程序 A[<地址>]
U(Unassemble)
对二进制指令代码进行反汇编 U[<地址范围>]
T(Trace)
跟踪执行程序并显示寄存器内容 T[=<地址>][<跟踪条数>]
P(Proceed)
跟踪执行一组相关的指令 P[=<地址>][<跟踪条数>]
D(Dump)
显示存储区数据 D[<地址>]或D[<地址范围>]
E(Enter)
修改存储区数据 E<地址>[<字符串>]
F(Fill)
将成组数据填入存储区 F<地址范围><要填入的字节或字节串>
G(Go)
运行程序 G[=<起始地址>][<断点地址>…]
R(Register)
显示和修改寄存器内容 R[<寄存器>]
N(Name)
定义文件名 N<文件名>[<文件名>…]
续表
命令及其功能 格 式
L(Load)
装入文件或磁盘扇区 L[<地址>][<盘符><相对扇区号><扇区数>]
W(Write)
写文件或写磁盘扇区 W[<地址>[<盘符><相对扇区号><扇区数>]]
M(Move)
传送存储区数据块 M<源地址范围><目的地址>
I(Input)
读/显示端口 I<端口号>
O(Output)
输出数据到端口 O<端口号><字节>
H(Hexarithmetic)
十六进制加减法运算 H<数值><数值>
C(Compare)
比较存储区数据 C<源地址范围><目的地址>
S(Search)
检索字节或字符串 S<地址范围><要检索的字节或字节串>
Q(Quit)
退出DEBUG Q
6.2 实习题
(1)下面的例子可用于调试程序的实验,并且作为几个常用DOS系统功能调用的示范。
① 将大写字母A转换为小写字母a
-A 200
MOV DL,41 ;A->DL
OR DL,20 ;A->a
MOV AH,2 ;功能号-> AH
INT 21 ;调用DOS功能调用2号功能,显示一个字符
INT 20 ;退出程序执行,返回DOS
-G =200
思考并尝试修改程序,实现如下功能:将大写字母B转换为小写字母b。
② 从键盘输入一个字符并回显
-A 220
MOV AH,1 ;功能号-> AH
INT 21 ;调用DOS功能调用1号功能,从键盘接收一个字符
MOV DL,AL ;将接收的字符送DL,准备显示
MOV AH,2 ;功能号-> AH
INT 21 ;调用DOS功能调用2号功能,显示一个字符
INT 20 ;退出程序执行,返回DOS
-G =220
③ 显示字符串
-E 120 ‘How do you do?$’
-A 100
MOV DX,120 ;待显示的字符串地址->DX
MOV AH,9 ;功能号-> AH
INT 21 ;调用DOS功能调用9号功能,显示一个字符串
INT 20 ;退出程序执行,返回DOS
-G =100
思考并尝试修改程序:如果将字符串存放在300H开始的存储区,应该怎样修改程序?
(2)从BX所指的内存单元开始连续存放着两个字数据(被减数和减数),按寄存器间接寻址方式写出指令序列,取得被减数和减数,求两数之差,并将差存放于减数之后。要求计算:
① 3580H-3000H ② 3-5
提示:先用DEBUG的E命令将被减数和减数写入内存某一块存储区(例如以200H为起始地址的存储区),然后在A命令状态下写程序,将数据存储区地址(200H)送入BX寄存器,利用寄存器间接寻址方式访问存储单元中的被减数和减数,再计算差和存放差。
思考并动手尝试:如何查看程序执行结果?
(3)写一指令序列完成以下操作:
① AX寄存器的低6位清0 ② BX寄存器的高4位置1
③ CX寄存器的低8位求反
(4)要求使用串操作指令编写一程序段,先将以400H为起始地址的存储区(40个字节单元)初始化为空格,然后将以500H为起始地址的存储区中的15个字符,传送到以400H为起始地址的存储区中。
(5)利用DEBUG的调试功能,体会、熟悉和掌握指令系统常用指令的使用方法及功能。
实习一 调试工具的使用方法训练(2学时)
1.实验目的
掌握调试工具DEBUG的使用方法,理解汇编指令、存储单元和寄存器等有关概念,能够对简单的汇编语言程序进行调试。
2.实验内容
(1)学习调试工具DEBUG的使用方法,熟悉DEBUG常用命令的功能和用法。
(2)利用DEBUG调试简单的汇编语言程序,体会汇编指令的功能、寄存器的作用、存储单元地址与内容的概念和作用、以及程序的执行过程。
3.实验要求
(1)掌握DEBUG的常用命令和基本的程序调试方法
(2)熟悉和掌握指令系统常用指令的功能和用法,能熟练运用DEBUG调试工具调试简单的程序,并初步掌握使用DOS系统功能调用的方法。
4.重点与难点
存储器和寄存器的概念、各寄存器的用途、常用指令的功能和用法、用DEBUG调试程序的方法。
5.实验结果验收
熟练运用DEBUG调试工具完成本实习6.2节要求的程序设计和调试
6.实验指导
6.1 调试工具DEBUG简介
DEBUG是DOS操作系统为汇编语言程序设计者和系统管理员提供的一个通用调试工具,利用DEBUG可以读写、传送、比较、查找和显示存储器单元内容,设置程序起始执行地址或断点,执行程序或分段执行程序,跟踪程序执行,显示处理器状态,汇编或反汇编程序等。用DEBUG编程简单、方便和直观,可以直接查看程序执行情况,便于熟悉和理解指令,掌握基本编程技巧。
DEBUG只使用十六进制表示数据(十六进制数后不加“H”),屏幕的显示数据形式如下:
1400:0100 24 65 6E 64 73 0D 0A 20-20 63 6F 64 65 20 20 24 *ends..code *
1400:0110 73 65 67 6D 65 6E 74 0D-0A 20 20 20 20 20 20 24 segment.. *
1400:0170 24 61 78 2c 30 0D 0A 09-20 20 20 20 70 75 73 68 *ax,0 push
屏幕每行显示内容分为三部分,一行共显示十六个字节单元的内容。第一部分是本行所显示的16个字节数据在存储器中的起始存放地址;第二部分是以十六进制显示的16个字节数据;第三部分是将本行所显示字节数据看作ASCII码时显示的字符,若某字节数据对应不可显示的ASCII码,则显示一个“.”字符代替该字节数据的显示字符。
DEBUG只有十几条单字母命令,功能强且易掌握,常用DEBUG命令如下:
1)DEBUG的进入和退出
进入DEBUG时,如果要同时装入某程序,键入下面的命令:
H:> DEBUG <文件名> [<参数>]
其中文件名指定要装入的程序目标码文件,其扩展名可以是.COM或.EXE。<参数>是由被装入程序接收的参数。此外,也可以用下面的方式进入DEBUG:
H:> DEBUG
-
“-”是DEBUG的命令提示符,表明已进入DEBUG状态。在“-”提示符之后,可以键入DEBUG命令。
退出DEBUG时,键入如下命令从DEBUG状态返回DOS:
-Q
2)汇编与反汇编命令
汇编命令A和反汇编命令U是常使用的DEBUG命令。
① 汇编命令A
格式:A [<起始地址>]
功能:逐行汇编程序,主要用于小段程序的汇编。
说明:使用A命令汇编程序,不允许程序中出现标号和伪指令,但MS-DOS的DEBUG允许使用DB和DW这两条伪指令。如果未给出起始地址,汇编后的程序代码从指令指针寄存器IP的值指定的地址开始存放。按两次回车键可退出汇编命令A的状态。
例1-1 汇编一段程序,该程序的功能是在屏幕上输出一个大写字母A。
-A 100
1141:0100 MOV DL,41
1141:0102 MOV AH,02
1141:0104 INT 21
1141:0106 INT 20
② 反汇编命令U
格式:U [<地址范围>]
功能:在指定的地址范围内,将二进制机器指令逐条翻译为汇编语言符号指令。
例1-2 将例1-1中汇编的程序进行反汇编
-U 100 107
1141:0100 B241 MOV DL,41
1141:0102 B402 MOV AH,02
1141:0104 CD21 INT 21
1141:0106 CD20 INT 20
3)执行程序命令
在DEBUG下,可以完整地执行程序、分段执行程序或单步执行程序。
① 执行程序命令G
格式:G [=<程序起始地址>] [<断点>…]
功能:完整地或分段执行程序。
说明:G命令可以从头至尾完整地执行程序,如果G命令带有有断点参数,则执行到断点地址时暂停并显示当前各寄存器状态,断点最多允许设置100个。程序正常结束时显示“Program terminated normally”。
例1-3 执行例1-1中汇编的程序。
-G =100
A
Program terminated normally
② 跟踪执行命令P和T
格式:P [=<地址>] [<跟踪条数>]
T [=<地址>] [<跟踪条数>]
功能:跟踪命令P和T可以逐条跟踪指令的执行,以便调试程序。
说明:每条指令执行后都将显示各寄存器的当前值。P命令与T命令的差别是,P命令按程序书写的指令为单位,一次跟踪完一条书写指令(执行一组相关的指令),而T命令按存储单元中存放的指令为单位,一次跟踪一条指令的执行。
例1-4 用P命令跟踪例1-1中的程序。
设程序执行前的各寄存器初值如下,然后开始用P命令跟踪例1-1程序:
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1141 ES=1141 SS=1141 CS=1141 IP=0100 NV UP EI PL NZ NA PO NC
1141:0100 B241 MOV DL,41
-P =100
AX=0000 BX=0000 CX=0000 DX=0041 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1141 ES=1141 SS=1141 CS=1141 IP=0102 NV UP EI PL NZ NA PO NC
1141:0102 B402 MOV AH,02
-P
AX=0200 BX=0000 CX=0000 DX=0041 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1141 ES=1141 SS=1141 CS=1141 IP=0104 NV UP EI PL NZ NA PO NC
1141:0104 CD21 INT 21
-P
A
AX=0241 BX=0000 CX=0000 DX=0041 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1141 ES=1141 SS=1141 CS=1141 IP=0106 NV UP EI PL NZ NA PO NC
1141:0106 CD20 INT 20
-P
Program terminated normally
用P命令只需跟踪执行4次,程序就执行完毕。如果用T命令逐条指令跟踪执行,则将跟踪进入DOS功能调用的软中断服务程序中。
4)显示寄存器命令R
格式:R [<寄存器>]
功能:显示或修改寄存器内容。
说明:当R命令后面不指定寄存器时,显示所有寄存器的内容。
例1-5 显示所有寄存器内容
-R
AX=0100 XB=0000 CX=2000 DX=00000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=07E1 ES=07E1 SS=07E1 CS=07E1 IP=0114 NV UP DI PL NZ NA PO NC
例1-6 修改寄存器内容
要修改某寄存器内容,可在R命令后键入寄存器名,DEBUG将显示出这个寄存器的值,然后键入新值就可修改该寄存器内容。例如修改AX寄存器的内容:
-R AX
AX 4500
:3000
用RF命令可显示和修改标志寄存器FR中的标志位,无论修改哪一位标志位,只需要键入该标志位的表示符号(各标志位的符号表示如表1.1所示),并且标志位值的键入顺序可任意。
例1-7 修改FR寄存器的零标志位和进位标志位。
-RF
NV UP EI PL ZR NA PE CY - NZ NC (修改零标志和进位标志)
-RF
NV UP EI PL NZ NA PE NC - (显示修改结果)
表1.1 标志寄存器各标志位符号及意义
标 志 位 符号表示
=1 =0
OF 溢出(是/否) OV NV
DF 方向(减/增) DN UP
IF 中断(开/关) EI DI
SF 符号(负/正) NG PL
ZF 零(是/否) ZR NZ
AF 辅助进位(是/否) AC NA
PF 奇偶(偶/奇) PE PO
CF 进位(是/否) CY NC
5)存储器单元访问命令
① 显示存储器单元命令D
格式:D [<地址范围>]
功能:显示指定地址范围内的存储区数据,包括十六进制数据形式及其对应的ASCII码字符显示。
例1-8 显示110H到116H存储器单元的内容。
-D 110 116
1540:0110 73 65 67 6D 65 6E 74 segment
② 写存储器单元命令E
格式:E <地址> [<字符串>]
功能:逐个修改指定单元内容或将字节串写入指定的一组连续单元。
例1-9 将字节串string写入以142H为起始地址的存储器区。
-E 142 string
例1-10 逐个单元向彩显视频缓冲区写入41H、42H、41H、42H,彩显视频缓冲区的段地址为B800H,数据写入后立即显示出大写的ABAB。
-E B800:70
B800:0070 30.41 07.00 30.42 07.00 30.41 07.f0 30.42 07.f0
B800:0078 20.
注意,“.”前为存储器单元原内容,“.”后为键入的数据,按空格键继续修改下一个存储器单元。例中前两个AB为正常显示,后两个AB为反相、闪烁显示。
③ 填充命令F
格式:F <地址范围> <要填入的字节或字节串>
功能:在指定地址范围内写入数据。
例1-11 联用R命令和F命令在彩显视频缓冲区中写入一串小写字母a。
-R DS (修改DS,使DS指向彩显缓冲区B8000H)
DS 0000
:B800
-F 0000 0050 61 (在0到50H单元内填满a)
6)读写磁盘命令
读写磁盘有两种方式,一种是按扇区读写,直接使用读写命令即可,另一种是按文件名读写。后一种方法首先要指定读写文件名及待读写数据的字节数,再键入读写命令。
① 按文件名读写
文件名定义命令N
格式:N <文件名> [<文件名>…]
功能:为读写磁盘文件定义文件名。
说明:可以指定多个文件名
例1-12 定义要读写的文件为FILE.COM
-N FILE.COM
② 写盘命令W
格式:W [<地址> [<盘符> <相对扇区号> <扇区数>]
功能:将指定存储区单元内容写入指定盘的扇区或盘文件。
例1-13 把例1-1中的程序存入盘文件DEMO.COM中。
写盘文件操作步骤如下:
-N DEMO.COM (定义文件名)
-R BX (在BX:CX中设置待写数据的字节数)
BX 0000
:
-R CX
CX 0000
:8 (写8个字节到DEMO.COM文件中)
-W 100 (执行写盘文件操作,从100H单元开始取8个字节写盘文件)
Writing 0008 bytes
-
③ 读盘命令L
格式:L [<地址> [<盘符> <相对扇区号> <扇区数>]]
功能:将指定盘文件或扇区的内容读入存储器单元中。
说明:<地址>项为存放读入数据的存储区单元地址,其余项与W命令说明类似。
例1-14 从B盘相对扇区10H(16)开始,读64H(100)个连续扇区的数据,存入起始地址为400H:100H的存储区。
-L 400:100 1 10 64
例1-15 读入文件DEMO.COM,再反汇编该程序。
H:>DEBUG
-N DEMO.COM
-L 100
-U 100 107
1156:0100 B241 MOV DL,41
1156:0102 B402 MOV AH,02
1156:0104 CD21 INT 21
1156:0106 CD20 INT 20
7)其他命令
除以上常用命令外,DEBUG还提供了存储区数据比较命令C、数据查找命令S、数据移动命令M和十六进制数运算命令H等。表1.2列出了DEBUG的全部命令以便于查阅。
表1.2 DEBUG命令表
命令及其功能 格 式
A(Assemble)
汇编源程序 A[<地址>]
U(Unassemble)
对二进制指令代码进行反汇编 U[<地址范围>]
T(Trace)
跟踪执行程序并显示寄存器内容 T[=<地址>][<跟踪条数>]
P(Proceed)
跟踪执行一组相关的指令 P[=<地址>][<跟踪条数>]
D(Dump)
显示存储区数据 D[<地址>]或D[<地址范围>]
E(Enter)
修改存储区数据 E<地址>[<字符串>]
F(Fill)
将成组数据填入存储区 F<地址范围><要填入的字节或字节串>
G(Go)
运行程序 G[=<起始地址>][<断点地址>…]
R(Register)
显示和修改寄存器内容 R[<寄存器>]
N(Name)
定义文件名 N<文件名>[<文件名>…]
续表
命令及其功能 格 式
L(Load)
装入文件或磁盘扇区 L[<地址>][<盘符><相对扇区号><扇区数>]
W(Write)
写文件或写磁盘扇区 W[<地址>[<盘符><相对扇区号><扇区数>]]
M(Move)
传送存储区数据块 M<源地址范围><目的地址>
I(Input)
读/显示端口 I<端口号>
O(Output)
输出数据到端口 O<端口号><字节>
H(Hexarithmetic)
十六进制加减法运算 H<数值><数值>
C(Compare)
比较存储区数据 C<源地址范围><目的地址>
S(Search)
检索字节或字符串 S<地址范围><要检索的字节或字节串>
Q(Quit)
退出DEBUG Q
6.2 实习题
(1)下面的例子可用于调试程序的实验,并且作为几个常用DOS系统功能调用的示范。
① 将大写字母A转换为小写字母a
-A 200
MOV DL,41 ;A->DL
OR DL,20 ;A->a
MOV AH,2 ;功能号-> AH
INT 21 ;调用DOS功能调用2号功能,显示一个字符
INT 20 ;退出程序执行,返回DOS
-G =200
思考并尝试修改程序,实现如下功能:将大写字母B转换为小写字母b。
② 从键盘输入一个字符并回显
-A 220
MOV AH,1 ;功能号-> AH
INT 21 ;调用DOS功能调用1号功能,从键盘接收一个字符
MOV DL,AL ;将接收的字符送DL,准备显示
MOV AH,2 ;功能号-> AH
INT 21 ;调用DOS功能调用2号功能,显示一个字符
INT 20 ;退出程序执行,返回DOS
-G =220
③ 显示字符串
-E 120 ‘How do you do?$’
-A 100
MOV DX,120 ;待显示的字符串地址->DX
MOV AH,9 ;功能号-> AH
INT 21 ;调用DOS功能调用9号功能,显示一个字符串
INT 20 ;退出程序执行,返回DOS
-G =100
思考并尝试修改程序:如果将字符串存放在300H开始的存储区,应该怎样修改程序?
(2)从BX所指的内存单元开始连续存放着两个字数据(被减数和减数),按寄存器间接寻址方式写出指令序列,取得被减数和减数,求两数之差,并将差存放于减数之后。要求计算:
① 3580H-3000H ② 3-5
提示:先用DEBUG的E命令将被减数和减数写入内存某一块存储区(例如以200H为起始地址的存储区),然后在A命令状态下写程序,将数据存储区地址(200H)送入BX寄存器,利用寄存器间接寻址方式访问存储单元中的被减数和减数,再计算差和存放差。
思考并动手尝试:如何查看程序执行结果?
(3)写一指令序列完成以下操作:
① AX寄存器的低6位清0 ② BX寄存器的高4位置1
③ CX寄存器的低8位求反
(4)要求使用串操作指令编写一程序段,先将以400H为起始地址的存储区(40个字节单元)初始化为空格,然后将以500H为起始地址的存储区中的15个字符,传送到以400H为起始地址的存储区中。
(5)利用DEBUG的调试功能,体会、熟悉和掌握指令系统常用指令的使用方法及功能。
#12
实习二 指令系统的应用与程序调试方法(2学时)
1.实验目的
综合应用指令与伪指令编写简单完整的宏汇编语言程序,掌握常用的运算符、伪指令及宏汇编语言程序的结构,理解内存分段管理的方法和原理,熟悉调试宏汇编语言程序的上机过程及方法,掌握基本的循环程序设计方法。
2.实验内容
使用汇编程序ML(或MASM)、连接程序LINK及DEBUG调试简单的宏汇编语言程序,综合应用指令完成基本的循环程序设计。
3.实验要求
综合应用指令与伪指令编写简单完整的宏汇编语言程序,并熟悉汇编、连接及调试的方法和过程,完成实现简单功能的循环程序。
4.重点
掌握常用运算符和伪指令的功能与用法,能正确地编写分段结构的宏汇编语言程序。
5.实验结果验收
(1)编写四段结构和二段结构的宏汇编语言程序并调试成功
(2)编写具有一定实用功能的循环程序并输出程序执行结果
6.实验指导
6.1上机步骤
编辑、汇编、连接、运行汇编语言程序的步骤如下:
1)编辑源程序文件
用EDIT或者任何一种文本编辑工具(如UltraEdit32等)建立源程序文件,注意汇编语言程序源文件扩展名必须是“.ASM”。例如,用EDIT建立源程序文件FILE.ASM的命令如下:
H:> EDIT FILE.ASM
执行上述命令将出现一个编辑窗口,在此窗口内进行源程序编辑。按“Alt”键可以下拉出菜单选择需要的操作功能。按热键“X”,再按“Enter”键,将保存源文件并退出EDIT编辑窗口。
2)汇编源程序
① 用MASM 6.X版汇编程序进行汇编
H:> ML /c FILE.ASM (只产生目标文件,不进行连接)
或
H:> ML FILE (产生目标文件并自动进行连接,产生可执行文件)
② 用MASM 5.X版汇编程序进行汇编
H:> MASM FILE
Microsoft(R) Macro Assembler Version 5. 01
Copyright(C) Microsoft Corp 1981-1985, 1987. All right reserved.
Object filename [FILE.OBJ]:
Source Listing [NUL.LST]:
cross reference [NUL.CRF]:
0 Warning Errors
0 Sever Errors
汇编无错后,可进行目标文件的连接。
2) 连接
H:> LINK FILE
Microsoft(R) Overlay Linker Version 5.03
Copyright(C) Microsoft Corp 1983-1987. All right reserved.
Run File [FILE.EXE]:
List File [FILE.MAP]:
Libraries [.LIB]:
Definitions File[NUL.DEF]:
3)运行程序
H:> FILE
6.2 四段结构的宏汇编语言程序示例
(1)完整的段定义
例2-1 下面是一个简单的汇编语言源程序,该程序以完整的段定义格式定义了数据段、附加段、堆栈段和代码段,功能是完成字符串传送,将40个星号“*”从数据段传送到附加段。
data segment ;定义数据段
sbuffer db 40 dup (*)
data ends ;数据段结束
extra segment ;定义附加段
dbuffer db 40 dup (?)
extra ends ;附加段结束
stack segment para stack ‘stack’ ;定义堆栈段
db 100 dup(0)
stack ends ;堆栈段结束
code segment ;定义代码段
main proc far ;定义主过程开始
assume cs:code,ds:data,es:extra,ss:stack
start: push ds ;程序执行的起始地址
sub ax,ax
push ax
mov ax,data ;设置数据段地址,初始化DS段寄存器
mov ds,ax
mov ax,extra ;设置附加段地址,初始化ES段寄存器
mov es,ax
lea si,sbuffer ;源字符串存储区首址送SI寄存器
lea di,dbuffer ;目的存储区首址送DI寄存器
cld ;设置方向标志(DF=0)
mov cx,40 ;源字符串长度送CX寄存器
rep movsb ;字符串传送
ret ;返回DOS
main endp ;主过程结束
code ends ;代码段结束
end start ;源程序结束
(2)简化的段定义
例2-2 下面是例2-1源程序的简化段定义格式。
.model small ;定义存储模式
.data ;定义数据段
sbuffer db 40 dup (*)
.data? ;定义data?数据段
dbuffer db 40 dup (?)
.stack 100 ;定义堆栈段(100字节)
.code ;定义代码段
.startup ;定义程序起始点
mov ax,@data ;设置附加段地址,初始化ES段寄存器
mov es,ax
lea si,sbuffer ;源字符串存储区首址送SI寄存器
lea di,dbuffer ;目的存储区首址送DI寄存器
cld ;设置方向标志(DF=0)
mov cx,40 ;源字符串长度送CX寄存器
rep movsb ;字符串传送
.exit 0 ;返回DOS
end ;源程序结束
(3)汇编(同时产生列表文件)、连接并运行
将上述简化段定义源程序建立为源文件stars40.asm后,汇编命令如下:
H:> ML /c /Fl /Sg stars40.asm
上述命令将产生目标文件stars40.obj和列表文件stars40.lst。其中选项/c要求只汇编不连接,选项/Fl要求产生列表文件,选项/Sg要求在列表文件中列出由汇编程序根据伪指令所产生的机器指令。列表文件内容如下:
Microsoft (R) Macro Assembler Version 6.14.8444 03/08/03 15:48:45
stars40.asm Page 1 - 1
.model small
0000 .data
0000 0028 [ sbuffer db 40 dup ('*')
2A
]
0000 .data?
0000 0028 [ dbuffer db 40 dup (?)
00
]
.stack 100
0000 .code
.startup
0000 *@Startup:
0000 BA ---- R * mov dx, DGROUP
0003 8E DA * mov bx, ss
0007 2B DA * sub bx, dx
0009 D1 E3 * shl bx, 001h
000B D1 E3 * shl bx, 001h
000D D1 E3 * shl bx, 001h
000F D1 E3 * shl bx, 001h
0011 FA * cli
0012 8E D2 * mov ss, dx
0014 03 E3 * add sp, bx
0016 FB * sti
0017 B8 ---- R mov ax,@data
001A 8E C0 mov es,ax
001C 8D 36 0000 R lea si,sbuffer
0020 8D 3E 0000 R lea di,dbuffer
0024 FC cld
0025 B9 0028 mov cx,40
0028 F3/ A4 rep movsb
.exit 0
002A B8 4C00 * mov ax, 04C00h
002D CD 21 * int 021h
end
Microsoft (R) Macro Assembler Version 6.14.8444 03/08/03 15:48:45
stars40.asm Symbols 2 - 1
Segments and Groups:
N a m e Size Length Align Combine Class
DGROUP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . GROUP
_DATA . . . . . . . . . . . . . 16 Bit 0028 Word Public 'DATA'
_BSS . . . . . . . . . . . . . . 16 Bit 0028 Word Public 'BSS'
STACK . . . . . . . . . . . . 16 Bit 0064 Para Stack 'STACK'
_TEXT . . . . . . . . . . . . . 16 Bit 002F Word Public 'CODE'
Symbols:
N a m e Type Value Attr
@CodeSize . . . . . . . . . . . Number 0000h
@DataSize . . . . . . . . . . . Number 0000h
@Interface . . . . . . . . . . . Number 0000h
@Model . . . . . . . . . . . . . Number 0002h
@Startup . . . . . . . . . . . . L Near 0000 _TEXT
@code . . . . . . . . . . . . . Text _TEXT
@data . . . . . . . . . . . . . Text DGROUP
@fardata? . . . . . . . . . . . Text FAR_BSS
@fardata . . . . . . . . . . . . Text FAR_DATA
@stack . . . . . . . . . . . . . Text DGROUP
dbuffer . . . . . . . . . . . . Byte 0000 _BSS
sbuffer . . . . . . . . . . . . Byte 0000 _DATA
0 Warnings
0 Errors
对stars40.obj文件进行连接,产生可执行文件stars40.exe,连接命令如下:
H:>LINK stars40
运行可执行文件stars40.exe,命令如下:
H:> stars40
(4)用DEBUG调试和分析stars40.asm程序
① 进入DEBUG时装入stars40.exe程序,如图2.1所示,执行命令:debug stars40.exe。
图2.1 进入DEBUG并装入stars40.exe程序
进入DEBUG后,用r命令显示出装入stars40.exe程序时各寄存器的初值,可供分析代码段、数据段、附加段及堆栈段的存储区分配位置和大小。注意数据段地址为DS=0B90,代码段地址为CS=0BA0。
② 用d命令从DS:0地址开始显示存储区内容(图2.2),前256个字节(存储区地址为0B90H:00H~0B90H:FFH)是程序段前缀(PSP),其中00H-01H字节存放的是INT 20H指令的代码(CD 20),用于结束程序执行,返回DOS(教材第四章详细讨论PSP)。
图2.2 显示程序段前缀(PSP)
③ 继续显示存储区内容(图2.3),可以看到从0B90H:0100H单元开始是代码段存储区,该地址为代码段第一条指令的地址,等价于CS:IP中的段地址和偏移地址0BA0H:0000H。
图2.3 显示源数据区和目的存储区
可以用u命令进行反汇编(如图2.4所示),验证代码段存储区中的指令。从0BA0H:0H单元(等价于0B90H:0100H单元)开始存放着代码段二进制指令,反汇编后得到符号汇编指令(参考前边的列表文件),其中前12条指令是由.startup伪指令展开的一组指令,主要完成初始化DS段寄存器、调整SS和SP寄存器的功能。
图2.4 反汇编列出源代码
④ 从0B90H:0130H单元开始是数据段(见图2.3),数据段中定义了40(28H)个字节的源数据区sbuffer,并初始化为40个“*”,其ASCII码为2AH。从0B90H:0158H单元开始定义了40个字节的目的存储区dbuffer。在程序执行前,dbuffer还没有从sbuffer传送来的40个“*”。
⑤ 用g命令从0BA0H:0000H地址开始执行程序stars40.exe,再执行d命令显示存储区内容,如图2.5所示,从窗口中可以看出,程序执行后,在0B90H:0158H单元开始的目的存储区dbuffer中,已经存放了由0B90H:0130H单元开始的sbuffer传送来的40个“*”。
图2.5 执行]程序并显示dbuffer中的执行结果
⑥ 要进一步分析程序执行过程,可用p命令逐条跟踪程序的执行,如图2.6和2.7所示。
图2.6 开始单步跟踪程序的执行
图2.7 继续跟踪程序的执行
当各个段寄存器初始化完成后(即执行完 mov es,ax指令后),DS=ES=0BA3H,SS:SP调整为0BA3H:00C4H。这是因为对于.small存储模式,规定数据段、附加段、堆栈段共占一段(<=64KB)存储区。0BA3H是相对段内偏移地址为0的段地址,而0B90H是从程序段前缀(PSP)起点开始计数的段地址,二者的关系为0B90H:0130H=0BA3H:0000H,转换为物理地址时是相同的地址,代表相同的存储单元。此外,从程序的执行过程可以看到,源数据区sbuffer(偏移地址为0)和目的存储区dbuffer(偏移地址为28H)是接着连续分配单元的。
当执行了串传送指令repz movsb后,dbuffer存入40个“*”。用d命令从0BA3H:0000H地址开始显示存储单元内容,出现80个“*”,其中sbuffer和dbuffer各存有40个“*”,如图2.8所示,该窗口中的显示结果与图2.3(见该图从0B90H:0130H地址开始的存储单元内容)的显示结果相同。
图2.8 显示目的存储区中的串传送指令执行结果
由于stars40.exe程序没有输出操作,所以程序运行后在屏幕上没有执行结果显示。但是在DEBUG中执行该程序时,可以跟踪执行并查看内存单元数据,因此能看到程序的执行结果,由此也可以体会DEBUG的调试功能。
6.3 实习题
(1)修改例2-1程序,输出传送到目的缓冲区dbuffer中的字符串。
修改提示:
① DS应指向附加段
② dbuffer中的字符串应加字符串结束符$
③ 执行DOS功能调用的9号子功能输出dbuffer中的字符串
(2)写程序,输出演示系统的欢迎词,输出格式的最低要求如下:
***********************************************
* *
* 英文(中文)欢迎词 *
* *
***********************************************
提示:通过编写与调试该程序,掌握两段结构的程序设计、输出数据的格式编排(由ASCII码0AH和0DH控制换行和回车操作)、DOS功能调用,熟悉宏汇编程序调试的上机过程。
(3)编程计算3550H-2320H,按16进制输出计算所得的差1230H。再输出3550H-2321H的差,检验程序的正确性。
提示:考虑依次将1230H(即0001 0010 0011 0000B)从高位到低位,每4位二进制数一组分离出来,再将4位二进制数转换为ASCII码,利用DOS系统功能调用的2号子功能输出,就得到16进制数据的输出效果。本题要求综合应用移位操作、逻辑操作等指令,并利用条件转移指令实现简单的循环程序,程序流程如图2.9所示。
1.实验目的
综合应用指令与伪指令编写简单完整的宏汇编语言程序,掌握常用的运算符、伪指令及宏汇编语言程序的结构,理解内存分段管理的方法和原理,熟悉调试宏汇编语言程序的上机过程及方法,掌握基本的循环程序设计方法。
2.实验内容
使用汇编程序ML(或MASM)、连接程序LINK及DEBUG调试简单的宏汇编语言程序,综合应用指令完成基本的循环程序设计。
3.实验要求
综合应用指令与伪指令编写简单完整的宏汇编语言程序,并熟悉汇编、连接及调试的方法和过程,完成实现简单功能的循环程序。
4.重点
掌握常用运算符和伪指令的功能与用法,能正确地编写分段结构的宏汇编语言程序。
5.实验结果验收
(1)编写四段结构和二段结构的宏汇编语言程序并调试成功
(2)编写具有一定实用功能的循环程序并输出程序执行结果
6.实验指导
6.1上机步骤
编辑、汇编、连接、运行汇编语言程序的步骤如下:
1)编辑源程序文件
用EDIT或者任何一种文本编辑工具(如UltraEdit32等)建立源程序文件,注意汇编语言程序源文件扩展名必须是“.ASM”。例如,用EDIT建立源程序文件FILE.ASM的命令如下:
H:> EDIT FILE.ASM
执行上述命令将出现一个编辑窗口,在此窗口内进行源程序编辑。按“Alt”键可以下拉出菜单选择需要的操作功能。按热键“X”,再按“Enter”键,将保存源文件并退出EDIT编辑窗口。
2)汇编源程序
① 用MASM 6.X版汇编程序进行汇编
H:> ML /c FILE.ASM (只产生目标文件,不进行连接)
或
H:> ML FILE (产生目标文件并自动进行连接,产生可执行文件)
② 用MASM 5.X版汇编程序进行汇编
H:> MASM FILE
Microsoft(R) Macro Assembler Version 5. 01
Copyright(C) Microsoft Corp 1981-1985, 1987. All right reserved.
Object filename [FILE.OBJ]:
Source Listing [NUL.LST]:
cross reference [NUL.CRF]:
0 Warning Errors
0 Sever Errors
汇编无错后,可进行目标文件的连接。
2) 连接
H:> LINK FILE
Microsoft(R) Overlay Linker Version 5.03
Copyright(C) Microsoft Corp 1983-1987. All right reserved.
Run File [FILE.EXE]:
List File [FILE.MAP]:
Libraries [.LIB]:
Definitions File[NUL.DEF]:
3)运行程序
H:> FILE
6.2 四段结构的宏汇编语言程序示例
(1)完整的段定义
例2-1 下面是一个简单的汇编语言源程序,该程序以完整的段定义格式定义了数据段、附加段、堆栈段和代码段,功能是完成字符串传送,将40个星号“*”从数据段传送到附加段。
data segment ;定义数据段
sbuffer db 40 dup (*)
data ends ;数据段结束
extra segment ;定义附加段
dbuffer db 40 dup (?)
extra ends ;附加段结束
stack segment para stack ‘stack’ ;定义堆栈段
db 100 dup(0)
stack ends ;堆栈段结束
code segment ;定义代码段
main proc far ;定义主过程开始
assume cs:code,ds:data,es:extra,ss:stack
start: push ds ;程序执行的起始地址
sub ax,ax
push ax
mov ax,data ;设置数据段地址,初始化DS段寄存器
mov ds,ax
mov ax,extra ;设置附加段地址,初始化ES段寄存器
mov es,ax
lea si,sbuffer ;源字符串存储区首址送SI寄存器
lea di,dbuffer ;目的存储区首址送DI寄存器
cld ;设置方向标志(DF=0)
mov cx,40 ;源字符串长度送CX寄存器
rep movsb ;字符串传送
ret ;返回DOS
main endp ;主过程结束
code ends ;代码段结束
end start ;源程序结束
(2)简化的段定义
例2-2 下面是例2-1源程序的简化段定义格式。
.model small ;定义存储模式
.data ;定义数据段
sbuffer db 40 dup (*)
.data? ;定义data?数据段
dbuffer db 40 dup (?)
.stack 100 ;定义堆栈段(100字节)
.code ;定义代码段
.startup ;定义程序起始点
mov ax,@data ;设置附加段地址,初始化ES段寄存器
mov es,ax
lea si,sbuffer ;源字符串存储区首址送SI寄存器
lea di,dbuffer ;目的存储区首址送DI寄存器
cld ;设置方向标志(DF=0)
mov cx,40 ;源字符串长度送CX寄存器
rep movsb ;字符串传送
.exit 0 ;返回DOS
end ;源程序结束
(3)汇编(同时产生列表文件)、连接并运行
将上述简化段定义源程序建立为源文件stars40.asm后,汇编命令如下:
H:> ML /c /Fl /Sg stars40.asm
上述命令将产生目标文件stars40.obj和列表文件stars40.lst。其中选项/c要求只汇编不连接,选项/Fl要求产生列表文件,选项/Sg要求在列表文件中列出由汇编程序根据伪指令所产生的机器指令。列表文件内容如下:
Microsoft (R) Macro Assembler Version 6.14.8444 03/08/03 15:48:45
stars40.asm Page 1 - 1
.model small
0000 .data
0000 0028 [ sbuffer db 40 dup ('*')
2A
]
0000 .data?
0000 0028 [ dbuffer db 40 dup (?)
00
]
.stack 100
0000 .code
.startup
0000 *@Startup:
0000 BA ---- R * mov dx, DGROUP
0003 8E DA * mov bx, ss
0007 2B DA * sub bx, dx
0009 D1 E3 * shl bx, 001h
000B D1 E3 * shl bx, 001h
000D D1 E3 * shl bx, 001h
000F D1 E3 * shl bx, 001h
0011 FA * cli
0012 8E D2 * mov ss, dx
0014 03 E3 * add sp, bx
0016 FB * sti
0017 B8 ---- R mov ax,@data
001A 8E C0 mov es,ax
001C 8D 36 0000 R lea si,sbuffer
0020 8D 3E 0000 R lea di,dbuffer
0024 FC cld
0025 B9 0028 mov cx,40
0028 F3/ A4 rep movsb
.exit 0
002A B8 4C00 * mov ax, 04C00h
002D CD 21 * int 021h
end
Microsoft (R) Macro Assembler Version 6.14.8444 03/08/03 15:48:45
stars40.asm Symbols 2 - 1
Segments and Groups:
N a m e Size Length Align Combine Class
DGROUP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . GROUP
_DATA . . . . . . . . . . . . . 16 Bit 0028 Word Public 'DATA'
_BSS . . . . . . . . . . . . . . 16 Bit 0028 Word Public 'BSS'
STACK . . . . . . . . . . . . 16 Bit 0064 Para Stack 'STACK'
_TEXT . . . . . . . . . . . . . 16 Bit 002F Word Public 'CODE'
Symbols:
N a m e Type Value Attr
@CodeSize . . . . . . . . . . . Number 0000h
@DataSize . . . . . . . . . . . Number 0000h
@Interface . . . . . . . . . . . Number 0000h
@Model . . . . . . . . . . . . . Number 0002h
@Startup . . . . . . . . . . . . L Near 0000 _TEXT
@code . . . . . . . . . . . . . Text _TEXT
@data . . . . . . . . . . . . . Text DGROUP
@fardata? . . . . . . . . . . . Text FAR_BSS
@fardata . . . . . . . . . . . . Text FAR_DATA
@stack . . . . . . . . . . . . . Text DGROUP
dbuffer . . . . . . . . . . . . Byte 0000 _BSS
sbuffer . . . . . . . . . . . . Byte 0000 _DATA
0 Warnings
0 Errors
对stars40.obj文件进行连接,产生可执行文件stars40.exe,连接命令如下:
H:>LINK stars40
运行可执行文件stars40.exe,命令如下:
H:> stars40
(4)用DEBUG调试和分析stars40.asm程序
① 进入DEBUG时装入stars40.exe程序,如图2.1所示,执行命令:debug stars40.exe。
图2.1 进入DEBUG并装入stars40.exe程序
进入DEBUG后,用r命令显示出装入stars40.exe程序时各寄存器的初值,可供分析代码段、数据段、附加段及堆栈段的存储区分配位置和大小。注意数据段地址为DS=0B90,代码段地址为CS=0BA0。
② 用d命令从DS:0地址开始显示存储区内容(图2.2),前256个字节(存储区地址为0B90H:00H~0B90H:FFH)是程序段前缀(PSP),其中00H-01H字节存放的是INT 20H指令的代码(CD 20),用于结束程序执行,返回DOS(教材第四章详细讨论PSP)。
图2.2 显示程序段前缀(PSP)
③ 继续显示存储区内容(图2.3),可以看到从0B90H:0100H单元开始是代码段存储区,该地址为代码段第一条指令的地址,等价于CS:IP中的段地址和偏移地址0BA0H:0000H。
图2.3 显示源数据区和目的存储区
可以用u命令进行反汇编(如图2.4所示),验证代码段存储区中的指令。从0BA0H:0H单元(等价于0B90H:0100H单元)开始存放着代码段二进制指令,反汇编后得到符号汇编指令(参考前边的列表文件),其中前12条指令是由.startup伪指令展开的一组指令,主要完成初始化DS段寄存器、调整SS和SP寄存器的功能。
图2.4 反汇编列出源代码
④ 从0B90H:0130H单元开始是数据段(见图2.3),数据段中定义了40(28H)个字节的源数据区sbuffer,并初始化为40个“*”,其ASCII码为2AH。从0B90H:0158H单元开始定义了40个字节的目的存储区dbuffer。在程序执行前,dbuffer还没有从sbuffer传送来的40个“*”。
⑤ 用g命令从0BA0H:0000H地址开始执行程序stars40.exe,再执行d命令显示存储区内容,如图2.5所示,从窗口中可以看出,程序执行后,在0B90H:0158H单元开始的目的存储区dbuffer中,已经存放了由0B90H:0130H单元开始的sbuffer传送来的40个“*”。
图2.5 执行]程序并显示dbuffer中的执行结果
⑥ 要进一步分析程序执行过程,可用p命令逐条跟踪程序的执行,如图2.6和2.7所示。
图2.6 开始单步跟踪程序的执行
图2.7 继续跟踪程序的执行
当各个段寄存器初始化完成后(即执行完 mov es,ax指令后),DS=ES=0BA3H,SS:SP调整为0BA3H:00C4H。这是因为对于.small存储模式,规定数据段、附加段、堆栈段共占一段(<=64KB)存储区。0BA3H是相对段内偏移地址为0的段地址,而0B90H是从程序段前缀(PSP)起点开始计数的段地址,二者的关系为0B90H:0130H=0BA3H:0000H,转换为物理地址时是相同的地址,代表相同的存储单元。此外,从程序的执行过程可以看到,源数据区sbuffer(偏移地址为0)和目的存储区dbuffer(偏移地址为28H)是接着连续分配单元的。
当执行了串传送指令repz movsb后,dbuffer存入40个“*”。用d命令从0BA3H:0000H地址开始显示存储单元内容,出现80个“*”,其中sbuffer和dbuffer各存有40个“*”,如图2.8所示,该窗口中的显示结果与图2.3(见该图从0B90H:0130H地址开始的存储单元内容)的显示结果相同。
图2.8 显示目的存储区中的串传送指令执行结果
由于stars40.exe程序没有输出操作,所以程序运行后在屏幕上没有执行结果显示。但是在DEBUG中执行该程序时,可以跟踪执行并查看内存单元数据,因此能看到程序的执行结果,由此也可以体会DEBUG的调试功能。
6.3 实习题
(1)修改例2-1程序,输出传送到目的缓冲区dbuffer中的字符串。
修改提示:
① DS应指向附加段
② dbuffer中的字符串应加字符串结束符$
③ 执行DOS功能调用的9号子功能输出dbuffer中的字符串
(2)写程序,输出演示系统的欢迎词,输出格式的最低要求如下:
***********************************************
* *
* 英文(中文)欢迎词 *
* *
***********************************************
提示:通过编写与调试该程序,掌握两段结构的程序设计、输出数据的格式编排(由ASCII码0AH和0DH控制换行和回车操作)、DOS功能调用,熟悉宏汇编程序调试的上机过程。
(3)编程计算3550H-2320H,按16进制输出计算所得的差1230H。再输出3550H-2321H的差,检验程序的正确性。
提示:考虑依次将1230H(即0001 0010 0011 0000B)从高位到低位,每4位二进制数一组分离出来,再将4位二进制数转换为ASCII码,利用DOS系统功能调用的2号子功能输出,就得到16进制数据的输出效果。本题要求综合应用移位操作、逻辑操作等指令,并利用条件转移指令实现简单的循环程序,程序流程如图2.9所示。
#13
看了一下,感觉非常有用,谢谢你啊!
知道它有多难了,看来还有好长的路要走啊……一定要好好学
知道它有多难了,看来还有好长的路要走啊……一定要好好学
#14
分享是CSDN的宗旨