您的位置:首页 > 其它

4.1

2016-03-24 17:05 225 查看
DATAS SEGMENT
string_a db 'The School of Information Science and Engineering Shandong University','$'
DATAS ENDS

EXT SEGMENT
string_b db 100 dup(?)
EXT ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS

CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS,ES:EXT
START:
MOV AX,DATAS
MOV DS,AX
MOV SI,69
MOV AX,EXT
MOV ES,AX
MOV DI,69
MOV CX,70
STD
REP MOVSB
MOV AX,EXT
MOV DS,AX
MOV DX,0
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
CODES ENDS
END START




Created with Raphaël 2.1.0开始获得原数据地址,设置DS:SI获得目的数据地址,设置ES:DI设置CX为数据长度用CLD(正向)/STD(反向)用REP MOVSB指令复制数据显示复制数据结束

2.产生1-9随机数

计算机的主机板上都会有这样一个定时/记数器用来计算当前系统时间,每过一个时钟信号周期都会使记数器加一,记数器的值存放在内存的0040:006CH处,这一段内存空间是这样定义的:

TIMER_LOW DW ? ;地址为 0040:006CH

TIMER_HIGH DW ? ;地址为 0040:006EH

TIMER_OFT DB ? ;地址为 0040:0070H

时钟中断服务程序中,每当TIMER_LOW转满时,此时,记数器也会转满,记数器的值归零,即TIMER_LOW处的16位二进制归零,而TIMER_HIGH加一

所以可以用0040:006CH处的值当成随机数的种子,取个位即可

DATAS SEGMENT

DATAS ENDS

STACKS SEGMENT

STACKS ENDS

CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,CS
MOV DS,AX
MOV SI,OFFSET RAND
MOV AX,0
MOV ES,AX
MOV DI,200H                       ;将中断安装在一般不被占用的0200:0000处
MOV CX,OFFSET RANDEND-OFFSET RAND ;取得中断子程序的长度
CLD
REP MOVSB

MOV AX,0
MOV ES,AX
MOV WORD PTR ES:[86H*4],200H     ;设置中断向量表
MOV WORD PTR ES:[86H*4+2],0

S:  INT 86H                          ;如果产生随机数是0的话跳过
MOV CL,AH
JCXZ S
ADD AH,30H
MOV DL,AH
MOV AH,02H                       ;显示产生的随机数
INT 21H
MOV AH,4CH
INT 21H

RAND:
PUSH DS
PUSH BX
MOV AX,0040H
MOV DS,AX
MOV AX,WORD PTR DS:[006CH]
MOV AH,0                     ;AH置0防止除法溢出
MOV BL,10                    ;此时余数为0-9
DIV BL
POP BX
POP DS
IRET
RANDEND:
NOP
CODES ENDS
END START




Created with Raphaël 2.1.0开始取得中断程序的地址安装中断程序设置中断向量表结束

Created with Raphaël 2.1.0中断子程序取得一个随机数种子,例如系统时间将随机数的除以A余数即为需要的随机数IRET

3.键盘输入10个学生的成绩,编写一个程序统计60-69分,70-79分,80-89分,90-99分及100分的人数,分别存放在Score6,Score7,Score8,Score9和Score10单元中。

DATAS SEGMENT
STRING DB 'INPUT:$' ;输入提示信息
S6 DB 0             ;存放60-69人数
S7 DB 0             ;存放70-79人数
S8 DB 0             ;存放80-89人数
S9 DB 0             ;存放90-99人数
S10 DB 0            ;存放100人数
DATAS ENDS

STACKS SEGMENT

STACKS ENDS

CODES SEGMENT
ASSUME CS:CODES,DS:DATAS
START:
MOV AX,DATAS
MOV DS,AX
MOV DX,OFFSET STRING   ;显示提示信息
MOV AH,09H
INT 21H
CALL LF                ;输入一个换行符
XOR AX,AX              ;先将下面用到的寄存器清零
XOR BX,BX
XOR CX,CX
S1:
MOV AH,1              ;输入一个带键盘回显的字符
INT 21H
MOV DH,AL             ;暂存在DH中
CMP DH,0DH            ;如果输入回车,则开始显示分数段人数
JE DISPLAY
MOV AH,1              ;再输入第二个字符,这里并不需要判断第二个字符的大小
INT 21H
CMP DH,'1'            ;与1比较,如果相等,则说明输入的可能是100,转入NEXT4处理
JE NEXT4
MOV DL,0              ;显示一个空格,等到输入下个数字
MOV AH,2
INT 21H
CMP DH,'6'            ;等于6则60-69加一,以下同理
JA NEXT1
JB S1
INC S6
JMP S1
NEXT1:
CMP DH,'7'
JA NEXT2
INC S7
JMP S1
NEXT2:
CMP DH,'8'
JA NEXT3
INC S8
JMP S1
NEXT3:
INC S9
JMP S1
NEXT4:
MOV AH,1          ;因为100有三位数,所以再输入一位
INT 21H
MOV DL,0
MOV AH,2
INT 21H
INC S10
JMP S1
DISPLAY:
MOV SI,OFFSET S6      ;开始显示S6-S10内存单元的数据
MOV CX,5
S:
SUB AX,AX
MOV AL,[SI]
MOV DH,10
DIV DH
XCHG AX,BX
MOV DL,BL
ADD DL,30H
MOV AH,2
INT 21H
INC SI
MOV DL,BH
ADD DL,30H
MOV AH,2
INT 21H
CALL LF
LOOP S
MOV AH,4CH
INT 21H
LF:
MOV DL,0AH                  ;输出一个回车
MOV AH,2
INT 21H
RET
CODES ENDS
END START




Created with Raphaël 2.1.0开始显示提示信息输入一个换行符将下面用到的寄存器清零输入一个带键盘回显的字符再输入一个带键盘回显的字符判断第一个字符与1,6,7,8,9关系,相等则对应分数段+1收到回车时显示统计信息结束

心得

每一个程序都有很多种实现方式,选择合适的方式可以提高程序的执行效率以及开发难度

程序错误最难发现的就是逻辑错误,在写程序之前一定要想好程序流程,画好程序流程图

在学过汇编之后,感觉对一些高级语言函数的实现有了一些了解,比如之前学过c语言里的
printf()
函数,以前只知道它的作用,现在大致了解它是怎么实现的了。一些c中的问题,可能不学汇编完全看不出来是怎么一回事,但是如果将其反编译之后再看汇编代码,就很清楚了,比如

i=1 i=(++i)+(++i)
最后结果可能是4或者5,这和编译器有关系,不同编译器编译成的汇编指令可能有所不同。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  4-1