博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
汇编语言实验+题目
阅读量:3904 次
发布时间:2019-05-23

本文共 7586 字,大约阅读时间需要 25 分钟。

汇编语言实验

本学期汇编课程已经结束,整理一下曾经做过的题目和写过的汇编代码。

使用dosbox环境masm5.0编译器,debug方式可以看我这篇文章

 

  • 实验题

循环程序设计

1. 有一个首地址为Arr的N字数组,编程求数组中的最大值和最小值,并存入MAX和MIN地址单元中。

Data segment	Arr dw 1H,3H,2H	N EQU 3 ; 这里可以 $-Arr / 2 因为dw 是双字节	Max dw ?	Min dw ?Data endsCode segment	Assume cs:Code, ds:DataStart:	mov ax,Data	mov ds,ax		mov dx,Arr	mov ax,Arr	mov si,00H	mov cx,N-1NEXT:	add si,2		cmp dx,Arr[si]	jle jmp1	mov dx,Arr[si]jmp1:	; do nothing 		cmp ax,Arr[si]	jge jmp2	mov ax,Arr[si]jmp2:	; do nothing LOOP NEXT	mov Max,dx	mov Min,ax		MOV	AH,4CH    ;返回dos    INT	21HCode ends	end Start

调试结果:

2. 显示一个十六进制数(XXXXH)

思路:循环位移4位后,每次取出bx(存放16进制数)的低第四位,加上‘0’判断是否在0-9ascii码范围内在则直接打印不在则加7再打印,重复4次。最后打印一个’H’。测试数:1E2AH存入BX

Code segment	assume cs:Codestart:	mov ax,Code	mov ds,ax		xor ax,ax; to 0	xor cx,cx; to 0	xor bx,bx; to 0		mov bx,1E2AH	mov ch,4rotate:		mov cl,4	rol bx,cl	mov al,bl	and al,0FH	add al,30H	cmp al,3aH	jl print	add al,7H	print:	mov dl,al	mov ah,2	int 21H	dec ch	jnz rotate	mov dl,'H'	mov ah,2	int 21H		mov ah,4cH	int 21HCode ends	end start

运行结果:

3. 编制一个程序把BX寄存器内的二进制数用十进制的形式在屏幕上显示出来。

思路: 将bx中的内容mov到ax,分别除10000,1000,100,10,将商放到data segment存起来,将余数放回ax继续除,直到余数为一位数,再将data segment的数顺序打印出来。

Datas segment	decnum db 5 dup(?)Datas endsCode segment	assume cs:Code,ds:Datasstart:	mov ax,Datas	mov ds,ax		mov bx,0FFFFH ; 要转换的数	lea si,decnum	mov dx,0    ;dx一定要置零	mov ax,bx		mov cx,10000	div cx	mov [si],al	inc si	mov ax,dx;把上一次运算的余数放入ax		mov dx,0	mov cx,1000	div cx	mov [si],al	inc si	mov ax,dx		mov dx,0	mov cx,100	div cx	mov [si],al	inc si	mov ax,dx		mov dx,0	mov cx,10	div cx	mov [si],al	inc si	mov [si],dl	;****循环打印data段数据 decnum****	lea si,decnum	mov cx,5next:	mov dx,[si]	add dx,'0'	mov ah,2	int 21H	inc si	loop next		mov ah,4cH	int 21HCode ends	end start

运行结果:

 

调试

 

分支程序设计

1. 设有10个学生的成绩分别是76,69,84,90,73,88,99,63,100和80分。试编制一个程序统计60~69分,70~79分,80~89分,90~99分和100分的人数,分别存放到S6,S7,S8,S9和S10单元中。

