21,458
社区成员
发帖
与我相关
我的任务
分享
;定义数据段,不说了。
DATA SEGMENT
GRADE DW 88,75,95,63,98,78,87,73,90,60
RANK DW 10 DUP (?)
DATA ENDS
;------------------------------------------------------------------------------
;代码段
PROGNAM SEGMENT
ASSUME CS:PROGNAM , DS:DATA
MAIN PROC FAR ;定义函数。
START: ;程序的入口。
MOV AX , DATA
MOV DS , AX ;初始化数据段的段地址。
MOV CX , 10 ;设置循环次数为10
MOV BX , 0 ;BX存放当前被处理的数据在数组中的索引值,初始化为0。
CYCLE: ;外层循环的起始点。
PUSH CX ;保存循环计数(下面的pop CX用来恢复这个计数)。
MOV AX , GRADE[BX] ;取出第BX个学生的成绩,放到AX寄存器中(即当前处理的学生的成绩)。
MOV DX , 0 ;存放当前处理的学生的名次。初始化为0.
LEA SI , GRADE ;取数组的起始偏移地址,放到SI寄存器中。
MOV CX,10 ;个人认为这里应该加上这一句。原来的应该得不到正确的结果。但是没有试验。下面会用C语言来解释这段代码。
NEXT: ;内层循环的起始点。该循环用来找出成绩比AX高的学生人数+1。
CMP AX , [SI] ;用AX和DS:[SI]比较,
JG NOCOUNT ;如果AX大则跳过INC DX
INC DX ;AX不大于DS:[SI]则DX自增一次。
NOCOUNT:
ADD SI , 2 ;使SI加2以指向下一个被计较的对象。
LOOP NEXT ;内层循环。CX不为0则跳到NEXT。
MOV RANK[BX] , DX ;把DX(此时是第BX个学生的排名)存到RANK数组对应的位置。
POP CX ;恢复外层循环的计数。
ADD BX , 2 ;BX加2指向下个被处理的学生的成绩。
LOOP CYCLE ;外层循环。
MOV AX , 4c00h
INT 21h ;结束程序。
MAIN ENDP
PROGNAM ENDS
END START ;定义程序的入口点。
ASSUME CS:CODE,DS:DATA
DATA SEGMENT
GREAD DW 88,75,95,63,98,78,87,73,90,60
RANK DW 10 DUP(0)
MSG1 DB 'THE GREADE:$'
MSG2 DB 'THE RANK :$'
RADIX DW 10
TAB DB '0123456789ABCDEF'
DATA ENDS
CODE SEGMENT
START:MOV AX,DATA
MOV DS,AX
XOR SI,SI
XOR BX,BX ;存放当前被测学生的相对地址指针
XOR DI,DI
MOV DX,1 ;存放当前被测学生的名次计数值
MOV CX,10 ;外层循环计数器
OLP: ;外层循环
MOV AX,GREAD[BX]
XOR SI,SI
MOV DX,1
PUSH CX ;保存外层循环计数器
MOV CX,10 ;内层循环计数器
ILP: ;内层循环
MOV DI,GREAD[SI]
CMP AX,DI
JAE NEXT
INC DX ;名次加一
NEXT:
INC SI
INC SI
LOOP ILP
MOV RANK[BX],DX ;名次放入RANK数组
POP CX
INC BX
INC BX
LOOP OLP
;------显示成绩----------------
LEA DX,MSG1
MOV AH,09H
INT 21H
MOV CX,10
XOR BX,BX
SHOW_G:
MOV AX,GREAD[BX]
CALL OUTPUT
MOV AH,02H
MOV DL,' '
INT 21H
ADD BX,2
LOOP SHOW_G
;----------回车换行------------------
MOV AH,02H
MOV DL,0AH
INT 21H
MOV AH,02H
MOV DL,0DH
INT 21H
;----------显示名次-------------------
LEA DX,MSG2
MOV AH,09H
INT 21H
MOV CX,10
XOR BX,BX
SHOW_R:
MOV AX,RANK[BX]
CALL OUTPUT
MOV AH,02H
MOV DL,' '
INT 21H
ADD BX,2
LOOP SHOW_R
MOV AX,4C00H
INT 21H
;显示子程序
OUTPUT PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
CMP AX,9
JA LARGE
XOR DX,DX
MOV DL,AL
ADD DL,30H
MOV AH,02H
INT 21H
JMP RETURN
LARGE:
XOR CX, CX ;CX统计位数
TRANS:
MOV DX, 0
DIV RADIX ;RADIX除数
PUSH DX ;余数入栈
INC CX
TEST AX,AX
JNZ TRANS
OM:
POP BX ;余数出栈
MOV DL,BYTE PTR TAB[BX]
MOV AH,02H
INT 21H
LOOP OM
RETURN:
POP DX
POP CX
POP BX
POP AX
RET
OUTPUT ENDP
CODE ENDS
END START
DATA SEGMENT
GRADE DW 88,75,95,63,98,78,87,73,90,60
RANK DW 10 DUP (1)
TEN DW 10
DATA ENDS
PROGNAM SEGMENT
ASSUME CS:PROGNAM , DS:DATA
MAIN PROC;定义函数。
MOV AX , DATA
MOV DS , AX ;初始化数据段的段地址。
MOV CX , 10 ;设置循环次数为10
MOV SI, OFFSET GRADE
OLP:
MOV AX, [SI]
XOR BX, BX ; BX = 0,作为数组下标
ILP:
CMP AX, GRADE[BX]
JLE LESSEQ
INC RANK[BX] ; 如果AX>GRADE[BX],RANK[BX] + 11
LESSEQ:
ADD BX, 2 ;索引加2,因为每个数据占2个字节
CMP BX, 20 ; 到达数组末尾
JL ILP
ADD SI, 2 ; SI 指向下一个元素
LOOP OLP
MOV CX, 10
MOV SI, OFFSET RANK ;SI指向rank数组头
PRINT:
MOV AX, [SI] ;读取一个元素到AX
PUSH CX
XOR CX, CX
NEXTDIGIT:
XOR DX, DX
DIV TEN ;ax = ax / 10, dx = ax % 10
CMP AX, 0 ; 如果ax=0,说明已经到了个位数,也就是最后一个位数
JE LASTDIGIT
PUSH DX ; 每一个十进制位压栈
INC CX ; 这里CX用作计数器,计算有多少个十进制位
JMP NEXTDIGIT
LASTDIGIT:
PUSH DX
INC CX
NEXTDIGIT2:
POP DX ; 十进制位弹栈,转化成ascii码输出
ADD DL, '0'
MOV AH, 2
INT 21H
LOOP NEXTDIGIT2
MOV DL, ' ' ;输出一个空格
MOV AH, 2
INT 21H
POP CX ;恢复先前保存的cx
ADD SI, 2 ; SI指向rank数组的下一个元素
LOOP PRINT
MOV AX , 4c00h
INT 21h ;结束程序。
MAIN ENDP
PROGNAM ENDS
END MAIN;定义程序的入口点。
CYCLE:
PUSH CX
MOV AX ,GRADE[BX]
MOV DX ,1 ; 存放当前处理的学生的名次。初始化为1.
LEA SI ,GRADE
MOV CX,10
NEXT:
CMP AX , [SI]
JNC NOCOUNT ; 如果AX不小于[SI]则跳过INC DX