汇编语言实验报告
实验一 DOS环境下的汇编语言编程环境使用
(基础与验证型)
班级:05211002
姓名:张宁
学号:1120102310
实验日期:2012.9.7晚6:00~9:00
汇编语言实验报告
实验一 DOS 环境下的汇编语言编程环境使用(基础与验证型)
一、实验要求和目的
1、掌握汇编语言程序设计的基本流程和学会上机开发简单程序;
2、熟练掌握宏汇编程序MASM 的使用;
3、熟练掌握连接程序LINK 的使用;
4、熟练掌握DEBUG 的使用;
二、软硬件环境
1、硬件环境:计算机系统 windows;
2、软件环境:装有MASM、DEBUG、LINK、等应用程序。
三、实验涉及的主要知识
汇编语言程序设计上机开发过程如图1.1 所示。
四、实验内容与步骤
1、汇编、链接并调试给出的简单程序,找出程序中的错误。
(一)录入并建立汇编语言源程序文件(ASM 文件)
(二)用汇编程序MASM 将ASM 文件汇编成目标程序文件(OBJ 文件)
(三)用连接程序LINK 生成可执行程序文件(EXE 文件)
(四)程序的调试
2、完成程序设计:
分类统计字数组data 中正数、负数和零的个数,并分别存入内存字变量Positive、Negative
和Zero 中,数组元素个数保存在其第一个字中。使用Debug 查看Positive、Negative 和
Zero 三个变量的数据。
五、实验过程及结果:
实验一:
1. 输入给出的程序
2. 运行输入的程序,发现了三处错误:
根据错误提示,发现错误为ADDITION后未打冒号,CMP错打为COM。修改原代码:
改为:
3. 代码编译成功,生成OBJ文件,再生成EXE文件,可成功运行。
4. 在原程序代码后添加两行代码,以验证ADDITION的逻辑正确性,改动如下:
现实在DATA1中添加字节型sum ,再将ADDITION的运行结果,从AX送到sum中去。
5. 调试发现 ADDITION并没用正确运行。检查语句逻辑性发现,应将JAE改成JB,才能实现累加并终结。
改为:
6. 重新进行DEBUG调试:
实验二:
分类统计字数组data 中正数、负数和零的个数,并分别存入内存字变量Positive、Negative
和Zero 中,数组元素个数保存在其第一个字中。使用Debug 查看Positive、Negative 和
Zero 三个变量的数据。
1. 根据题目要求,编译如下程序:
测试数据为 1,1,0,0,0,-1,则应1有2个正数,3个零,1个负数。
2. 在DEBUG中调试:
直接用-g36将程序运行到操作归还给DOS系统之前。用-dds:0查看内存状态:
实验感想:
1. 由于第一次进行实验,原理和操作上都不熟悉,一开始一头雾水……后来听老师讲 和同学无限讨论,终于搞明白一点。实验回来之后自己又尝试了几次。感觉这门实验需要多做多练多思考,熟能生巧。
2. C语言结课之后再一次产生被电脑耍的感觉。因为电脑不会告诉我们逻辑上的错误 它只能机械地判断语法错误。于是我们不得不面对的纠结问题就是:即使电脑告诉你没错 你还是要努力查错!
第二篇:北京理工大学汇编语言实验报告4分支和循环程序设计实验(设计性实验)
实验四 分支和循环程序设计实验(设计性实验)
一、实验要求和目的
1.熟悉汇编语言程序设计结构;
2.熟悉汇编语言分支程序基本指令的使用方法;
3.掌握利用汇编语言实现单分支、双分支、多分支的程序设计方法;
4.了解汇编语言循环程序设计的基本流程;
5.熟悉汇编语言循环基本指令的使用方法;
6.掌握利用汇编语言的循环指令完成循环程序设计方法。。
二、软硬件环境
1、硬件环境:计算机系统 windows;
2、软件环境:装有MASM、DEBUG、LINK、等应用程序。
三、实验涉及的主要知识
在实际应用中,经常根据一些条件来选择一条分支执行。汇编语言的条件判断主要是通
过状态寄存器中的状态位、无符号数相减或有符号相减而导致的结果来进行。
1.无条件转移指令JMP
无条件转移指令JMP 是使程序无条件转移至目标处,又分为段内转移、段间转移。
2.条件转移指令JXX
条件转移指令可分为三大类:
1).简单条件转移指令指令。根据单个标志位的状态判断转移条件。
标志位 指令 转移条件 意义
JC CF=1 有进位/借位
CF
JNC CF=0 无进位/借位
JE/JZ ZF=1 相等/等于0
ZF
JNE/JNZ ZF=0 不相等/不等于0
JS SF=1 是负数
SF
JNS SF=0 是正数
JO OF=1 有溢出
OF
JNO OF=0 无溢出
JP/JPE PF=1 有偶数个1
PF
JNP/JPO PF=0 有奇数个1
2).无符号数条件转移指令。
假设在条件转移指令前使用比较指令,比较两个无符号数A,B,指令进行的的操作是
A-B,其转移指令如下:
指令 转移条件 意义
JA/JNBE CF=0 AND ZF=0 A>B
JAE/JNB CF=0 OR ZF=1 A>=B
JB/JNAE CF=1 AND ZF=0 A<B
JBE/JNA CF=1 OR ZF=1 A<=B
3).带符号数条件转移指令。
指令 转移条件 意义
JG/JNLE SF=OF AND ZF=0 A>B
JGE/JNL SF=OF OR ZF=1 A>=B
JL/JNGE SF OF AND ZF=0 A<B
JLE/JNG SF OF OR ZF=1 A<=B
在汇编程序设计中,要熟练使用循环指令和跳转等指令来实现循环,理解循环体结构中
的初始化部分、循环体、结束部分,并且要结合前面分支结构相关的知识点,加深对循环结
构的理解和掌握。循环结构的组成及其设计方法的知识要点有:
1、循环程序的基本结构通常由3 部分组成
1) 初始化部分
建立循环初始值,为循环做准备,如设置地址指针,(BX/SI/DI/BP),初始化循环控制变量
或计数器(CX),数据寄存器(AX/DX)初值等.
2) 循环体
循环体是循环程序的主体,是程序中重复执行的程序段.它是由循环工作部分、修改部
分、和循环控制部分。
①循环工作部分:完成程序功能的主要程序段,用于解决程序的实际任务;
②修改部分:对循环参数进行修改,并为下一次循环做准备;
③循环控制部分:判断循环结束条件是否满足。通常判断循环结束方法:
用计数控制循环;循环是否进行了预定的次数。
用条件控制循环。循环终止条件是否满足。
3)结束处理处理部分
主要是对循环的结果进行处理,比如现实提示信息等,很多时候没有此部分程序。
2、循环控制指令:
指令格式 执行操作 循环结束条件
LOOP 标号 CX=CX-1; 若CX=0,则循环 CX=0
LOOPNZ/LOOPNE 标号 CX=CX-1; 若CX=0 且ZF=0,则循环 CX=0 或ZF=0
LOOPZ/LOOPE 标号 CX=CX-1; 若CX=0 且ZF=1,则循环 CX=0 或ZF=1
JCXZ 标号 仅测试(CX)=0? 若等于0,则转移到目标地址,否则就顺序执行
3、循环控制可以分为:计数循环和条件循环。作为计数循环,一般是指循环次数是已
知的情况,在程序设计的的循环时,先应将循环次数送入计数器CX 中进行计数,在循环体
中使用LOOP 等循环指令。当然,也可以通过其他方式来进行,如cx←cx-1,jnz 等结合实
现。
四、实验内容与步骤
1、判断方程AX2+BX+C=0 是否有实根。若有实根,则将字节变量tag 置1,否则置0。假
设A、B、C 均为字节变量,数据范围为-128~127。
·源代码如下:
DATAS SEGMENT
a dw 2
b dw 8
d dw 5
tag db ?;此处输入数据段代码
DATAS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
mov cx,b
mov ax,0
l1: add ax,b
loop l1
mov cx,d
mov dx,0
l2:add dx,a
loop l2
mov cx,4
add bx,dx
cmp ax,bx
jge exist
mov tag,0
jmp done
exist: mov tag,1 ;此处输入代码段代码
done:
MOV AH,4CH
INT 21H
CODES ENDS
END START
·结果如下:b=8,a=2,c=5,因为8*8-4*2*5=24>0所以应该有解,tag为1
运行后,
Dds:0显示的数据第一排一次为2、8、5、1,前面三个是a、b、c的值,第四个是tag的值,值为1,符合题目要求
若改一改数据,将b改成2,结果应该为0
这里的tag果然为0,也符合题目要求。
2、编写一个程序,判别键盘上输入的字符;若是1-9 字符,则显示之;若为A-Z 字符,显
示“C”;若为a-z 字符,显示“c”;若是回车字符<CR>(其ASCII 码为0DH),则结束程序,
若为其它字符则显示显示“R”。
·源代码如下:
DATAS SEGMENT
char db ? ;此处输入数据段代码
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
l: mov ah,1
int 21h
mov char,al
cmp char,0dh
je end1
cmp char,'1';判断输入数是否比0大
jge next1
jmp others
next1:cmp char,'9';判断是否比9大
jle show1;不是的话,即在0~9之间,跳至show1
cmp char,'A';比9大后判断是否比41(‘A’)大
jge next2
jmp test1;不比40大,去检测是否是回车
next2: cmp char,'Z';比40大后,判断是否比5a(‘Z’)大
jle show2;不比5a(‘Z’)大,即在‘A’~‘Z’之间,跳至show2
cmp char,'a';判断是否比61(‘a’)大
jge next3;若大,跳至next3
jmp others
next3:cmp char,'z';检测是否比7a('z')大
jle show3;不比7a(‘z’)大,即在‘a’~‘z’之间跳至show3
jmp others
test1: cmp char,0dh
je end1
jmp others
show1: mov dl,char
mov ah,02h
int 21h
jmp done
show2: mov dl,'C'
mov ah,02h
int 21h
jmp done
show3: mov dl,'c'
mov ah,02h
int 21h
jmp done
others:mov dl,'R'
mov ah,02h
int 21h
jmp done
done:
loop l;输完一个字符之后,会立刻显示对应字符,此后可以继续输入字符。
end1:
;此处输入代码段代码
MOV AH,4CH
INT 21H
CODES ENDS
END START
运行结果如下:
例如输入3,则立刻显示3(0~9显示原字符,输入),输入e之后显示‘c’(小写字母都显示c),输入S之后显示‘C’(大写字母显示C),输入@之后显示‘R’(其他字符统一显示R),如果按回车,则退出循环,如下
3、(大家再次编成实现实验一的题目,看是否可以优化程序?)分类统计字数组data 中正
数、负数和零的个数,并分别存入内存字变量Positive、Negative 和Zero 中,数组元素个
数保存在其第一个字中。使用Debug 查看Positive、Negative 和Zero 三个变量的数据。
·源代码如下:
DATAS SEGMENT
data1 dw 1,-2,-3,7,4,0,5
count equ ( $-data1)/2
positive dw count+1 dup(?)
negetive dw count+1 dup(?)
zero dw count+1 dup(?)
;此处输入数据段代码
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
mov dx,0
mov bx,0
mov di,0
mov si,0
mov cx,count
ll: mov ax,data1[si]
cmp ax,0
jg p
je z
jl n
p:mov ax,data1[si]
mov positive[si+2],ax
inc dx
add si,2
jmp l
z: mov ax,data1[si]
mov zero[si+2],ax
inc bx
add si,2
jmp l
n: mov ax,data1[si]
mov negetive[si+2],ax
inc di
add si,2
jmp l
l: loop ll
mov positive[0],dx
mov zero[0],bx
mov negetive[0],di;此处输入代码段代码
MOV AH,4CH
INT 21H
CODES ENDS
END START
运行结果如下:
-dds:0里面显示的前面7个数为data1里面的,紧接着7个数是positive
4、编写程序,在字符串变量STRING 中存有一个以$为结尾的ASCII 码字符串,要求计算
字符串的长度,并把它存入LENGTH 单元中。(要求用条件控制循环方法,并且字符串分数
据类型是字节和字两种情况)
流程图:
情况1(字节)
·源代码:
DATAS SEGMENT
string db '13211$'
length1 db ?;此处输入数据段代码
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
mov al,0
mov si,0
count: cmp string[si],'$'
je done
inc si
inc al
jmp count
done:
mov length1,al
mov dl,al
mov ah,02h
int 21h;此处输入代码段代码
MOV AH,4CH
INT 21H
CODES ENDS
END START
·运行结果为:
-dds:0中数据的第一行前面几个数是string,‘$’的ASCII码是24,之后的一个数据就是string中字节的个数,这里显示为5个(不含‘$’本身)
情况2(字)
·源代码:
DATAS SEGMENT
string dw '1','3','2','1','1','$'
length1 db ?;此处输入数据段代码
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
mov al,0
mov si,0
count: cmp string[si],'$'
je done
inc si
inc si
inc al
jmp count
done:
mov length1,al
mov dl,al
mov ah,02h
int 21h;此处输入代码段代码
MOV AH,4CH
INT 21H
CODES ENDS
END START
·运行结果如下:
前面的几个数据是string的数据,最后一个数0005是string中元素的个数,5个(这里依旧把‘$’算作其内)。
注意:涉及到初始数据的,同学们自行给出多组数据,反复加以验证各题程序。
五、实验要求与提示
1、实验要求
(1)画出各程序流程图;
(2)列出程序清单,加上适量注释;
(3)回答思考问题;
(4)记录实验结果;
(5) 完成实验报告(实验材料上的内容简写,自己的工作要详尽)。
2、实验提示:
A)二元一次方程有根的条件是B2-4*A*C>=0。依据题意,先计算出B2 和4*A*C,然
后比较两者大小,
B)字符输入输出
利用 DOS 的INT 21H 系统功能调用来实现字符的输入/输出操作,其中1 号功能表示
输入字符;2 号功能表示输出字符;详细查阅相关资料,简单示例:
(1)显示单个字符可以用DOS 的INT 21H 的2 号功能,将字符放在DL 寄存器中,2
号放在AH 寄存器中。
MOV DL,’*’
MOV AH,2
INT 21H__