Datas segment	STU db 76,69,84,90,73,88,99,63,100,80	S6 db 0	S7 db 0	S8 db 0	S9 db 0	S10 db 0Datas ends  Code segment	assume ds:Datas,cs:Codestart:	mov ax,Datas	mov ds,ax		xor ax,ax	mov si,0	mov cx,10	next:	mov al,byte ptr [si]		cmp ax,69	jg jmp1	add S6,1	jmp finaljmp1:	cmp ax,79	jg jmp2	add S7,1	jmp finaljmp2:	cmp ax,89	jg jmp3	add S8,1	jmp finaljmp3:	cmp ax,99	jg jmp4	add S9,1	jmp finaljmp4:	add S10,1	final:	inc si	loop next		mov dl,S6	mov ah,2H	int 21H	mov dl,S7	mov ah,2H	int 21H	mov dl,S8	mov ah,2H	int 21H	mov dl,S9	mov ah,2H	int 21H	mov dl,S10	mov ah,2H	int 21H		mov ah,4cH	int 21H	Code ends	end start

运行结果:

 

2. 试编写一个汇编语言程序,要求对键盘输入的小写字母用大写字母显示出来。

Data segment	max_len db 100	real_len db ?	str1 db 100 dup('$')Data endsCode segment	assume cs:code,ds:datastart:	mov ax,data	mov ds,ax	lea dx,max_len	mov ah,0AH	int 21H		mov dl,0DH	mov ah,02H	int 21H	mov dl,0AH	mov ah,02H	int 21H		; 字符大小写转换	xor cx,cx		mov cl,real_len	mov si,0	lop:	mov bl,str1[si]	cmp bl,61H	jb ok	cmp bl,7AH	ja ok	sub bl,20H	mov str1[si],blok:	inc si	loop lop		lea dx,str1	mov ah,09H	int 21H		mov ah,4cH	int 21HCode endsend start

 运行结果:

 

3. 以T为首地址定义10个带符号数(补码),将负数去掉,正数按原序排列,并显示正数。

思路:如果一个长度为一个字节的十六进制数高位为大于9的数,那这个数就是负数,所以遍历整个数组,判断每个十六进制数的高位大小,跳过负数,输出正数。

Data segment	num db 0AAH,01H,02H,0ABH,03H,04H,05H,06H,07H,0FFH	count db 10Data endsCode segment	assume cs:Code,ds:Datastart:	mov ax,Data	mov ds,ax		xor bl,bl	xor cx,cx	; to 0	mov cl,count	mov si,0	; 筛选正数并输出next:	mov bl,num[si]	rcl bl,1	jc lop	; output	; 十位	mov bl,num[si]	shr bl,1	shr bl,1	shr bl,1	shr bl,1	and bl,0FH	mov dl,bl	cmp dl,09H	ja big1	add dl,30H	jmp outt1big1:	add dl,36Houtt1:	mov ah,02H	int 21H	; 个位	mov bl,num[si]	and bl,0FH	mov dl,bl	cmp dl,09H	ja big2	add dl,30H	jmp outt2big2:	add dl,36Houtt2:	mov ah,02H	int 21H	; 输出H	mov dl,'H'	mov ah,02H	int 21H	lop:	inc si	loop next		mov ah,4cH	int 21HCode ends 	end start

运行结果:

 

4. 试编写一个汇编语言程序,要求从键盘接收一个四位的十六进制数,并在终端显示与它等值的二进制数。

code segment   assume cs:codestart:  mov bx,0mov ch,4mov cl,4s0:     mov ah,1          ;输入4个16进制数int 21hcmp al,39h        ;判断 0~9 or A~Hjbe nextsub al,07hnext:    sub al,30hshl bx,cladd bl,al        dec chjnz s0            mov cx,16	;显示mov dl,0AH	;换行mov ah,02Hint 21Hs1:mov dl,0rol bx,1          ;最高位入CFadc dl,30hmov ah,02hint 21hloop s1mov ax,4c00hint 21hcode ends	end start

运行结果:

 

5. 试编写一个程序,要求比较数组ARRAY中的三个16位补码数,并根据比较结果在终端上显示如下信息

(1)如果三个数都不相等则显示0;

(2)如果三个数有两个数相等则显示1;

(3)如果三个数都相等,则显示2.

