汇编程序
发布网友
发布时间:2022-04-20 10:03
我来回答
共2个回答
热心网友
时间:2023-10-03 09:57
; 题目名称:输入成绩,分别升序、降序排序
; 题目来源:http://zhidao.baidu.com/question/132061481.html
; 操作说明:成绩按百分制,输入成绩时,最多3位数,即100分;小于100分的成绩,按回车确认
; 本程序在MASMPlus 1.2集成环境下通过编译,经过调试,运行正确。
Code Segment
Assume CS:Code,DS:Code
CR equ 000DH
LF equ 000AH
KBBack equ 0008H
; -------------------------------------
; 功能:显示指定地址(Str_Addr)的字符串
; 入口:
; Str_Addr=字符串地址(要求在数据段)
; 用法: Output Str_Addr
; 用法举例:Output PromptStr
Output MACRO Str_Addr
push ax
lea dx,Str_Addr
mov ah,9
int 21h
pop ax
EndM
; -------------------------------------
; 功能:在当前光标位置显示一个字符
; 入口:dl=要显示的字符
Output_Chr proc Near
push ax
mov ah,2
int 21h
pop ax
ret
Output_Chr Endp
; -------------------------------------
; 功能:取光标位置
; 入口:无
; 出口:DH=行号,DL=列号
GetCursor Proc Near
PUSH DS
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH CS
POP DS
XOR BX,BX
MOV AH,3
INT 10H
MOV Cursor_Row,DH
MOV Cursor_Col,DL
POP DX
POP CX
POP BX
POP AX
POP DS
RET
Cursor_Row DB ?
Cursor_Col DB ?
GetCursor EndP
; -------------------------------------
; 功能:置光标位置
; 入口:Cursor_Row=行坐标; Cursor_Col: 列坐标)
SetCursor Proc Near
PUSH DS
PUSH DX
PUSH CX
PUSH BX
PUSH AX
PUSH CS
POP DS
MOV DH,Cursor_Row
MOV DL,Cursor_Col
XOR BX,BX
MOV AH,2
INT 10H
POP AX
POP BX
POP CX
POP DX
POP DS
RET
SetCursor EndP
; -------------------------------------
; 功能:键盘输入一个指定位数(N)的十进制数字,将其转换成二进制数并保存在指定的内存单元。
; 输足N位的,自动结束输入;不足N位的,空格结束输入。
; 由于限定最大数据类型为字,所以,数字位数最多:5,最大无符号数:65536
; 约定:直接回车,视为数字0
; 入口:cs:@@Digits=数字位数;es:di=保存输入的数字首地址
; cs:@@Type_Data=保存的数据类型,B=字节类型,W=字类型。
; 出口:转换后的二进制数保存在di所指的单元
Input_Dec Proc Near
push ds
push dx
push cx
push bx
push di
push cs
pop ds
call GetCursor ;取光标位置
mov dx,WORD PTR Cursor_Row
mov @@Tmp_Cursor,dx ;保存起始光标位置
lea di,@@Save_Tmp
push di
cld
mov cl,@@Digits
xor ch,ch
push cx
@@Input_Dec: call GetCursor ;取光标位置
mov ah,1 ;从键盘接受一个字符
int 21h
cmp al,27 ;Esc?
jz @@Return
cmp al,CR ;若键入的是回车,已经键入的数字不足N位
jz @@ASC_Dec ;转去处理已经键入的数字
cmp al,KBBack
jz @@KB_Back ;若是回空键,重新输入
cmp al,'0'
jb @@KBBack ;若低于数字'0',重新输入
cmp al,'9'
ja @@KBBack ;若高于数字'9',重新输入
jmp @@Save_Dig
@@KB_Back: cmp cl,cs:@@Digits ;十进制数字位数
jz @@Input_Dec
inc cx
dec di
dec Cursor_Col
@@KBBack: call SetCursor ;置光标位置
jmp @@Input_Dec
@@Save_Dig: and al,0fh ;转换成二进制数
stosb ;保存
loop @@Input_Dec ;接受下一个数字
@@ASC_Dec: mov ax,cx
pop cx
pop si
sub cx,ax ;实际输入的数字位数
xor bp,bp
xor dx,dx
xor ax,ax
jcxz @@Save_Ret ;若直接回车,没有输入任何数字,按输入'0'处理
dec cx ;实际输入的数字位数减1,准备把输入的这一串数字转换成二进制数
jcxz @@One_Digit ;若输入的数字只有一位,转去直接保存这个二进制数
mov bx,10
@@Mul_Ten: lodsb
xor ah,ah
add ax,bp
mul bx
mov bp,ax
loop @@Mul_Ten
@@One_Digit: lodsb
xor ah,ah
add ax,bp
@@Save_Ret: pop di
cmp @@Type_Data,'B' ;字节类型?
jz $+5
stosw
jmp $+3
stosb
pop bx
pop cx
pop dx
pop ds
clc
ret
@@Return: pop cx
pop di
pop di
pop bx
pop cx
pop dx
pop ds
stc
ret
@@Tmp_Cursor dw ? ;起始光标位置
@@Digits db ? ;十进制数字位数
@@Type_Data db 'B' ;保存的数据类型。B=字节类型,W=字类型
@@Save_Tmp db 7 p(?)
Input_Dec EndP
; -------------------------------------
; 功能:把AX中的二进制无符号数转换成显式的十进制ASCII码,并送显示屏显示
; 入口:AX=二进制数
; 出口:在当前光标位置显示转换后的ASCII码数字
Unsi_Dec_ASCII Proc Near
push dx
push bx
push di
mov bx,10
lea di,@@Temp_Save[5]
mov BYTE PTR [di],'$'
dec di
cld
@@Divide: xor dx,dx
div bx
or dl,30h
mov [di],dl
dec di
test ax,ax
jnz @@Divide
inc di
push di
pop dx
mov ah,9
int 21h
pop di
pop bx
pop dx
ret
@@Temp_Save db 6 p(?)
Unsi_Dec_ASCII EndP
; -------------------------------------
Input_Score proc Near
mov @@Digits,3 ;十进制数字位数
mov @@Type_Data,'B' ;保存的数据类型。B=字节类型,W=字类型
lea di,Buffer ;成绩保存地址
Output Prompt_Str ;提示输入成绩
@@Input_Scores:call Input_Dec ;键盘输入一个指定位数(N)的十进制数字,将其转换成二进制数并保存在指定的内存单元
pushf
inc Cursor_Col
call Setcursor
mov dl,20h
call Output_Chr ;显示一个空格
popf
jnc @@Input_Scores
mov cx,di
sub cx,offset Buffer ;成绩个数
mov Counter,cx ;保存
ret
Input_Score Endp
; -------------------------------------
Increase_Sort proc Near
mov BYTE ptr @@Compare[5],76h
jmp @@Sorting
Increase_Sort Endp
; -------------------------------------
Decrease_Sort proc Near
mov BYTE ptr @@Compare[5],73h
@@Sorting: lea si,Buffer
mov cx,Counter ;成绩个数
dec cx ;外循环次数
cld
@@Scanning: push cx ;入栈保存外循环次数
push si ;入栈保存数组地址
@@Compare: mov di,si ;当前数组元素地址赋给目的变址寄存器,以备交换之用
lodsb ;将当前数组元素读入累加器
cmp al,[si] ;当前数组元素与相邻的下一个数组元素相比较
jae @@NextOne ;若大于或等于,不作数据交换,处理下一个数组元素
xchg al,[si] ;若小于,交换数组元素
stosb ;保存数值较小者
@@NextOne: loop @@Compare ;处理下一个数组元素
pop si ;数组地址出栈
pop cx ;外循环次数出栈
loop @@Scanning ;下一趟比较
mov WORD ptr Cursor_Row,12
call SetCursor ;置光标位置
lea si,Buffer
mov cx,Counter ;成绩个数
@@List_Scores: lodsb
xor ah,ah
call Unsi_Dec_ASCII ;把AX中的二进制无符号数转换成显式的十进制ASCII码,并送显示屏显示
mov dl,20h
call Output_Chr ;显示一个空格
loop @@List_Scores
ret
Decrease_Sort Endp
; -------------------------------------
Prompt_Menu db 35 p(20h),'Main Menu',13,10
db 30 p(20h),201,18 p(205),187,13,10
db 30 p(20h),186,' 1. input scores ',186,13,10
db 30 p(20h),186,' 2. increase sort ',186,13,10
db 30 p(20h),186,' 3. decrease sort ',186,13,10
db 30 p(20h),186,' 0. Return to DOS ',186,13,10
db 30 p(20h),200,18 p(205),188,13,10
db 32 p(20h),'Choice(0-3):$'
Cursor_Tmp dw ?
Counter dw ? ;成绩个数
Proc_Addr dw Input_Score,Increase_Sort,Decrease_Sort
Prompt_Str db 13,10,10,'Please input scores:',13,10,'$'
Press_Key db 7,13,12 p(10),'The complated. Press any key to exit...$'
Start: push cs
pop ds ;使数据段与代码段同段
mov ax,3 ;设置25*80字符显示方式
int 10h
Output Prompt_Menu ;显示主菜单
xor bx,bx
mov ah,3
int 10h
mov Cursor_Tmp,dx
mov ax,0b800h
mov es,ax ;设置字符显示方式缓冲区段地址
mov di,35*2+1
mov al,13 ;LightMagenta
mov cx,10
cld
Attribute: stosb
inc di
loop Attribute
mov di,160*2+32*2+1
stosb
add di,159
stosb
add di,159
stosb
add di,159
stosb
mov di,160*7+39*2+1
stosb
inc di
stosb
inc di
stosb
push cs
pop es ;使附加段与代码段同段
Choice_Func: mov dx,Cursor_Tmp
xor bx,bx
mov ah,2
int 10h
mov ah,1
int 21h
cmp al,'0'
jz Exit_Proc
cmp al,'1'
jb Choice_Func
cmp al,'3'
ja Choice_Func
and ax,0fh
mov bx,ax
dec bx
shl bx,1
call Proc_Addr[bx]
jmp Choice_Func
; -------------------------------------
Exit_Proc: Output Press_Key ;提示操作完成,按任意键结束程序
mov ah,1
int 21h
mov ah,4ch ;结束程序
int 21h
Buffer db ? ;数据缓冲区
Code ENDS
END Start ;编译到此结束
热心网友
时间:2023-10-03 09:57
;首先,这里面有in.h、input和output函数等,你没有的话,我传给你
;另外,程序需要在dos下ml和link,命令你不知道的话我告诉你
;程序先要求输入命令,我加入了“0”这条命令,表示结束程序
;若不输入0,则程序会回到开始重新开始新的循环
;排序方法是冒泡排序法,分别写了两个子程序
.386
.MODEL FLAT
ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD
INCLUDE io.h
cr EQU 0dh
Lf EQU 0ah
.STACK 4096
.DATA
out0 byte "请输入命令:1表示输入 2代表增序 3代表降序", cr, Lf, 0
out1 byte "请输入所需的数的个数", cr, Lf, 0
out2 byte "请输入数据", cr, Lf, 0
out3 byte "结果是:", cr, Lf, 0
out4 byte "输入错误", cr, Lf, 0
lenth dword 1 ; //记录要输入的数的个数,初始为1
number dword 20 DUP (?) ; 最多20个数
string byte 11 DUP (?), 0
newline byte cr, Lf, 0
PUBLIC _start
.Code
_start:
begin:
output out0
input string, 11
atod string
cmp eax, 0 ; 输入0表示终止程序
je endof
cmp eax, 1
je inputnumber
cmp eax, 2
jne else1
call increase
jmp outout
else1:
cmp eax, 3
jne else2
call decrease
jmp outout
else2:
output out4
jmp begin
inputnumber:
output out1
input string, 11
atod string
mov lenth, eax
mov ecx, eax
lea edi, number
output out2
forinput:
input string, 11
atod string
mov [edi], eax
add edi, 4
loop forinput
jmp begin
outout:
output out3
mov ecx, lenth
lea edi, number
foroutput:
dtoa string, [edi]
output string
add edi, 4
loop foroutput
output newline ; 输出回车
jmp begin
endof:
INVOKE ExitProcess, 0
increase PROC NEAR32 ; 增序排列
mov eax, lenth
begin1:
dec eax
cmp eax, 0
jng end1
mov ecx, eax
lea edi, number
forincrease:
mov ebx, [edi]
cmp ebx, [edi+4]
jng nochange1
mov ebx, [edi]
xchg ebx, [edi+4]
xchg ebx, [edi]
nochange1:
add edi, 4
loop forincrease
jmp begin1
end1:
ret
increase ENDP
decrease PROC NEAR32 ; 降序排列
mov eax, lenth
begin2:
dec eax
cmp eax, 0
jng end2
mov ecx, eax
lea edi, number
fordecrease:
mov ebx, [edi]
cmp ebx, [edi+4]
jnl nochange2
mov ebx, [edi]
xchg ebx, [edi+4]
xchg ebx, [edi]
nochange2:
add edi, 4
loop fordecrease
jmp begin2
end2:
ret
decrease ENDP
END