片头第一章 软件设计基础
1-1 系统软件及功能
1-2 汇编源程序 详细步骤
本章主要介绍在 PC系列微机上上机操作的全过程,及所用系统软件的基本功能。
1-3 汇编源程序 一般结构目录
1-1 在 80X86系列微机上运行汇编源程序所必须具备的系统软件及功能一,编辑程序 ( EDIT,SK编辑器) —— 其作用是建立与修改源文件。(,ASM文件 )
二.宏汇编程序 ( MASM或 TASM) —— 将汇编源文件翻译成目标文件(,OBJ文件 )
三.连接程序 ( LINK) —— 把各种语言 (如汇编、
PASCAL,C)编译产生的目标模块连接起来,形成可执行文件(,EXE)。
四.调试程序 ( DEBUG或 TDEBUG) —— 提供一个控制测试的环境,以便用户能够监视和控制被调试程的执行;可以直接确定程序中出现的问题,然后立即执行程序,以便判定这些问题是否已经解决。它是一个交互式的机器语言程序的调试程序,是一个有用的调试工具。
早期的开发是依靠单一功能的各个独立软件来完成这些步骤的。使用较普通的是 MASM,适用于 MS-
DOS操作系统,集成开发环境则将执行上述步骤的分立软件集成在一个功能强大的软件包中,进入开发环境后,开发者就能方便自如地在编辑、汇编、
链接,调试之间任意切换,从而大大提高了应用程序开发效率 。
适应目前 Windows环境的产品亦有不少,在此我们只介绍 FASM (Flat Assembler),又称 未来汇编 。
未来汇编主界面包含了 5个菜单,(这些主菜单都包含了子菜单。除鼠标点击外,还可以通过以下键盘操作来 选择主菜单 ﹕
ALT+F,选择,文件,菜单 — 主要用于文件管理 ﹔
ALT+E,选择,编辑,菜单 — 主要用于源程序的编辑 ;
ALT+P,选择,程序,菜单 — 主要用于程序的编译,
连接,运行与调试 ﹔
ALT+O,选择,选项,菜单 — 主要用于集成环境的设置
ALT+H,选择,帮助,菜单 — 在线帮助与版本信息等 。
可以通过小键盘上的左右键在主菜单之间进行切换,使用小键盘上的上下键可以选择子菜单中的菜单项 。
选中要执行的菜单项,键入 Enter 键即可执行相应操作 。
回章首
1-2 在 80X86系列微机上运行汇编源程序的 详细步骤下面结合一个简单的程序来介绍未来 汇编的详细操作步骤。
例 1.1 两单元内容交换
.586 ;方式选择 586实地址方式
stack segment stack ‘stack ‘ ; 堆栈段开始
dw 32 dup(?) ; 预留堆栈区
stack ends ; 堆栈段结束
data segment use16 ; 数据段开始,16位地址方式
DAT1 DB 11H
DAT2 DB 22H
data ends ; 数据段结束
code segment use16 ; 代码段开始,16位地址方式
begin proc far ; 远过程调用开始
assume cs:code,ss:stck,ds:data ; 设定段
push ds ; PSP的 DS,0000进栈保护
sub ax,ax
push ax
mov ax,data ; 设定用户数据段
mov ds,ax
MOV AL,DAT1
XCHG AL,DAT2
MOV DAT1,AL
ret ; 返回 DOS
begin endp ; 过程调用结束
code ends ; 代码段结束
end begin ; 源 程序 结束上述 程序使用 未来 汇编进行编译,汇编,连接,运行的详细操作步骤如下:
1.点击,开始,→,程序,→ 未来汇编,进入未来汇编的主界面。
2.在编辑窗口中键入以上汇编源程序,并检查无误。
3.点击主菜单中的,文件,选择,保存,,在弹出的对话框中 键入文件名 L1-1,该文件的扩展名默认为
.ASM,再点击,保存,,输入的 L1-1,ASM文件即存为源代码文件。
4.点击主菜单中,程序,栏中的,编译,或按快捷键,
系统对源程序进行汇编,生成扩展名为,OBJ的目标文件。
编译后在屏幕下方显示编译结果。
若有错误,则显示错误行号及错误性质。
如,若将主程序段(大写字母部分)第一行误输为;
MOV AL,DAT
则显示下列信息:
**Error** l1-1.ASM(18) Undefined symbol:DAT
Error messages,1 ; 一个错误
Warning messages,0 ; 0 警告
Passes,1
Remaining memory,381K
将 DAT改为 DAT1后再 点击编辑命令;
若无错误,则显下列信息:
Error messages,0 ; 0个错误
Warning messages,0 ; 0 警告
Passes,1
Remaining memory,381K
5.点击主菜单中,程序,栏中的,连接,或按快捷键,
系统将先前生成的,OBJ的目标文件连接成扩为,EXE
的执行文件。
并显下列信息:
Turbo Link Version 7.1.30.1,Copyright(c)1987,
1996 Borland International
6,运行程序本地方式,
点击菜单,程序,栏中的,运行,;
弹出程序运行窗口,运行程序 ;
按 任意键即返回 FASM 主界面,结束程序的运行。
但有的程序没有直接显示结果;对于较复杂程序难免会出现错误,直接观察很难找到错误所在,这样就要借用调试程序进行调试。
DEBUG调试,
1.简介点击主菜单中的,程序,栏中的,调试,,进入 调试界面,调试的对象是扩展名为,EXE或,COM的可执行文件。
调试窗口上方是调试 菜单栏,中间是 程序调试区,
下方是调试中可使用的 热键提示信息 。
调试 菜单包含 9个子菜单栏:
File,Edit,Run ……
快捷键包含 F1∽F9,各键功能见 P14。
2.调试以调试 L1-1.EXE为例,
(1)点击主菜单中的,程序,栏中的,调试,,进入调试界面。在 View菜单中 点击,CPU”,弹出 调试窗口,调试窗口划分为 5个显示区:
上方从左至右分别为 代码段,寄存器与 标志位 3个显示区,下方为 数据段,堆栈段 2个 显示区。
通过鼠标可在这 5个窗口间进行选择。
通过窗口的 [↑],[↓][ ] 打开、关闭窗口;
[?]返回上级采单。
此时,代码段显示 反汇编 出来的 源程序 和对应的 机器码指令,所有的 寄存器和标志位显示 初始状态 。
如,代码段显示:
1127:0000 1E PUSH DS
1127:0001 2BC0 SUB AX,AX
1127:0003 50 PUSH AX
1127:0004 B82611 MOV AX,DATA
1127:0007 8ED8 MOV DS,AX
1127:0009 A00000 MOV AL,DAT1
1127:000C 86060100 XCHG AL,DAT2
1127:0010 A20000 MOV DAT1,AL
1127:0013 CB RETF
寄存器显示:
ax 0000 sp 0040
bx 0000 ds 1112
cx 0000 es 1112
dx 0000 ss 1122
si 0000 cs 1127
di 0000 ip 0000
sp 0000
SS=DS+PSP长度 /10=( 11120+100) /10=1122
DS=SS+堆栈长度 ( 16的整数倍 ) /10=( 11220+40) /10
=1126
CS=DS+数据长度 ( 16的整数倍 ) /10=( 11260+10) /10
=1127
PSP数据段用户 数据段数据段显示:
DS,0000 CD 20 00 00 00 00 00 00
DS,0008 00 00 00 00 00 00 00 00
根据上述寄存器内容可画出 L1-1.EXE的 内存映象图。
ES=DS=1112 PSP( 100HB)
SS=1122 堆栈段( 40)
用户 DS=1126 数据段( 10)
CS=1127 代码段注意:下列操作都是在调试窗口下进行 。
( 2) 单步运行:
F7—— 执行一条指令,显示所有寄存器及标志寄存器的内容 。
F8—— 执行完一个调用过程,其它同 F7。
( 3) 设断点运行 ——系统从当前代码段开始执行指令,直至执行到光标处 。
( 4) 寄存器检查,
主菜单 VIEW→REG —— 显示当前所有寄存器的内容
( 5) 存储器检查,
主菜单 VIEW→DUMP ——显示当前地址 ( DS,****)
下的存储单元的内容 。
( 6) 光标移至数据段 ( DS,ES),代码段 ( CS)
堆栈段 ( SS),寄存器显示区时:
Ctrl+ G —— 指定需要显示的显示区首地址
Ctrl+ C —— 修改指定单元 ( 寄存器,存储器堆栈 ) 的内容 。
( 7) 光标移至标志寄存器时:
Ctrl+ T —— 翻转改变光标指示的标志位状态 。
例如 L1-1.EXE的调试:
主菜单 VIEW?DUMP,数据段显示:
DS,0000 CD 20 …
此时看到的是 PSP数据段 的信息。
用 F7或 F8命令单步执行,如 执行 5句 。
主菜单 VIEW?DUMP,查看 用户数据段,显示:
DS,0000 11 22
通过窗口的 [↑][↓] 箭头可打开或关小数据窗口。
再单步 执行 4句,注意观察寄存器内容。
按 [↑] 箭头可打开数据窗口,可见:
DS,0000 22 11
说明程序正确。
回章首
1-3 汇编源程序设计的一般结构下面通过一个简单的程序来介绍汇编语言程序的一般结构 。
例,L1-2 编写并调试程序,要求在屏幕上显示字符串 good。
1,使用常规段定义结构的程序:
.586
stack segment stack 'stack' ; 堆栈段开始
dw 32 dup(?) ; 预留堆栈区
stack ends ; 堆栈段结束
Data segment use16 ; 数据段开始,16位地址方式
SUMS DB 'good','$'
data ends ; 数据段结束
code segment use16 ; 代码段开始,16位地址方式
begin proc far ; 远过程调用开始
assume ss:stack,cs:code,ds:data
push ds ; PSP的 DS,0000进栈保护
sub ax,ax
push ax
mov ax,data
mov ds,ax ; 用户数据段 DATA→DS
MOV DX,OFFSET SUMS ; 显示 good
MOV AH,9
INT 21H
ret ; 返回 DOS
begin endp ; 过程调用结束
code ends ; 代码段结束
end begin ; 源程序结束通过本地方式运行上述程序,此时屏幕显示字串
Good,按任意键即返回 FASM主界面,结束程序运行 。
进入 DEBUG调试窗口,从代码段的机器机码指令中可看出这里 DS中的段地址 DATA为 1126H,数据段缓冲区 SUMS的偏移量首地址为 0000H。
1127:0000 1E PUSH DS
1127:0001 2BC0 SUB AX,AX
1127:0003 50 PUSH AX
1127:0004 B82611 MOV AX,DATA
1127:0007 8ED8 MOV DS,AX
1127:0009 BA0000 MOV DX,SUMS
1127:000C B409 MOV AH,9
1127:000E CD21 INT 21H
2.使用简化段定义结构的程序 (不用,STARTUP伪指令 )
.MODEL SMALL ;小型方式
.586
.STACK 100H ;定义堆栈段
.DATA ;定义数据段
sums db ’good’,’$’
.CODE ;定义代码段
BEGIN,mov ax,@data ;给用户数据段赋值
mov ds,ax
MOV DX,OFFSET SUMS
MOV AH,9
INT 21H
.EXIT ; 返回 DOS
END BEGIN ; 源程序结束进入 DEBUG调试窗口,从代码段的机器机码指令中可看出地址信息不同于传统结构程序,这里 DS中的段地址 DATA为 1123H,数据段缓冲区 SUMS的偏移量首地址为 0010H。
1127:0000 B82311 MOV AX,DATA
1127:0003 8ED8 MOV DS,AX
1127:0005 BA1000 MOV DX,SUMS
1127:0008 B409 MOV AH,9H
1127:000A CD21 INT 21H
3.使用简化段定义结构的程序 (使用,STARTUP伪指令 )
.MODEL SMALL
.586
.STACK 100H
.DATA
SUMS DB 'GOOD','$'
.CODE
.STARTUP ;使用该伪指令主程序开始和结束都不使用 BGING,并省略了 对用户 DS赋值语句 。
MOV DX,OFFSET SUMS
MOV AH,9
INT 21H
.EXIT
END
进入 DEBUG调试窗口,从代码段的机器机码指令中可看出地址信息又发生了变化,这里 DS中的段地址 DATA为 1122H,数据段缓冲区 SUMS的偏移量首地址为 0020H。
1127:0010 BA2000 MOV DX,SUMS
1127:0012 B409 MOV AH,9H
1127:0014 CD21 INT 21H
从上述三种程序结构可以得出下列结论,
(1)在不同的 PC或者同一 PC的不同场合,对于同一程序,代码与数据等各段的段址可能不尽相同,
因此程序代码中 具地址属性 的代码就不可能完全一样。
(2)使用 ·STARTUP伪指令的程序中,代码段 的偏移量不是从 0000H开始,而是 从 0010H开始 。
( 3) 从这 3种结构的程序中都可以看出,伪指令不生成对应的机器代码。
( 4)程序的 不同结构不会影响程序执行的最终结果,
因此在以后的实验或应用设计中,用户可依据自己的爰好来选择其中某种结构。
回章首目录本章结束