Data segmentARRAY DW 1,2,3Data endsCode segment    assume cs:Code,ds:DataMain PROC FARstart:MOV AX,DATAMOV DS,AXMOV AX,word ptr ARRAYMOV BX,word ptr ARRAY[2]CMP AX,word ptr ARRAY[2]; AB比较je AB_ECMP AX,word ptr ARRAY[4]; AC比较je AC_ECMP BX,word ptr ARRAY[4]; BC比较je BC_EMOV dl,30HJMP EXITAB_E:CMP BX,word ptr ARRAY[4]; BC比较je BC_E2MOV dl,31HJMP EXITAC_E:MOV dl,31HJMP EXITBC_E:MOV dl,31HJMP EXITBC_E2:MOV dl,32HJMP EXITEXIT:MOV AH,2INT 21HMOV AH,4CH    INT 21HCode ends Main endp    end start

 运行结果:

 

 

 

子程序设计

1. 求1+2+3+……n的和,并以十进制数形式显示此数。

data segment	decnum db 5 dup(?)data endscode segment	assume cs:code,ds:data	main proc farstart:	mov ax,data	mov ds,ax		mov cx,20	;从1加到xxx 		call sumfunc	;使用cx寄存器传参,bx存返回值		call printfunc		mov ah,4ch	int 21h	main endpsumfunc proc near	xor bx,bx	xor ax,axlop:	add ax,1	add bx,ax	loop lop	retsumfunc endpprintfunc proc near	LEA  SI,DECNUM	;偏移地址传送    MOV  DX,0      MOV  AX,BX	MOV  CX,10000	DIV  CX	MOV  [SI],AL	;求得万位的值,存入指定单元    INC  SI	MOV  AX,DX 	;上次计算的余数存在DX中	MOV  DX,0	MOV  CX,1000					DIV  CX	MOV  [SI],AL	;求得千位的值,存入指定单元    INC  SI	MOV  AX,DX	MOV  DX,0	MOV  CX,100	DIV  CX	MOV  [SI],AL	;求得百位的值,存入指定单元    INC  SI	MOV  AX,DX	MOV  CL,10	DIV  CL	MOV  [SI],AL	;求得十位的值,存入指定单元    INC  SI	MOV  [SI],AH	;存个位的值	LEA  SI,DECNUM   ;开始显示存储单元中的十进制数	MOV  CX,5DISP:		MOV	DL,[SI]	;依次取出十进制数各位的值	OR  DL,30H	;将取出的值转换为ASCII值	MOV  AH,2	INT  21H		;利用DOS功能调用,显示	INC  SI	LOOP  DISP    MOV  DL,'D'	MOV  AH,2	INT  21H	retprintfunc endpcode ends	end start

运行结果:

 

2. 从键盘输入一个十进制数然后以十六进制输出

DATA SEGMENT	NUM10 DB 5;定义缓冲区长度		  DB ?;实际输入字符个数的计数单元		  DB 5 DUP(0)		  	NUM16 DB 4 DUP(?)	ENDSING DB '$'DATA ENDSCODE SEGMENT	ASSUME DS:DATA,CS:CODE	MAIN PROC FAR	START:	MOV AX,DATA	MOV DS,AX		CALL INPUT	CALL TURN	CALL PRINT16		MOV AH,4CH	;返回dos	INT 21H	MAIN ENDPTURN PROC NEAR	XOR BX,BX	XOR AX,AX	XOR CX,CX	MOV CL,BYTE PTR [NUM10+1]	MOV SI,2	MOV DI,0AHLOP1:	MUL DI	MOV BL,BYTE PTR NUM10[SI]	SUB BL,30H	ADD AX,BX	INC SI	LOOP LOP1	;到这里ax存了输入的数	;接下来转换16进制存入num16地址单元	MOV CL,04H	MOV CH,04H	MOV SI,0LOP2:	XOR BX,BX	;清空bx	;位移ax	ROL AX,CL	MOV BL,AL	AND BL,0FH	CMP BL,09H	JA ZIMUCONTI:	ADD BL,30H	MOV NUM16[SI],BL	;储存	INC SI	DEC CH	JNZ LOP2	RET					;循环结束推出子程序ZIMU:				;转字母	ADD BL,07H	JMP CONTI	TURN ENDPINPUT PROC NEAR	LEA DX,NUM10	MOV AH,0AH	INT 21H	RETINPUT ENDPPRINT16 PROC NEAR	MOV AH,02H	MOV DL,0DH	;回车	INT 21H	MOV AH,02H	MOV DL,0AH	;换行	INT 21H		LEA DX,NUM16	MOV AH,09H	INT 21H	MOV AH,02H	MOV DL,'H'	;'H'	INT 21H	RETPRINT16 ENDPCODE ENDS	END START

