汇编作业【4】

1、字符串的复制

编写一个汇编程序,实现字符串的复制功能,并且将复制
的字符串显示出来。(选做部分:倒序显示复制字符串)

  • 直接编写
DATAS SEGMENT
	;string_a db 'He','$'
    ;string_a db 'Hello world','$'
    string_a db 'The School of Information Science and Engineering Shandong University','$'
DATAS ENDS

STACKS SEGMENT
DB 200 DUP(?)
STACKS ENDS
EXT SEGMENT
string_b db 100 dup(?) ;定义一个空的字符串b准备复制
EXT ENDS

CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS,ES:EXT
START:
MOV AX,DATAS
MOV DS,AX
MOV AX,EXT
MOV ES,AX

mov ah<span class="token punctuation">,</span><span class="token number">0</span>
mov cx<span class="token punctuation">,</span><span class="token number">200</span>	<span class="token punctuation">;</span>最多复制<span class="token number">200</span>长度的字符串

copy: ;复制
MOV AL,ds:[si] ;读取
cmp AL,24H
je output ;读到'$'就退出,开始输出
mov es:[si],AL ;复制
inc si
loop copy

output: ;输出
mov cx,si
mov si,0
shunxu: ;顺序输出 从0到si-1
mov dl,es:[si]
mov ah,2
int 21h
inc si
loop shunxu

mov dl<span class="token punctuation">,</span><span class="token number">32</span> <span class="token punctuation">;</span>空格用以区分
<span class="token keyword">int</span> <span class="token number">21</span>h
mov cx<span class="token punctuation">,</span>si

nixu: ;逆序输出 从si-10
mov dl,es:[si-1]
mov ah,2
int 21h
dec si
loop nixu

MOV AH<span class="token punctuation">,</span><span class="token number">4</span>CH	<span class="token punctuation">;</span>结束
INT <span class="token number">21</span>H

CODES ENDS
END START

  • 按书上的方法
DATAS SEGMENT
	;string_a db 'He','$'
    ;string_a db 'Hello world','$'
    string_a db 'The School of Information Science and Engineering Shandong University','$'
    COUNT EQU $-string_a ;COUNT=$-string_a
 						 ;EQU 伪指令
DATAS ENDS

STACKS SEGMENT
DB 200 DUP(?)
STACKS ENDS

EXT SEGMENT
string_b db 100H dup(?) ;定义一个空的字符串b准备复制,长度不要超过100H
string_c db 100H dup(?) ;用于逆序存储
EXT ENDS

CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS,ES:EXT
START:
MOV AX,DATAS
MOV DS,AX
MOV AX,EXT
MOV ES,AX

MOV SI<span class="token punctuation">,</span><span class="token number">0</span>		<span class="token punctuation">;</span>两个循环变量都从<span class="token number">0</span>开始
MOV DI<span class="token punctuation">,</span><span class="token number">0</span>		
MOV CX<span class="token punctuation">,</span>COUNT	<span class="token punctuation">;</span>循环次数是字符串长度
CLD				<span class="token punctuation">;</span>指示方向,正向
REP MOVSB

LEA DX<span class="token punctuation">,</span>STRING_B	<span class="token punctuation">;</span>顺序
MOV AH<span class="token punctuation">,</span><span class="token number">9</span>
INT <span class="token number">21</span>H			<span class="token punctuation">;</span>输出

MOV SI<span class="token punctuation">,</span>count	<span class="token punctuation">;</span>si从末尾到开头
lea di<span class="token punctuation">,</span>string_c	<span class="token punctuation">;</span>di从string_c的地址
MOV CX<span class="token punctuation">,</span>COUNT	<span class="token punctuation">;</span>循环次数是字符串长度
sub si<span class="token punctuation">,</span><span class="token number">2</span>
dec cx
s<span class="token operator">:</span>
mov ax<span class="token punctuation">,</span>ds<span class="token operator">:</span><span class="token punctuation">[</span>si<span class="token punctuation">]</span>
mov es<span class="token operator">:</span><span class="token punctuation">[</span>di<span class="token punctuation">]</span><span class="token punctuation">,</span>ax
dec si			<span class="token punctuation">;</span>一加一减
inc di
loop s

mov ax<span class="token punctuation">,</span><span class="token char">'$'</span>		<span class="token punctuation">;</span>补全字符串末尾的<span class="token char">'$'</span>
mov es<span class="token operator">:</span><span class="token punctuation">[</span>di<span class="token punctuation">]</span><span class="token punctuation">,</span>ax

lea DX<span class="token punctuation">,</span>string_c	
MOV AH<span class="token punctuation">,</span><span class="token number">9</span>		<span class="token punctuation">;</span>输出
INT <span class="token number">21</span>H

MOV AH<span class="token punctuation">,</span><span class="token number">4</span>CH		<span class="token punctuation">;</span>结束
INT <span class="token number">21</span>H

CODES ENDS
END START

2、中断调用产生随机数

  • 中断

利用中断调用,在屏幕上显示 1—9 之间随机数。中断号 86H

DATAS SEGMENT
   infon DB 0DH,0AH,'RANDOM NUMBER:','$' ;提示显示随机数
DATAS ENDS

STACKS SEGMENT STACK
DB 200 DUP(0)
STACKS ENDS

CODES SEGMENT
ASSUME DS:DATAS,SS:STACKS,CS:CODES

START:
MOV AX,DATAS
MOV DS,AX

LEA DX,infon
MOV AH,9
INT 21H ;输出提示字符串

MOV AX,CS ;调整ds寄存器指向的位置,使其指向程序区
MOV DS,AX

