4.1

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,这和编译器有关系,不同编译器编译成的汇编指令可能有所不同。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值