运行结果:

 

  • 练习题目

这里我就不分章节了,只记录一些比较难懂的题目。

1. 在汇编语言程序中,对END语句的叙述正确的是(  C  )。

A、END语句是一可执行语句

B、END语句表示程序执行到此结束
C、END语句表示源程序到此结束
D、END语句在汇编后要产生机器码

2. 假设OP1,OP2是已经用DB定义的变量,判断指令格式是否正确

CMP 15, BX (x)

CMP OP1, OP2(x)

CMP AX, OP1(x)
CMP OP1, 25(√)

3. 假设VAR1和VAR2为字变量,LAB为标号

JMP LAB [SI](x)

JNZ VAR1(x)

 

4. 语句LENGTH=SIZE*TYPE是合法的。(x)

 

5. 指出下列指令的错误原因,假设下列指令中的所有标识符均为类型属性为字的变量

(1) MOV AH, BX 

数据类型不一致

(2) MOV AX, [SI][DI]

只有变址+基址寻址方式,没有变址+变址寻址方式

(3) MOV BYTE PTR [BX], 1000 

立即数和指定的操作数类型不一致,指定为字节操作,1000为字类型

(4) MOV CS, AX 

CS代码段寄存器,该寄存器只能由系统管理

(5) MOV WORD_OP1, WORD_OP2

不允许两个内存单元直接传递数据

(6) MOV AX, WORD_OP1+WORD_OP2

两个内存单元地址相加没有意义

(7) SUB [BX],2

未指定数据类型

6. 8086/8088系统中,存储器是分段组织的,存储器物理地址计算式是( B  )

A、段地址+偏移地址

B、段地址*10H+偏移地址
C、段地址*16H+偏移地址
D、段地址+10H*偏移地址

7. 溢出标志可以用来判断运算的结果是否产生溢出。(X)

溢出标志指CF标志位,但是有些运算不是靠CF标志溢出

 

8. 对于有符号的数来说,下列哪个值最大(D )

A、0F8H

B、11010011B
C、82
D、123Q

AB是负数,对于A第一个0是因为汇编中的16进制不允许用字母开头,故A其实就是F8H。

 

 

转载地址:http://znoen.baihongyu.com/

你可能感兴趣的文章
深入理解Mysql索引底层数据结构与算法
查看>>
B+tree结构详解
查看>>
B+树算法在mysql中能存多少行数据?
查看>>
【vue学习】—条件判断、循环遍历
查看>>
【vue学习】—slot插槽的使用
查看>>
【vue学习】—前端模块化
查看>>
STM32 外部中断
查看>>
STM32 PWM
查看>>
STM32 PWM波驱动模拟舵机(库函数版)
查看>>
STM32——ADC
查看>>
破解百度网盘屏蔽文件分享失效被和谐的独家秘籍
查看>>
STM32F10X_XX宏定义的选择
查看>>
在头文件声明全局变量和创建extern
查看>>
stm32 USART 串口通信[操作寄存器+库函数]
查看>>
MATLAB画图常用调整代码
查看>>
WORD2010加载mathtype6.6
查看>>
TTL电平、CMOS电平、RS232电平的区别
查看>>
c语言那些细节之a+1和&a+1的区别
查看>>
交换两个变量的值,不使用第三个变量的四种法方
查看>>
STM32 产生随机数
查看>>