MOV AX,0
MOV ES,AX ;段偏移地址指向0000
MOV DI,200H ; 设置es:si指向目的地址
MOV SI,OFFSET RANDOM ; 设置ds:si指向源地址
MOV CX,OFFSET RANDOMEND-OFFSET RANDOM ;设置CX为传输长度

CLD ;设置传输方向为正
REP MOVSB

MOV AX,0
MOV ES,AX

MOV BX,86H*4 ;把中断号86H的地址赋给BX

MOV WORD PTR ES:[BX],200H
MOV WORD PTR ES:[BX+2],0 ;进行字操作,将其安装在0:200

INT 86H ;调用中断例程

MOV AX,4CH
INT 21H ;程序结束

RANDOM: ;中断例程

MOV AH,0
INT 1AH ;读时钟计数器值.CX:DX存着计数器值

MOV AX,DX
MOV DX,0
MOV BX,10
DIV BX ;除以10获得1-9随机数

ADD DL,30H;余数转为ASCII码
MOV AH,2
INT 21H ;显示输出随机数

IRET ;中断返回
RANDOMEND:NOP

CODES ENDS
END START

  • DOS

然后是使用DOS提供的中断,王爽《汇编语言》没有细讲。主要是使用INT 21H的25号和35号中断,实现类似于之前的的功能。

DATAS SEGMENT 
   infon DB 'RANDOM NUMBER:','$'	;提示显示随机数
DATAS ENDS 
STACKS SEGMENT STACK 
   DB 200H DUP(?) 
STACKS ENDS
CODES SEGMENT
   ASSUME DS:DATAS,CS:CODES,SS:STACKS
START:            
   MOV AX,DATAS
   MOV DS,AX   

LEA DX,infon ;显示提示信息
MOV AH,9
INT 21H

MOV AL,86H ;将要设置的中断类型号86H放入AL准备取中断向量
MOV AH,35H
INT 21H ;调用INT 21H函数的取中断功能

MOV AX,OFFSET RANDOM ;设置中断向量 DS:DX
MOV DX,AX
MOV AX,SEG RANDOM
MOV DS,AX

MOV AL,86H
MOV AH,25H ;设置新的86号中断
INT 21H ;执行INT21H的25H号功能,设置新的86号中断

INT 86H ;执行86号中断

MOV AH,4CH
INT 21H

RANDOM PROC ;定义一个过程

MOV AH,0 ;int 1Ah是关于时钟的中断
INT 1AH ;读时钟计数器值.CX:DX存着计数器值

MOV AX,DX
MOV DX,0
MOV BX,10
DIV BX ;除以10获得1-9随机数

ADD DL,30H ;30H,余数转为ASCII码
MOV AH,2
INT 21H ;显示输出随机数

IRET ;中断返回
RANDOM ENDP
CODES ENDS
END START

3、成绩统计

键盘输入10个学生的成绩,编写一个程序统计60-69分,
70-79 分,80-89 分,90-99 分及 100 分的人数,分别存放
在Score6,Score7,Score8,Score9和Score10单元中。
【输入 10 个学生的成绩如下】
65 98 78 82 88 95 72 62 90 100

更新:之前粘贴错了,现在改过来了。感谢指正。

DATAS SEGMENT
   INFON1 DB 0DH,0AH,'PLEASE INPUT SCORES:','$';提示输入
   INFON2 DB 13,10,'THE NUMBER OF SCORE6-SCORE10 IS:'  ;提示输出成绩人数
   SCORE6 DB 30H
   DB 32
   SCORE7 DB 30H
   DB 32
   SCORE8 DB 30H
   DB 32
   SCORE9 DB 30H
   DB 32
   SCORE10 DB 30H
   DB '$'
DATAS ENDS

STACKS SEGMENT
DB 200 DUP(0)
STACKS ENDS

CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
MOV AH,9
LEA DX,INFON1
INT 21H ;显示提示输入字符串

MOV CX,10 ;设置循环次数
S: MOV AH,1
INT 21H ;输入一个数的最高位。
CALL COMPARE;调用子程序进行比较分类
INT 21H
MOV AH,2
MOV DL,32
INT 21H ;显示空格,将成绩分隔开
LOOP S ;循环输入每一个成绩
MOV AH,9
LEA DX,INFON2
INT 21H
MOV AX,4CH
INT 21H ;程序结束

COMPARE PROC ;定义子程序COMPARE,比较最高位数值
PUSH AX
CMP AL,31H ;最高位与1比较相等则跳转到S10
JZ S10
CMP AL,36H ;最高位与6比较
JZ S6 ;相等则跳转到S6
CMP AL,37H ;最高位与7比较
JZ S7 ;相等则跳转到S7
CMP AL,38H ;最高位与8比较
JZ S8 ;相等则跳转到S8
CMP AL,39H ;最高位与9比较
JZ S9 ;相等则跳转到S9

S6:
ADD [SCORE6],1 ;60-69的人数加一
JMP OVER
S7:
ADD [SCORE7],1 ;70-79的人数加一
JMP OVER
S8:
ADD [SCORE8],1 ;80-89的人数加一
JMP OVER
S9:
ADD [SCORE9],1 ;90-99的人数加一
JMP OVER
S10:
ADD [SCORE10],1 ;100的人数加一
MOV AH,1
INT 21H ;输入十位
OVER:POP AX
RET ;返回主程序
COMPARE ENDP ;COMPARE子程序结束

CODES ENDS
END START

其实这里输入50以下的也会被统计成60-69的。

posted @ 2022-03-31 00:48  zokji  阅读(88)  评论(0)    收藏  举报