实验一 汇编程序
一、实验目的
1. 掌握DEBUG常用命令的使用方法
2. 熟悉汇编源程序编辑、汇编、连接和调试过程
3. 练习汇编源程序编写
二、实验内容及步骤
(一)学习DEBUG常用命令的使用方法
1. 进入DEBUG;
2. 用DEBUG的R命令查看、改变CPU寄存器的内容;
a)用R命令查看各寄存器的内容并纪录;
b)用R命令修改寄存器BX、SI、BP的值。
3. 用DEBUG的D命令查看内存中的内容(以下内容分别使用不同的D命令);
a)用D命令查看从1000:0开始的128个内存单元的内容并纪录;
b)用D命令查看从2000:8开始的128个内存单元的内容并纪录;
c)用D命令查看从3000:0开始的10个内存单元的内容并纪录;
4. 用DEBUG的E命令改写内存中的内容;
用E命令将内存1000:0—1000:9单元中的内容改写为0、1、2、3、4、5、6、7、8、9,并进行验证。
5. 用DEBUG的U命令将内存中的机器指令翻译成汇编指令;
用E命令从1000:0单元开始写入如下机器码,然后用U命令将内存中的机器指令翻译成汇编指令,并分析实验结果各部分的含义。
机器码 对应的汇编指令
b80100 mov ax,0001
b90200 mov cx,0002
01c8 add ax,cx
6. 用DEBUG的T命令执行机器指令;
用T命令单步执行上题程序段的每条指令并纪录结果。
7. 用DEBUG的A命令以汇编指令的格式在内存中写入机器指令
用A命令将下面的程序段写入内存,用U命令翻译成机器指令,逐条执行,观察每条指令执行后,CPU中相关寄存器中内容的变化。
MOV AX,4E20H
ADD AX,1416H
MOV BX,2000H
ADD AX,BX
MOV BX,AX
ADD AX,BX
MOV AX,001AH
MOV BX,0026H
ADD AL,BL
ADD AH,BL
ADD BH,AL
MOV AH,0
ADD AL,BL
ADD AL,9CH
(二)掌握汇编程序编辑、汇编、连接及调试的方法
设首地址为BUFFER的内存缓冲区中有20H个字节数据,试将数据区中的正数(包括0)存放至起始地址为PLUS的缓冲区,负数存入起始地址为MINUS的缓冲区。初始源程序如下,请用DEBUG软件调试该程序,找出其中的错误并加以修改。
;ex1.asm
Data segment
Buffer db f5h,46h,78h,4fh,0bch,0dah,0abh,02h //f5h应该改为0f5h
db 12h,56h,0d5h,0ach,34h,89h,45h,0c3h
db 00,14h,45h,58h,64h,0d4h,0c3h,0a5h
db 0b3h,0ffh,0d9h,64h,0d3h,90h,80h,7fh
count equ $-buffer
plus db count dup(?)
minus db count dup(?)
data ends
stack segment stack ‘stack’ //应该有stack 结束
db 100 dup(?)
code segment para ‘code’
assume cs:code,ss:stack,ds:data,es:data
start proc far //不能用start作为子程序名
push ds
xor ax,ax
push ax
mov ax,data //应该放在主程序开始start后边
mov ds,ax
mov es,ax
mov si,offset buffer
lea di,plus
lea bx,minus
mov cl,count
l1: losdb //拼写错误,应该是lodsb
test al,80
jnz l2
stosb
l2: xchg bx,di
stosb
xchg bx,di
again: loop l1
ret //在ret前应该有pop操作
start endp //应该把start改为另外定义的子程序名
code ends
end start
调试通过后的程序:
Data segment
Buffer db 0f5h,46h,78h,4fh,0bch,0dah,0abh,02h
db 12h,56h,0d5h,0ach,34h,89h,45h,0c3h
db 00,14h,45h,58h,64h,0d4h,0c3h,0a5h
db 0b3h,0ffh,0d9h,64h,0d3h,90h,80h,7fh
count equ $-buffer
plus db count dup(?)
minus db count dup(?)
data ends
stack segment stack 'stack'
db 100 dup(?)
stack ends
code segment para 'code'
assume cs:code,ss:stack,ds:data,es:data
start : mov ax,data
mov ds,ax
call done
mov ax,4c00h
int 21h
done proc far
push ds
xor ax,ax
push ax
mov es,ax
mov si,offset buffer
lea di,plus
lea bx,minus
mov cl,count
l1: lodsb
test al,80
jnz l2
stosb
l2: xchg bx,di
stosb
xchg bx,di
again: loop l1
pop ax
pop ds
ret
done endp
code ends
end start
(三)编写汇编源程序
将两个多位十进制数相加(39174+65082),并在屏幕上显示加数、被加数以及和。已知被加数和加数均以ASCII码形式存放在DATA1和DATA2为首的单元中(“低端方式存储”),结果送回DATA1中。
提示:被加数和加数以ASCII码形式存放在内存中,在相加前必须转换为BCD码,用未组合BCD码最适宜。未组合BCD码相加要用到AAA加法调整指令。
.model small
.stack
.data
data1 db '3','9','1','7','6'
data2 db '6','5','0','8','2'
.code
start: mov ax,@data
mov ds,ax
mov di,offset data1
mov si,offset data2
mov cx,5
again : ;显示第一个加数
mov dl,[di]
mov ah,2h
int 21h
inc di
loop again
mov cx,5
call decrf ;调用回车换行子函数
again1: ;显示第二个加数
mov dl,[si]
mov ah,2h
int 21h
inc si
loop again1
call decrf
mov cx,5
xor ax,ax
mov di,offset data1+4 ;从低位开始
mov si,offset data2+4
again2: sub [di],30h ;转换为由十六进制表示的数字串形式
sub [si],30h
mov al,[di]
add al,[si]
add al,ah
mov ah,0
aaa ;aaa调整指令
add al,30h
mov [di],al
dec di
dec si
loop again2
cmp ah,1
jnz done ;若有进位则在前面显示1
mov dl,'1'
mov ah,02h
int 21h
done: mov di,offset data1
mov cx,5
again3: mov dl,[di]
mov ah,02h
int 21h
inc di
loop again3
mov ax,4c00h
int 21h
decrf proc ;回车换行子函数
push ax
push dx
mov ah,2
mov dl,0dh
int 21h
mov ah,2
mov dl,0ah
int 21h
pop dx
pop ax
ret
decrf endp
end start
三、思考题
1. 汇编程序经汇编和链接后产生的是哪一种可执行程序?这种文件中IP的一般初始值是多少?
答:用masm汇编程序对源程序进行汇编,形成目标文件,再用link链接程序对目标程序进行链接形成可执行文件。IP的一般初始值为0000
1.调试过程中遇到什么问题?如何解决?
答:①对基本汇编指令不是很熟悉,通过查找资料解决;
②感觉算法不是很好,但是没有想出来更好的算法;
③在调试过程中有很多错误,通过debug调试出结果;
第二篇:汇编实验报告3
一、 实验目的
1.熟悉串操作指令的功能。
2.了解串操作指令的使用方法。
二.实验环境
1微型计算机(Intel x86系列CPU)一台
2.windows98/2000/XP操作系统
三、 实验任务
1. 输入以下程序段并运行之,回答后面的问题。
CLD
MOV DI,1000H
MOV AX,55AAH
MOV CX,10H
REP STOSW
上述程序段执行后:
(1) 从DS:1000H开始的16个字单元的内容是什么?
(2) (DI)= ?(CX)= ?,并解释其原因。
2. 在上题的基础上,再输入以下程序段并运行之,回答后面的问题。
MOV SI,1000H
MOV DI,2000H
MOV CX,20H
REP MOVSB
程序段执行后:
(1) 从DS:2000H开始的16个字单元的内容是什么?
(2) (SI)= ?(DI)= ?(CX)= ?,并分析之。
3. 在以上两题的基础上,再输入以下三个程序段并依次运行之。
程序段1:
MOV SI,1000H
MOV DI,2000H
MOV CX,10H
REPZ CMPSW
程序段1执行后:
(1) ZF=? 根据ZF的状态,你认为两个串是否比较完了?
(2)(SI)= ?(DI)= ?(CX)= ?,并分析之。
程序段2:
MOV [2008H],4455H
MOV SI,1000H
MOV DI,2000H
MOV CX,10H
REPZ CMPSW
程序段2执行后:
(1) ZF=? 根据ZF的状态,你认为两个串是否比较完了?
(2)(SI)= ?(DI)= ?(CX)= ?,并分析之。
程序段3:
MOV AX,4455H
MOV DI,2000H
MOV CX,10H
REPNZ SCASW
程序段3执行后:
(1) ZF=? 根据ZF的状态,你认为在串中是否找到了数据4455H?
(2)(SI)= ?(DI)= ?(CX)= ?,并分析之。
4. 从DS:1000H开始存放有一个字符串”This is a string”,要求把这个字符串从后往前传送到DS:2000H开始的内存区域中(即传送结束后,从DS:2000H开始的内存单元的内容为”gnirts a si sihT”),试编写程序段并上机验证之。