合肥工业大学 计算机与信息学院
实验报告
课 程:汇编语言程序设计
专业班级:****************
学 号:**********
姓 名: *****
目录
实验一···········································3
实验二············································7
实验三···········································12
实验四···········································22
实验一 Debug程序的使用
一. 实验目的
1、熟悉DEBUG程序中的命令,学会在DEBUG下调试运行汇编语言源程序。 2、掌握8086/8088的寻址方式及多字节数据的处理方法。
二. 实验内容
1、利用DEBUG程序中的“E”命令,将两个多字节数“003F1AE7H”和“006BE5C4H”分别送入起始地址为DS:0200H和DS:0204H两个单元中。 2、分别用直接寻址方式和寄存器间接寻址方式编写程序段,实现将DS:0200H单元和DS:0204H单元中的数据相加,并将运算结果存放在DS:0208H单元中。 要求:
本次实验的内容均在DEBUG下完成,实现数据的装入、修改、显示;汇编语言程序段的编辑、汇编和反汇编;程序的运行和结果检查。
三. 实验过程和程序 实验内容一: e ds:0200 E7 1A 3F 00 e ds:0204 C4 E5 6B 00 实验内容二:
(1) 直接寻址方式 MOV AX,[0200] MOV BX,[0202] ADD AX,[0204] ADC BX,[0206] MOV [0208],AX MOV [020A],BX (2)寄存器间接寻址方式 MOV SI,0200H MOV DI,0204H MOV BX,0208H MOV AX,[SI] MOV DX,[SI+2] ADD AX,[DI] ADC DX,[DI+2]
MOV [BX],AX MOV [BX+2],DX 四. 实验结果(包括必要的截图)
实验内容一:
输入数据:
显示数据:
实验内容二: (1)直接寻址方式
程序段编辑:
反汇编:
运行:结果在DS:0208 单元中 为00AB00ABH
(2)寄存器间接寻址方式
程序段编辑:
反汇编:
运行:结果高字存放在dx中,低字存放在ax中(结果为00AB00ABh)
五. 实验体会
通过本实验,实践debug程序中的命令,并在debug下调试运行汇编语言源程序。在实践过程中,解决如何把数据录入存储单元、debug命令如何使用等问题后,知道存数据例如1234进存储单元时 要34 12存,还有掌握了寄存器的寻址方式。
实验二 汇编语言程序设计(顺序、循环)
一. 实验目的
1、掌握顺序和循环程序结构和设计方法;
2、熟悉在PC机上建立、汇编、连接、调试和运行8086/8088汇编语言程序的过程。
二. 实验内容
1、X、Y、Z、V均为字变量,在X、Y、Z、V字单元中存放是16位带符号数。试编写汇编语言程序完成以下功能: ①计算表达式值(V–(X*Y+Z-720))/X;
②将上述表达式运算结果整数放在SUM1单元,余数放在SUM2单元。 2、求一个班50名学生成绩的平均值(附加题:最大值和最小值,并将结果显示出来)
3、从键盘读入一个字符串,以Enter结束,字符串不超过50个字符,并打印该字符串(附加题:查找中间是否有‘asm’子串。如果有,输出‘Yes’;否则,输出‘No’)。 三. 实验过程和程序
(注:附加题没有做) 实验内容一:
X、Y、Z、V均为字变量,在X、Y、Z、V字单元中存放是16位带符号数。试编写汇编语言程序完成以下功能:①计算表达式值(V–(X*Y+Z-720))/X;②将上述表达式运算结果整数放在SUM1单元,余数放在SUM2单元。 Data segment x dw ? y dw ? z dw ? v dw ? sum1 dw ? sum2 dw ? Data ends Code segment assume cs:code,ds:data start:
mov ax,data mov ds,ax mov ax,x imul y
mov cx,ax
mov bx,dx mov ax,z cwd add cx,ax adc bx,dx sub cx,720 sbb bx,0 mov ax,v cwd sub ax,cx sbb dx,bx idiv x mov sum1,ax mov sum2,dx mov ah,4ch int 21h Code ends end start
实验内容二:求一个班50名学生成绩的平均值(为了方便,只设置了5个学生数据) data segment
grade dw 90,80,80,70,60;平均数76 data ends code segment
assume cs:code,ds:data start:
mov ax,data mov ds,ax xor ax,ax mov cx,5
mov bx,offset grade again: add ax,[bx] add bx,2 loop again mov cx,5
cwd idiv cx mov ah,4ch int 21h code ends end start
实验内容三:从键盘读入一个字符串,以Enter结束,字符串不超过50个字符,并打印该字符串 data segment buffer db 50 db ? db 50 dup('$') cr db 0ah,0dh,\data ends
codes segment
assume cs:codes,ds:data start:
mov ax,data mov ds,ax
input: mov ah,10 lea dx,buffer int 21h lea dx,cr mov ah,9 int 21h output:
lea dx,buffer+2 mov ah,9 int 21h mov ah,4ch int 21h codes ends
end start
四. 实验结果(包括必要的截图)
实验内容一:
设x=156,y=10,z=220,v=2000,则sum1=0006h,sum2=0004h 在ax中看sum1,在dx中看sum2
实验内容二:
预先设置的数据求得平均数为76,在ax中查看,即ax=004Ch
实验内容三:
五. 实验体会
通过本实验,将课本上学到的算术运算类指令、变量定义伪指令、存储单元、DOS 0AH号功能(字符串输入)和DOS 09H功能(字符串输出)等在实验中实现。在实现过程中,解决遇到的问题(符号扩展、定义的数组存储空间地址、字符串如何输入输出等)后,对上述知识有了更深的了解,并掌握实现它。
实验三 汇编语言子程序设计(分支、子程序)
一. 实验目的
1、掌握分支和子程序结构和设计方法;
2、熟悉在PC机上建立、汇编、连接、调试和运行8086/8088汇编语言程序的过程。 3、通过汇编语言了解高级语言的参数传递等知识。
二. 实验内容
1、BL中的只有一位为1。编写程序测试,并输出提示信息“The X Bit is 1”,要求:地址表和转移表。
2. 编写一个子程序计算z=f(x,y)=x*y+x-y(x,y,z有符号数内存数)。要求通过堆栈(寄存器、内存)传送所有参数。 3. 实践C?Asm的转换过程。 三. 实验过程和程序
实验内容一:BL中的只有一位为1。编写程序测试,并输出提示信息“The X Bit is 1” (1)转移表
;转移表,bl 左到右1-8位 DATAS SEGMENT
str1 db 'the 1 bit is 1',0dh,0ah,'$' str2 db 'the 2 bit is 1',0dh,0ah,'$' str3 db 'the 3 bit is 1',0dh,0ah,'$' str4 db 'the 4 bit is 1',0dh,0ah,'$' str5 db 'the 5 bit is 1',0dh,0ah,'$' str6 db 'the 6 bit is 1',0dh,0ah,'$' str7 db 'the 7 bit is 1',0dh,0ah,'$' str8 db 'the 8 bit is 1',0dh,0ah,'$' DATAS ENDS CODES SEGMENT
ASSUME CS:CODES,DS:DATAS START:
MOV AX,DATAS MOV DS,AX mov bl,00010000b mov cx,8 mov si,0
again: shl bl,1 jc next add si,3 loop again next:
add si,offset jmptable jmp si jmptable: jmp near ptr l1 jmp near ptr l2 jmp near ptr l3 jmp near ptr l4 jmp near ptr l5 jmp near ptr l6 jmp near ptr l7 jmp near ptr l8 l1:
lea dx,str1 jmp output l2:
lea dx,str2 jmp output l3:
lea dx,str3 jmp output l4:
lea dx,str4 jmp output l5:
lea dx,str5 jmp output l6:
lea dx,str6 jmp output l7:
lea dx,str7 jmp output l8:
lea dx,str8 output: mov ah,9 int 21h MOV AH,4CH INT 21H CODES ENDS
END START (2)地址表
;地址表,bl左到右依次是第1-8位 DATAS SEGMENT
str1 db 'the 1 bit is 1',0dh,0ah,'$' str2 db 'the 2 bit is 1',0dh,0ah,'$' str3 db 'the 3 bit is 1',0dh,0ah,'$' str4 db 'the 4 bit is 1',0dh,0ah,'$' str5 db 'the 5 bit is 1',0dh,0ah,'$' str6 db 'the 6 bit is 1',0dh,0ah,'$' str7 db 'the 7 bit is 1',0dh,0ah,'$' str8 db 'the 8 bit is 1',0dh,0ah,'$'
addrtable dw show1,show2,show3,show4,show5,show6,show7,show8 DATAS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS START:
MOV AX,DATAS MOV DS,AX mov bl,00001000b mov cx,8
mov si,0 again: shl bl,1 jc next add si,2 loop again next:
jmp addrtable[si] show1: lea dx,str1 jmp output show2: lea dx,str2 jmp output show3: lea dx,str3 jmp output show4: lea dx,str4 jmp output show5: lea dx,str5 jmp output show6: lea dx,str6 jmp output show7: lea dx,str7 jmp output show8: lea dx,str8 jmp output output: mov ah,9
int 21h MOV AH,4CH INT 21H CODES ENDS
END START
实验内容二:编写一个子程序计算z=f(x,y)=x*y+x-y(x,y,z有符号数内存数) (1)堆栈传递参数
;z=x*y+x-y,x、y、z为有符号数,堆栈传递 DATAS SEGMENT x dw 5 y dw 2 z dw ? DATAS ENDS CODES SEGMENT
ASSUME CS:CODES,DS:DATAS START:
MOV AX,DATAS MOV DS,AX sub sp,2 push y push x call cal pop z mov bx,z MOV AH,4CH INT 21H cal proc push bp mov bp,sp push ax push bx mov ax,[bp+4] mov bx,[bp+6] imul bx add ax,[bp+4] adc dx,0
sub ax,[bp+6] sbb dx,0 mov [bp+8],ax pop bx pop ax pop bp ret 4 cal endp CODES ENDS END START (2)寄存器传递参数
;z=x*y+x-y,x、y、z为有符号数,寄存器传递 DATAS SEGMENT x dw 5 y dw 2 z dw ? DATAS ENDS CODES SEGMENT
ASSUME CS:CODES,DS:DATAS START:
MOV AX,DATAS MOV DS,AX mov ax,x mov bx,y call cal mov z,ax MOV AH,4CH INT 21H cal proc mov cx,ax imul bx add ax,cx adc dx,0 sub ax,bx sbb dx,0 ret
cal endp CODES ENDS END START (3)内存传递参数
;z=x*y+x-y,x、y、z为有符号数,内存传递 DATAS SEGMENT x dw 5 y dw 2 z dw ? DATAS ENDS CODES SEGMENT
ASSUME CS:CODES,DS:DATAS START:
MOV AX,DATAS MOV DS,AX call cal MOV AH,4CH INT 21H cal proc mov ax,x imul y add ax,x adc dx,0 sub ax,y sbb dx,0 mov z,ax ret cal endp CODES ENDS END START
实验内容三:实践C—>ASM的转换过程 _TEXT SEGMENT _c$ = -32 _b$ = -20 _a$ = -8
; size = 2 ; size = 2
; COMDAT
; size = 2
_main PROC
; 4 : void main(){
push mov push push push mov mov
ebp ebp, esp
; 000000e4H
ebx esi edi ecx, 57
; 00000039H
; ccccccccH
sub esp, 228
lea edi, DWORD PTR [ebp-228]
eax, -858993460
rep stosd
short a,b,c; eax, 1
WORD PTR _a$[ebp], ax b=a+1;
; 5 : ; 6 :
mov mov
; 7 : a=1;
; 8 :
movsx eax, WORD PTR _a$[ebp] add eax, 1 mov
WORD PTR _b$[ebp], ax c=a+b;
; 9 :
movsx eax, WORD PTR _a$[ebp] movsx ecx, WORD PTR _b$[ebp] add eax, ecx mov
WORD PTR _c$[ebp], ax
; 10 : ; 11 : ; 12 : }
xor eax, eax pop edi pop esi pop ebx mov pop ebp ret 0
esp, ebp
_main ENDP
_TEXT ENDS
四. 实验结果(包括必要的截图)
实验内容一:
(1) 转移表:设bl=00010000b
(2)地址表:设bl=00001000b
实验内容二:设x=5,y=2,则z=13(000D),结果在ax (1) 堆栈传递参数(结果在bx中查看)
(2)寄存器传递参数(结果在ax中查看)
(3)内存传递参数(结果在ax中查看)
五、实验体会
通过本实验,让我更加深入了解地址表和转移表、子程序和从C输出汇编文件等知识,
通过实现地址表与转移表加深了对汇编寻址方式的了解;实现子程序,掌握主程序如何调用子程序,及子程序与主程序之间的参数传递方式;用VS实现C->ASM后,对C或C++有了新的认识。
实验四 汇编语言高级编程专题
一. 实验目的
1、汇编语言宏程序设计;
2、 掌握中断服务子程序的编写。 3、 汇编语言与高级语言的混编。
二. 实验内容
1、编写一个宏,求三个数的最小数,原型为:MIN3 x,y,z,min 2、挂接1CH中断,正计时60秒后退出。要求屏幕显示0-59的秒数。 3、VC++中编写内联汇编,将字节数组的每个元素高低四位互换。 char dbyte[] = {0x34,0x45,0x56,0x67,0xaf};
三. 实验过程和程序
1. 编写一个宏,求三个数的最小数,原型为:MIN3 x,y,z,min
min3 macro x,y,z,min mov ax,x cmp ax,y jbe next mov ax,y cmp ax,z jbe done next: cmp ax,z jbe done done: mov min,ax endm
DATAS SEGMENT x dw 2 y dw 4 z dw 3 min dw ? DATAS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS START:
MOV AX,DATAS MOV DS,AX min3 x,y,z,min MOV AH,4CH INT 21H CODES ENDS END START
2、挂接1CH中断,正计时60秒后退出。要求屏幕显示0-59的秒数。
INTNO EQU 1CH DATA SEGMENT OLDISR DW ?,? TIMER DB 100 COUNTER DW 0 ISDONE DB 0 DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA START:
MOV AX,DATA MOV DS,AX MOV AX,0 MOV ES,AX xor cx,cx
;PROTECT
MOV AX, ES:[INTNO*4] MOV OLDISR[0],AX MOV AX,ES:[INTNO*4+2] MOV OLDISR[2], AX ;SET NEW ISR
MOV WORD PTR ES:[INTNO*4], OFFSET ISR MOV WORD PTR ES:[INTNO*4+2],SEG ISR ;WAIT HERE WAITHERE: CMP ISDONE,1 JNZ WAITHERE EXIT: ;RESTORE
MOV AX,OLDISR[0] MOV ES:[INTNO*4],AX MOV AX,OLDISR[2]
MOV ES:[INTNO*4+2],AX MOV AX,4C00H INT 21H ISR PROC FAR PUSH DX PUSH AX MOV AX,DATA MOV DS,AX
STI ;便于中断嵌套 INC TIMER
;--------判断是否输入a----------- mov ah,0bh int 21h or al,al jz next
MOV AH,8;不显示输入的字符
INT 21H CMP AL,'a' JNE next
MOV AH,2;换行 MOV DL,10 INT 21H
;MOV COUNTER,0 ;从起一行计时时从0开始计时,注释掉则从起一行继续旧时间计时
next:
CMP TIMER, 1000/55 JB DONE MOV TIMER,0 MOV AH,2 MOV DL,13 INT 21H
;-------print time--------- MOV AX,COUNTER MOV DL,10 DIV DL MOV DH,AH MOV DL,AL MOV AH,2 ADD DL,30H INT 21H mov ah,2 mov dl,dh ADD DL,30H INT 21H inc COUNTER cmp COUNTER,60 JNE DONE
MOV ISDONE,1 DONE:
PUSHF
CALL DWORD PTR OLDISR
CLI POP AX POP DX
IRET ;中断返回
ISR ENDP
CODE ENDS END START
3、VC++中编写内联汇编,将字节数组的每个元素高低四位互换。 char dbyte[] = {0x34,0x45,0x56,0x67,0xaf};
#include
unsigned char change(unsigned char x) {
unsigned char a; _asm }
void main() {
unsigned char dbyte[]={0x34,0x45,0x56,0x67,0xaf}; for(int i=0;i<5;i++){
cout<<\ \ } cout< 四. 实验结果(包括必要的截图) { mov cl,4 } mov al,x shr al,cl shl bl,cl add al,bl mov a,al mov bl,x return a; 实验内容一:设x=2,y=4,z=3,结果在ax查看 实验内容二: 实验内容三: 五. 实验体会 通过本实验,课堂上学到的汇编宏、中断和内联汇编知道得以实践。在现这些知识的过程中,遇到宏调用时参数问题、如何设置新中断、如何16进制输出等问题,通过上网查阅资料及对比老师给的代码等方法解决后获益匪浅,最后将这些正确实现出来。