微原软件实验报告
- 格式:docx
- 大小:1.24 MB
- 文档页数:29
微机原理与接口技术软件实验
实验报告一
姓名:王绪东
学院:信息与通信工程
学号:08210234
班级:08211108
实验一
一 实验目的
1.掌握汇编程序的编辑,编译,连接和执行的全过程;
2.学习和掌握用DEBUG调试程序的方法.
二 实验任务及内容
DAT SEGMENT
A DB 4 ;(自定)
B DB 5 ;(自定)
Y DB 3 DUP(0)
Z DB 0,0
DAT ENDS
STA SEGMENT STACK
DW 50 DUP(?)
STA ENDS
COD SEGMENT
ASSUME CS:COD,DS:DAT
STAR PROC FAR
PUSH DS
XOR AX,AX
PUSH AX
MOV AX,DAT
MOV DS,AX
MOV AX,STA
MOV SS,AX
MOV AL,A
MOV Z,AL
MOV Z+1,AL
CALL SUB1 ;A*A
MOV AL,B
MOV Z,AL
MOV Z+1,AL
CALL SUB1 ;B*B
MOV AL,A
MOV Z,AL
MOV AL,B
MOV Z+1,AL ;Z stores the two OPRD temporally
CALL SUB1 ;A*B
ADD WORD PTR Y,AX ADC BYTE PTR[Y+2],0 ;A*B*2
RET
STAR ENDP
SUB1 PROC
MOV AL,Z
MOV AH,Z+1
MUL AH
ADD WORD PTR Y,AX ;Y stores the result
ADC BYTE PTR[Y+2],0 ;Y+2 stores the signal flag
RET
SUB1 ENDP
COD ENDS
END STAR
三、实验文档中的要求
(1)用 D 命令观察数据区在内存中的具体内容,记录单元 A 和 B 的具体地址.
(图一 )
由于ds:0指向PSP的起始位置,PSP占用256个字节,故数据区放在ds+0010h:0处,再由d命令验证,知道A的具体地址为0BA2:0000,B的具体地址为0BA2:0001
(2)用 U 命令对目标代码反汇编,观察反汇编后的结果.注意发现源程序的起始位置, 并记录这个起始地址.
由图知,起始地址为0BAA:0000
(3)用 T 命令作单步跟踪调试.比较每条指令执行后的结果和原来的理解是否
一致.得出程序运行的结果:它们是写在什么单元,具体内容是什么; 并判断结果是
否正确.
现仅将关键步骤的单步调试结果列出,配合r命令查看结果。
(图二:单步调试结果一)
这是第一次调用SUB1子程序退出后的结果,从图中可以看出Y存储的数据是01,,09,00,0109h=400=20*20,z存储的数据为14h,14h.
(图三:单步调试结果二)
这是第二次调用SUB1子程序退出后的结果,从图中可以看出执行完“MUL AH”指令后,AX存储的数据是00E1,即是15*15的结果,子程序退出后Y存储的数据是0271H,即625,是20*20+15*15的结果。
(图四:单步调试结果三)
这是第三次调用SUB1子程序的结果,从图中可以看出执行完“MUL AH”指令后,AX存储的数据是012C,即是A*B=20*15=300的结果,子程序退出后Y存储的数据是039DH,即是625+300的结果。
(图五:单步调试结果四)
这是程序退出时的最终结果,从图中可以看出,Y存储的数据最终为 +1225 ,即为A*A+B*B+A*B+A*B的结果。结果正确。
(4)在子程序 SUB1 的入口处设一断点,用 G 命令执行程序. 在断点处观察堆栈的内容,比较堆栈的内容和程序返回地址是否一致.
(图六:调用子程序的堆栈内容改变结果)
从图中可以看出, IP指针的变化说明调用了子程序SUB1,而堆栈段段基址SS和栈顶指针SP的值都没有改变。程序返回地址一致。
(5)用 E 命令修改单元 A,B 的内容,重新执行程序,并记录结果.
(图七:修改A,B数值后的结果)
从图中可见,分别将A,B的值改为1,2后,程序执行完毕,Y存储的内容是9,结果正确。
(6)用 M 命令和 A 命令对程序进行修改: 将主程序中最后两条指令 (ADD 和ADC) 修改为一条 CALL SUB1 指令,重新执行程序.
(图八:a命令练习使用的结果)
反汇编发现程序最后的ADD指令在CODE段的偏移地址为0035,将此处改为调用SUB1子程序的指令,然后将0038处改为RETF。重新执行后,查看Y的内容,结果正确。使用M命令时,由于差retf命令,故程序会出错,可以另开辟一段内存存入上述命令,再将其复制到0BAA:0048处。
(7) 重新使用编辑软件,把源程序最后一句中的 STAR 去掉.再次生成可执行文件,并用
DEBUG 调入内存.当使用 U 命令时,显示的结果与前一次(未加 STAR) 的结果有何不同?
(图九:修改源程序后执行的结果)
由于省去了start,程序不再从标号start处开始执行,而从数据段开始,并将其翻译为对应的指令add [bx+si],al.
四 回答预习题
1. 阅读并分析程序的功能
答:最终实现了A*A+B*B+A*B+A*B=(A+B)*(A+B)的运算。
2. 若 SS=2000H,SP=FFFFH, 向堆栈中压入 4 字节数据后,如何用 D 命令显示压入堆栈的内容?
使用debug指令“d 2000:FFFB”即可显示压入堆栈的内容,SP=SP-4=FFFB,则前面4个字节的内容即为压入的内容。
五 实验总结
汇编语言编程时要求程序员有严谨、缜密的思维,在某些程度上,我感觉使用汇编语言的编程过程就是把高级语言的结构过程拉平成线性过程来考虑问题。
经过此次试验,我基本掌握了汇编程序的编辑、编译、连接、执行以及调试的主要步骤。应注意以下几点:
在debug过程中,任何存储器单元都无法用标号来识别,要使用它们,只能使用物理地址调用。
使用u指令修改asm代码时要对照反汇编的结果,若要删去某条指令,可以找到那条指令在代码段的偏移地址,再用u指令将其修改为NOP(从该指令开始到下一条指令开始的地址-1处)。
可以结合r指令、t指令、已经用g指令设置断点来诊断问题。
建议:个人觉得清华大学王爽的<>写得不错,将其作为入门教程很不错,可以考虑将其中的部分章节写入我们的实验教程中。
实验二 分支,循环程序设计
一 实验目的:
1.开始独立进行汇编语言程序设计;
2.掌握基本分支,循环程序设计;
3.掌握最简单的 DOS 功能调用。
二 实验任务及内容:
1.安排一个数据区,内存有若干个正数,负数和零。每类数的个数都不超过 9。
2.编写一个程序统计数据区中正数,负数和零的个数。
3.将统计结果在屏幕上显示。
三 源程序
assume cs:code,ds:data
data segment
buff db 1,2,3,4,5,-1,-2,-3,0,0 ;安排的数据区
string db 'positive numbers:'
plus db 0 ;用变量plus来存储正数的个数
db 0ah,0dh
string1 db 'zero numbers:'
zero db 0 ;用变量zero来存储零的个数
db 0ah,0dh
string2 db 'negative numbers:'
minus db 0 ;用变量minus来存储负数的个数
db '$'
data ends
code segment
start:mov ax,data
mov ds,ax
mov cx,10 ;初始化,并将CX赋为10,因为共有10个数
mov dx,0 ;将计数器dx,ah初始化为0
mov ah,0
lea bx,buff
cmping:cmp byte ptr [bx],0 ;取出一个数与0进行比较
jge plu ;大于0,跳至plu执行
inc ah ;小于0,用ah暂存小于0的个数,ah+1
jmp next ;比完后进行下一个数的比较
plu: je zer ;等于0,跳至zer执行
inc dl ;大于0,用dl暂存大于0的个数,dl+1
jmp next ;比完后进行下一个数的比较
zer: inc dh ;等于0,用dh暂存等于0的个数,dh+1
next: inc bx
loop cmping ;将dl,dh,ah分别赋值给变量plus,zero,minus,其ASCII分别加48
add dl,48
mov plus,dl
add dh,48
mov zero,dh add ah,48