汇编语言程序设计:从键盘上输入20个有符号数,将他们排序并在屏幕上显示,求程序具体解释,最好能有大概的流程过程说明

qq_33538022 2015-12-30 05:02:53
求大神下面程序具体解释


DATA SEGMENT
NOTE0 DB 'Note: The character that separates the integers can be any visible ASCII except ten digits(',27H,'0',27H,'-',27H,'9',27H,').',0DH,0AH,'$'
NOTE1 DB 0DH,0AH,'==================================================================',0DH,0AH ;0DH和0AH分别是回车和换行的ASCII码
DB 'Please input 20 (or less) decimal integers (-32768 to +32767):',0DH,0AH,'$' ;'$'是字符串的结束标志
NOTE2 DB 0DH,0AH,'==================================================================',0DH,0AH
DB 0DH,0AH,'The inputed integers: ','$'
NOTE3 DB 0DH,0AH,'==================================================================',0DH,0AH
DB 0DH,0AH,'How many decimal integers? ','$'
NOTE4 DB 0DH,0AH,'The sorted result: ',0DH,0AH,'$'
ERR_STR DB 0DH,0AH,'******************************************************************',0DH,0AH
DB 'Input error!',0DH,0AH
CON_STR DB 0DH,0AH,'******************************************************************',0DH,0AH
DB 0DH,0AH,'Continue? Y or N?','$'

DEC_STR DB 200 ;用来存放输入的原始数据
DB 60 ;db 60意思是定义一个字节初始值为60
DB 150 DUP('$') ;db 100 dup (?)意思是定义100个未经初始化的字节; db ?意思是定义一个未经初始化的字节
TOTAL DB 3 DUP('$') ;用来记录输入的数字个数
DEC_NUM DW 30 DUP(?) ;用来存放将输入的ASCII码转换成2进制数以便比较的结果
OUT_STR DB 150 DUP('$') ;存放待输出的字符组信息
DATA ENDS

STACK SEGMENT STACK
STT DB 100 DUP(60) ;堆栈
STACK ENDS

CODE SEGMENT
MAIN PROC FAR
ASSUME CS:CODE,DS:DATA,SS:STACK
START: MOV AX,STACK
MOV SS,AX ;初始化ss
MOV AX,DATA
MOV DS,AX
;---------------------------------- 输出提示信息
LEA DX,NOTE0 ;直接显示NOTE0
MOV AH,09H ;显示
INT 21H ;调用dos

DISP0: LEA DX,NOTE1 ;直接显示NOTE1
MOV AH,09H
INT 21H
LEA DX,DEC_STR ;将原始数据存入该空间
MOV AH,0AH ;字符串
INT 21H

MOV AL,BYTE PTR[DEC_STR+2] ;输入合法性的标志:开头是数字或者符号 ;将DEC_STR的偏移地址+2指向的第一个字节赋值给AL
CMP AL,'0' ;条件判转指令本身占两个字节
JAE CMP1 ;A为大于,B为小于,E为等于

CMP AL,'+' ;检验AL寄存器内的值是不是+
JE DISP2
CMP AL,'-'
JE DISP2

JMP DISP1 ;JMP 无条件跳转
CMP1: CMP AL,'9'
JBE DISP2 ; 0〈=?〈=9 跳转到DISP2

DISP1: LEA DX,ERR_STR
MOV AH,09H ;显示
INT 21H
CON_YN: MOV AH,01H ;程序结束处询问是否需要继续
INT 21H
CMP AL,'Y' ;检验AL寄存器内的值是不是Y
JE DISP0
CMP AL,'y'
JE DISP0
CMP AL,'N'
JE OVER0
CMP AL,'n'
JE OVER0
OVER0: JMP OVER ;用以结束程序

DISP2: LEA DX,NOTE2 ;将输入的数据输出以便用户对照其正确性
MOV AH,09H ;显示NOTE2
INT 21H

LEA DX,[DEC_STR+2]
MOV AH,09H
INT 21H
;===============================COUNT HOW MANY DECIMAL INTEGERS 计算个数
LEA SI,DEC_STR
MOV CL,BYTE PTR[SI+1] ;CL中存放输入的总字符数 ;BYTE PTR用来定义所存入的是字节单元。[si+1]以字节单元存入SI中
MOV CH,0
PUSH CX ;cx的值压入堆栈保存
MOV AL,0 ;AL用来计数数字个数

LP1: MOV DL,BYTE PTR[SI+2] ;如果输入数字,符号则继续读下一位,如果输入其他字符则AL加一,这也是开头第一个字母不能为其他字符的原因
CMP DL,'+'
JE MOV_PTR
CMP DL,'-'
JE MOV_PTR
CMP DL,'0'
JL MOV_INC ;JL小于0跳转到MOV_INC
CMP DL,'9'
JLE MOV_PTR
MOV_INC:INC AL ;加一
MOV_PTR:INC SI
LOOP LP1
INC AL
CBW ;将AL拓展到AX中
MOV DEC_NUM,AX ;将2进制形式的计数结果放入该单元
MOV CL,10
DIV CL ;除以10后,AL中放的是结果(十位数),AH中放的是余数(个位数)
ADD AX,3030H ;加3030H后将十位数和个位数分别转换成ASCII码

LEA DI,TOTAL
MOV BYTE PTR[DI],AL
MOV BYTE PTR[DI+1],AH
MOV BYTE PTR[DI+2],'$' ;将ASCII形式的计数结果放入单元以便输出,$符号为代码的结束

LEA DX,NOTE3 ;显示NOTE3,输出计数结果
MOV AH,9
INT 21H

LEA DX,TOTAL ;小小的处理使得第一位是0时自动缺省
CMP0: MOV BX,DX
CMP BYTE PTR [BX],'0'
JNE DISPLAY
INC DX
DISPLAY:MOV AH,9
INT 21H

;==================================ASCII to DECIMAL
LEA DX,[DEC_STR+2] ;从DX指向的单元读入
MOV CX,DEC_NUM
LEA BX,DEC_NUM ;写进BX指向的单元
ADD BX,2

T1: CALL ASC2DEC ;调用ASCII码转换
MOV [BX],AX ;将处理后的数放入储存单元
ADD BX,2
ADD DX,SI ;DX指向新位置
LOOP T1

;==================================Sort binary gigits
CALL COMP ;冒泡排序,算法很经典,就不过多标注了

;==================================NOTE4 ;输出结果提示
LEA DX,NOTE4
MOV AH,09H
INT 21H

;==================================DECIMAL TO ASCII ;将排序后的2进制数用ASCII码表示并打印出来
LEA BX,DEC_NUM
mov cx,DEC_NUM
ADD BX,2

D2A: MOV AX,[BX] ;读出二进制数放在AX中
CALL DEC2ASC ;调用转化和打印过程
MOV DL,' ' ;输出空格
MOV AH,2 ;在DOS系统功能调用(INT 21H)这个表里:ah放2,是2号功能,字符输出,并且要输出的字符是已经放在dl里面的
INT 21H

ADD BX,2 ;后移,空两个字节

LOOP D2A

LEA DX,CON_STR
MOV AH,09H
INT 21H
JMP CON_YN ;询问是否继续

OVER: MOV AH,4CH ;带返回码的结束,AL=返回码
INT 21H
MAIN ENDP

;-----------------------------------ASCII TO DECIMAL NUMBER ASCII码转十进制数
ASC2DEC PROC NEAR ;定义函数
PUSH BX ;入栈保护
PUSH CX
PUSH DX

MOV AX,0 ;AX初始为0,采用乘10相加的方式转换
MOV SI,DX
PUSH SI
MOV DL,[SI]
CMP DL,'-' ;如果读入的是负数则置CL为1最后处理
JNE L0
MOV CL,1
INC SI
MOV DL,[SI]
JMP L4
L0: CMP Dl,'+'
JNE L1
INC SI
MOV DL,[SI]

L1: MOV CL,0 ;正数置CL为0
L4: AND DL,0FH
MOV DH,0
ADD AX,DX
INC SI
MOV DL,[SI]
CMP DL,'0'
JL L2
CMP DL,'9'
JG L2
CALL TIMBY10 ;调用乘10进程
JMP L4
L2: CMP CL,1 ;如果是负数,对其求反
JNE L3
NEG AX
L3: POP DI ;DI出栈
SUB SI,DI ;SI减去初始位置,计算相对位移量
INC SI
POP DX
POP CX
POP BX
RET
ASC2DEC ENDP
;==================================AX TIME BY 10
TIMBY10 PROC NEAR
MOV BX,AX
SHL AX,1 ;乘2
SHL AX,1 ;再乘2
ADD AX,BX ;加一倍,现在相当于乘了5
SHL AX,1 ;乘2,总共是乘了10
RET
TIMBY10 ENDP

;==================================SORT DECIMAL NUMBERS 十进制数排序

COMP PROC NEAR ;保护
PUSH AX
PUSH BX
PUSH CX
PUSH DI

MOV AX,DATA
MOV DS,AX
LEA DI,DEC_NUM

MOV CX,WORD PTR[DI] ;计数
DEC CX

C1: MOV DX,CX
MOV BH,0
C2: ADD DI,2
MOV AX,[DI]
CMP AX,[DI+2]
JLE CONT1
XCHG AX,[DI+2]
MOV [DI],AX
MOV BH,1
CONT1: LOOP C2
CMP BH,0
JE STOP

MOV CX,DX

LEA DI,DEC_NUM
LOOP C1

STOP: LEA BX,DEC_NUM
MOV AX,[BX+8]
POP DI
POP CX
POP BX
POP AX
RET
COMP ENDP
;==================================DECIMAL NUMBER TO ASCII转换成ASCII码
DEC2ASC PROC
PUSH BX ;保护
PUSH CX

LEA DI,OUT_STR ;将处理后的放入DI
MOV DX,DI

CMP AX,0
JNE NON_0

ZERO: MOV BYTE PTR[DI],'0' ;如果是0
MOV BYTE PTR[DI+1],'$'
JMP OUT_ASC

NON_0: TEST AX,8000H ;不是0
JZ PTIVE ;判断符号,是正号跳转
NTIVE: NEG AX ;取反
MOV BYTE PTR[DI],'-' ;置负号
JMP CON

PTIVE: MOV BYTE PTR[DI],'+' ;置正号

CON: INC DI

MOV DX,0
MOV CX,10000 ;万位
IDIV CX ;带符号数除法
ADD AL,30H ;加30H变成ASCII
MOV BYTE PTR[DI],AL

MOV AX,DX
MOV DX,0
MOV CX,1000 ;千位
IDIV CX
ADD AL,30H ;加30H变成ASCII
MOV BYTE PTR[DI+1],AL ;写入

MOV AX,DX
MOV CL,100 ;百位
IDIV CL
ADD AL,30H
MOV BYTE PTR[DI+2],AL

MOV AL,AH
MOV AH,0
MOV CL,10 ;十位
IDIV CL
ADD AL,30H
MOV BYTE PTR[DI+3],AL

ADD AH,30H
MOV BYTE PTR[DI+4],AH ;个位

OUT_SIG:LEA DI,OUT_STR
MOV DL,BYTE PTR[DI]
MOV AH,2
INT 21H

INC DI
MOV DX,DI

B2: CMP BYTE PTR[DI],'0'
JNE OUT_ASC
INC DI
INC DX
JMP B2

OUT_ASC:MOV AH,09H ;打印
INT 21H

POP CX
POP BX
RET
DEC2ASC ENDP
;==================================

CODE ENDS
END START
...全文
5682 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
羽翼栗子球lv1 2017-04-02
  • 打赏
  • 举报
回复
求大佬回答一下 问什么我复制这些代码后,无法运行,显示START 是没有被定义的符号
赵4老师 2016-03-25
  • 打赏
  • 举报
回复
代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒:再牛×的老师也无法代替学生自己领悟和上厕所!
fornetuse123 2016-03-14
  • 打赏
  • 举报
回复
COMP PROC NEAR ;保护 PUSH AX PUSH BX PUSH CX PUSH DI MOV AX,DATA MOV DS,AX LEA DI,DEC_NUM MOV CX,WORD PTR[DI] ;计数 DEC CX C1: MOV DX,CX MOV BH,0 C2: ADD DI,2 MOV AX,[DI] CMP AX,[DI+2] JLE CONT1 XCHG AX,[DI+2] MOV [DI],AX MOV BH,1 CONT1: LOOP C2 CMP BH,0 JE STOP MOV CX,DX LEA DI,DEC_NUM LOOP C1 STOP: LEA BX,DEC_NUM MOV AX,[BX+8] POP DI POP CX POP BX POP AX RET COMP ENDP ;==================================DECIMAL NUMBER TO ASCII转换成ASCII码 DEC2ASC PROC PUSH BX ;保护 PUSH CX LEA DI,OUT_STR ;将处理后数字的ascii码存放在OUT_STR开始的内存 MOV DX,DI CMP AX,0 ;二进制数放在AX中,149行指令 JNE NON_0 ;不是0,跳转到NON_0 ZERO: MOV BYTE PTR[DI],'0' ;如果是0 MOV BYTE PTR[DI+1],'$';终止符 JMP OUT_ASC ;跳转到OUT_ASC NON_0: TEST AX,8000H ;不是0 JZ PTIVE ;判断符号,是正号跳转 NTIVE: NEG AX ;取反 MOV BYTE PTR[DI],'-' ;置负号 JMP CON PTIVE: MOV BYTE PTR[DI],'+' ;置正号 CON: INC DI ;以下将数字各位变成 ASCII MOV DX,0 MOV CX,10000 ;万位 IDIV CX ;带符号数除法 ADD AL,30H ;加30H变成ASCII MOV BYTE PTR[DI],AL MOV AX,DX MOV DX,0 MOV CX,1000 ;千位 IDIV CX ADD AL,30H ;加30H变成ASCII MOV BYTE PTR[DI+1],AL ;写入 MOV AX,DX MOV CL,100 ;百位 IDIV CL ADD AL,30H MOV BYTE PTR[DI+2],AL MOV AL,AH MOV AH,0 MOV CL,10 ;十位 IDIV CL ADD AL,30H MOV BYTE PTR[DI+3],AL ADD AH,30H MOV BYTE PTR[DI+4],AH ;个位 OUT_SIG:LEA DI,OUT_STR MOV DL,BYTE PTR[DI] MOV AH,2 INT 21H INC DI MOV DX,DI B2: CMP BYTE PTR[DI],'0' JNE OUT_ASC INC DI INC DX JMP B2 OUT_ASC:MOV AH,09H ;打印 INT 21H POP CX POP BX RET DEC2ASC ENDP ;================================== CODE ENDS END START
fornetuse123 2016-03-14
  • 打赏
  • 举报
回复
DATA SEGMENT NOTE0 DB 'Note: The character that separates the integers can be any visible ASCII except ten digits(',27H,'0',27H,'-',27H,'9',27H,').',0DH,0AH,'$' NOTE1 DB 0DH,0AH,'==================================================================',0DH,0AH ;0DH和0AH分别是回车和换行的ASCII码 DB 'Please input 20 (or less) decimal integers (-32768 to +32767):',0DH,0AH,'$' ;'$'是字符串的结束标志 NOTE2 DB 0DH,0AH,'==================================================================',0DH,0AH DB 0DH,0AH,'The inputed integers: ','$' NOTE3 DB 0DH,0AH,'==================================================================',0DH,0AH DB 0DH,0AH,'How many decimal integers? ','$' NOTE4 DB 0DH,0AH,'The sorted result: ',0DH,0AH,'$' ERR_STR DB 0DH,0AH,'******************************************************************',0DH,0AH DB 'Input error!',0DH,0AH CON_STR DB 0DH,0AH,'******************************************************************',0DH,0AH DB 0DH,0AH,'Continue? Y or N?','$' DEC_STR DB 200 ;用来存放输入的原始数据,第一个字节为200 DB 60 ; 第二个字节为60 DB 150 DUP('$') ;定义(?)意思是定义100个未经初始化的字节; db ?意思是定义一个未经初始化的字节 TOTAL DB 3 DUP('$') ;用来记录输入的数字个数 DEC_NUM DW 30 DUP(?) ;用来存放将输入的数字的ASCII码转换成2进制数以便进行排序 OUT_STR DB 150 DUP('$') ;存放排好顺序待输出的字符组信息 DATA ENDS STACK SEGMENT STACK STT DB 100 DUP(60) ;堆栈 STACK ENDS CODE SEGMENT MAIN PROC FAR ASSUME CS:CODE,DS:DATA,SS:STACK START: MOV AX,STACK MOV SS,AX ;初始化ss MOV AX,DATA ;初始化ds MOV DS,AX ;---------------------------------- 输出提示信息 LEA DX,NOTE0 ;直接显示NOTE0 MOV AH,09H ;显示 INT 21H ;调用dos DISP0: LEA DX,NOTE1 ;直接显示NOTE1 Please input 20 个数字 MOV AH,09H INT 21H LEA DX,DEC_STR ;将DEC_STR首地址给DX MOV AH,0AH ;将输入的数字输入缓冲区,DS:DX=缓冲区首地址,(DS:DX)=缓冲区最大字符数,(DS:DX+1)=实际输入的字符数 INT 21H ;下面的[DEC_STR+2]=(DS:DX+1)=实际输入的第一个数字 MOV AL,BYTE PTR[DEC_STR+2] ;判断第一个输入数据是否为数字?;将DEC_STR的偏移地址+2指向的第一个字节赋值给AL CMP AL,'0' ;条件判转指令 JAE CMP1 ;A为大于,B为小于,E为等于,如是数字跳转到CMP1 CMP AL,'+' ;检验AL寄存器内的值是不是ascii字符+(正号) JE DISP2 ;如果是跳转到DISP2 CMP AL,'-' ;检验AL寄存器内的值是不是ascii字符-(负号) JE DISP2 ;如果是跳转到DISP2 JMP DISP1 ;如果第一个输入数据不是数字或者正负号,JMP 无条件跳转DISP1,显示输入错误信息 CMP1: CMP AL,'9' JBE DISP2 ; 如果第一个输入数据是0-9之间的数字,跳转到DISP2 DISP1: LEA DX,ERR_STR MOV AH,09H ;输入错误信息显示 INT 21H CON_YN: MOV AH,01H ;程序运行结束后,询问是否继续,读取键盘输入并回显,al=输入字符 INT 21H CMP AL,'Y' ;检验AL寄存器内的值是不是Y JE DISP0 ;是Y跳转到DISP0 ,重新开始运行程序 CMP AL,'y' JE DISP0 CMP AL,'N' JE OVER0 CMP AL,'n' JE OVER0 ;是N跳转到OVER0,结束程序 OVER0: JMP OVER ;用以结束程序 DISP2: LEA DX,NOTE2 ;将输入的数据输出以便用户对照其正确性 MOV AH,09H ;显示NOTE2 INT 21H LEA DX,[DEC_STR+2];将输入数字的第一个字节地址给DX MOV AH,09H ;显示所有输入数字直到读到终止符号 $ INT 21H ;===============================COUNT HOW MANY DECIMAL INTEGERS 计算个数 LEA SI,DEC_STR ;将输入数字缓冲区的首地址给si MOV CL,BYTE PTR[SI+1] ;将输入的数字总个数给cl MOV CH,0 PUSH CX ;输入的数字总个数压栈 MOV AL,0 ;AL用来计数非数字数据,即分隔符个数 LP1: MOV DL,BYTE PTR[SI+2] ;将输入的第一个数据给dl CMP DL,'+' ;以下判断是否为正负号 JE MOV_PTR CMP DL,'-' JE MOV_PTR ;是的话跳转MOV_PTR CMP DL,'0' JL MOV_INC ;JL小于0,即读取的数据是否为输入数字时输入的分隔符,这条指令在第一次执行时并不执行,因为第一个输入的是数字和正负号 CMP DL,'9' JLE MOV_PTR ;是数字0-9跳转到MOV_PTR MOV_INC:INC AL ;每有一个分隔符,就相当于有一个数字,加一 MOV_PTR:INC SI;读取下一个字节 LOOP LP1;将所有字节读入求和输入数字个数 INC AL;这里将总个数加1是因为实际数字个数比分割符多1,因为最后一个数字输入后输入了回车 CBW ;将AL拓展到AX中 MOV DEC_NUM,AX ;将输入数字总个数给DEC_NUM MOV CL,10 DIV CL ;除以10后,AL中放的是结果(十位数),AH中放的是余数(个位数) ADD AX,3030H ;加3030H后将十位数和个位数分别转换成ASCII码 LEA DI,TOTAL ;将total地址给di MOV BYTE PTR[DI],AL;将分隔符总个数的ASCII形式的计数结果给连续的两个字节 MOV BYTE PTR[DI+1],AH MOV BYTE PTR[DI+2],'$' ;$符号为结束标志 LEA DX,NOTE3 ;显示NOTE3,输出计数结果 MOV AH,9 INT 21H LEA DX,TOTAL ;将数字总个数存储地址给dx CMP0: MOV BX,DX CMP BYTE PTR [BX],'0';数字总个数的十位数是否为0 JNE DISPLAY;不是0跳转到DISPLAY INC DX;是0将dx地址指针加1,即指向数字总个数的个位数 DISPLAY:MOV AH,9 INT 21H;输出总个数结果 ;==================================ASCII to DECIMAL LEA DX,[DEC_STR+2] ;将输入的第一个数字地址给dx MOV CX,DEC_NUM ;将输入数字总个数给cx LEA BX,DEC_NUM ;将存储数字总个数的DEC_NUM地址给bx ADD BX,2 ;首地址+2,即跳过存储数字总个数的两个字节 T1: CALL ASC2DEC ;调用ASCII码转换十进制 MOV [BX],AX ;将处理后的数存放在DEC_NUM中首地址+2开始的内存 ADD BX,2;将存储内存指针加一个字 ADD DX,SI ;DX指向下一个输入字符 LOOP T1;将所有处理后的输入字符存入DEC_NUM ;==================================Sort binary gigits CALL COMP ;冒泡排序,算法很经典,就不过多标注了 ;==================================NOTE4 ;输出结果提示 LEA DX,NOTE4 MOV AH,09H INT 21H ;==================================DECIMAL TO ASCII ;将排序后的2进制数用ASCII码表示并打印出来 LEA BX,DEC_NUM ;将DEC_NUM首地址给bx mov cx,DEC_NUM ;将DEC_NUM首地址内容(输入数字总个数)给cx,102行指令 ADD BX,2 ;指向DEC_NUM中下一个字内存地址 ,即经过转换后的数字 D2A: MOV AX,[BX] ;读出二进制数放在AX中 CALL DEC2ASC ;调用十进制转ascii码程序 MOV DL,' ' ;输出空格 MOV AH,2 ;在DOS系统功能调用(INT 21H)这个表里:ah放2,是2号功能,字符输出,并且要输出的字符是已经放在dl里面的 INT 21H ADD BX,2 ;后移,空两个字节 LOOP D2A LEA DX,CON_STR MOV AH,09H INT 21H JMP CON_YN ;询问是否继续 OVER: MOV AH,4CH ;带返回码的结束,AL=返回码 INT 21H MAIN ENDP ;-----------------------------------ASCII TO DECIMAL NUMBER ASCII码转十进制数 ASC2DEC PROC NEAR ;定义函数 PUSH BX ;入栈保护 PUSH CX PUSH DX MOV AX,0 ;AX初始为0,采用乘10相加的方式转换 MOV SI,DX ;将[DEC_STR+2] 中输入的第一个数字地址给si,125行指令 PUSH SI MOV DL,[SI] ;将输入的第一个数字给dl CMP DL,'-' ;如果读入的是负数则置CL为1最后处理 JNE L0 ;如果是0或者正数跳转到l0 MOV CL,1 ;负数将CL置1 INC SI ;读取下一个输入字符 MOV DL,[SI] JMP L4 ;跳转到L4 L0: CMP Dl,'+' ; 比较是数字还是正号 JNE L1 ;数字跳转到L1 INC SI ;正号读取下一个输入字符 MOV DL,[SI] L1: MOV CL,0 ;正数置CL为0 L4: AND DL,0FH ;对数字进行逻辑与运算,判断是正数还是负数 MOV DH,0 ADD AX,DX INC SI ;读取下一个输入字符 MOV DL,[SI] CMP DL,'0';如果是分隔符 JL L2 ;跳转到L2 CMP DL,'9';如果是分隔符 JG L2 ;跳转到L2 CALL TIMBY10 ;调用乘10进程,将当前数字的各个位数乘10,即每次循环时都将现有ax中数字扩大十倍, JMP L4 ;跳转到L4,循环执行将所有每一个字节中的输入数字各位数读入AX L2: CMP CL,1 ;如果是负数,对其求反 JNE L3 ;正是跳转到L3 NEG AX L3: POP DI ;DI出栈,将total首地址给di ,107行指令 SUB SI,DI ;SI减去初始位置,计算相对位移量 INC SI POP DX ;将输入的第一个数字地址给dx,170行指令参考125行指令 POP CX ;将输入数字总个数给cx,170行指令参考126行指令 POP BX ;首地址+2,即跳过存储数字总个数的两个字节,170行指令参考128行指令 RET ASC2DEC ENDP ;==================================AX TIME BY 10 TIMBY10 PROC NEAR MOV BX,AX SHL AX,1 ;乘2 SHL AX,1 ;再乘2 ADD AX,BX ;加一倍,现在相当于乘了5 SHL AX,1 ;乘2,总共是乘了10 RET TIMBY10 ENDP ;==================================SORT DECIMAL NUMBERS 十进制数排序
做而论道_CS 2016-02-02
  • 打赏
  • 举报
回复
注释已经够多了。
一、问题描述 课题1:排序。要键盘输入若干个人名,当输入完毕后,能显示正确的顺序。 课题2:编写一个类似于TT的英文打字测试程序。要输入的字符能在屏幕显示并报告所用时间。 二、设计思想 课题1:排序程序分3个部分 (1) 等待用户输入个人名,即输入字符串。本程序设定输入人名为5到15个,运用了2个函(input1,input2)实现。 定义 data1 db 21,0,22 dup('$') ;用于存放第一个字符串 data2 db 21,0,22 dup('$') ;用于存放第二个字符串 data3 db 21,0,22 dup('$') ;用于存放第三个字符串 data4 db 21,0,22 dup('$') ;用于存放第四个字符串 data5 db 21,0,22 dup('$') ;用于存放第五个字符串 data6 db 21,0,22 dup('$') ;用于存放第六个字符串 data7 db 21,0,22 dup('$') ;用于存放第七个字符串 data8 db 21,0,22 dup('$') ;用于存放第八个字符串 data9 db 21,0,22 dup('$') ;用于存放第九个字符串 dataa db 21,0,22 dup('$') ;用于存放第十个字符串 datab db 21,0,22 dup('$') ;用于存放第十一个字符串 datac db 21,0,22 dup('$') ;用于存放第十二个字符串 datad db 21,0,22 dup('$') ;用于存放第十三个字符串 datae db 21,0,22 dup('$') ;用于存放第十四个字符串 dataf db 21,0,22 dup('$') ;用于存放第十五个字符串 input1实现前五个字符串的输入,调用0A号功能实现输入,当用户没有输入字符而直接回车时,程序会判断为输入错误,直到输入字符为止,此时按下回车,会转到下个字符串的输入。 input2实现后10个字符串的输入,调用0a号功能实现输入,当用户没有输入字符而直接回车时,程序会判断用户选择结束输入,跳转出input2函。实现了用户连续按两下回车(注意:第一个回车为前一个字符串的结束回车,此后再按一次回车就表示退出),直接退出输入的功能。 (2)人名排序,即字符串排序。 采用冒泡排序的方法,进行双重循环,内循环实现字符串的比较交换,若前一 个字符串大则跳转去交换,小或者相等则跳转去比较下两个字符串。 外循环是在内部循环结束后继续从第一个字符串开始跳转到内部循环,保证顺序排好。 另外字符串本身的比较也是一重循环,以字符串结尾符号'$'控制比较次。 交换部分则是两个存储单元的完全交换(从第一个字符到最后一个字符)。 (3)输出排序好的人名 最后将排序好的字符串依次输出在屏幕上。 三、课程设计体会 在此次课程设计中,我与吕鑫等人一组,我们综合利用了80X86汇编语言程序设计这门课中所学的所有知识,实践操作了多种指令的功能,丰富了用汇编语言编程的经验。也从中体会到了用汇编编程的难处。 在以小组为单位的课程设计制作过程中,我与其他组员相互讨论、配合,最后共同完成了2个课题要程序编写,极大提升了我团队共同合作的编程经验,受益匪浅。也提高了我分析问题、解决问题的能力。 课题2:TT英文打字测试程序程序有3功能 (1)在屏幕上输出一条字符串; 在程序中定义几段字符串 STR1 DB 'ABCD EFGH IJKL MNOP QRST UVWX YZ.' STR2 DB 'THERE ARE SOME NEWSPAPERS ON THE TABLE.' STR3 DB 'THERE ARE SOME CLOUDS IN THE SKY.' STR4 DB 'SHE ALWAYS EATS HER LUNCH AT NOON.' STR5 DB 'I DO NOT LIKE AUTUMN AND WINTER.' 运行时,在屏幕上依次输出这几段字符串,每输出一段字符串,便开始等待用户从键盘输入字符。 (2)从键盘上读入字符,并显示屏幕上,以回车键结束输入; 首先用 INT 21H 从键盘读入一个字符,将读入的字符放入AL中,判断该字符是否是回车,若不是回车则马上用INT 10H 在当前光标位置上显示AL中的字符,若是回车则结束从键盘上读入字符。 (3)对从键盘上读入字符的过程计时,并在输入结束后,将输入用时显示屏幕上。 定义 SEC DW 0 ;sec表示秒钟 MIN DW 0 ;min表示分钟 HOURS DW 0 ;hours表示小时 将它们初始化为0。 输入字符结束后,依次将hours、min、mours赋值给ax,并输出在屏幕上,以分号隔开。
第1章 基本知识 1-1 汇编语言介绍 1-1-1 程序设计语言分类 1-1-2 汇编语言程序设计的意义 1-2 位及字节 1-3 二进制 1-3-1 字系统 1-3-2 补码 1-3-3 BCD码 1-4 十六进制表示法 1-5 ASCII码 1-6 个人计算机组成 1-6-1 处理器 1-6-2 内部存储器 1-6-3 段与地址 1-6-4 寄存器 1-7 硬件中断 课后习题 第2章 程序加载并执行 2-1 操作系统的组成 2-2 BIOS启动程序 2-3 系统加载程序 2-4 堆栈 课后习题 第3章 NASM汇编语言基础 3-1 源程序行格式 3-2 伪指令 3-2-1 定义含有初值的据 3-2-2 定义不含初值的据 3-2-3 INCBIN伪指令 3-2-4 EQU伪指令 3-2-5 TIMES伪指令 3-3 有效地址 3-4 常量 3-4-1 字常量 3-4-2 字符常量 3-4-3 字符串常量 3-4-4 浮点常量 3-5 表达式 3-5-1 OR运算符 3-5-2 XOR运算符 3-5-3 AND运算符 3-5-4 移位运算符 3-5-5 加及减运算符 3-5-6 乘及除运算符 3-5-7 单元运算符 3-6 临界表达式 3-7 局部标号 3-8 预处理器 3-8-1 %define指令 3-8-2 %undef指令 3-8-3 %assign指令 3-8-4 多行宏 3-8-5 条件汇编 3-8-6 预处理循环 3-8-7 文件引用指引 3-8-8 标准宏 3-8-9 汇编语言指引 3-9 目标文件格式 3-10 NASM汇编程序安装 3-11 范例 课后习题 第4章 一般指令 4-1 源操作与目的操作 4-2 MOV传送指令 4-3 XCHG互换指令 4-4 有效地址送寄存器指令LEA 4-5 指针送寄存器指令LDS及LES指令 4-6 压入PUSH及弹出POP指令 4-7 存储寄存器PUSHA及POPA指令 4-8 标志寄存器传送PUSHF及POPF指令 4-9 没有运算的NOP指令 课后习题 第5章 基本输入与输出 5-1 软件中断INT指令 5-2 将一个字符串输出到屏幕 5-3 从键盘输入一个字符 5-4 将一个字符输出到屏幕 5-5 从键盘输入一个字符串 5-6 将一个字输出到屏幕 5-7 显示内存内容 5-8 键盘输入控制 5-8-1 由键盘输入字符 5-8-2 直接由键盘输入或输出字符 5-8-3 直接由键盘输入字符 5-8-4 直接由键盘输入字符 5-8-5 由键盘输入字符串 5-8-6 检查键盘缓冲区 5-8-7 清除键盘缓冲区 5-8-8 从键盘缓冲区读取字符 5-8-9 测试键盘缓冲区是否有字符 5-8-10 传回控制键状态 5-9 屏幕输出控制 5-9-1 显示字符 5-9-2 显示字符串 5-9-3 设定光标位置 5-9-4 向上滚动屏幕 5-10 打印机输出控制 5-10-1 输出字符至打印机 5-10-2 打印一个字符 5-10-3 取得打印机状态 课后习题 第6章 程序流程控制 6-1 标志寄存器 6-2 改变标志的指令 6-3 条件转移指令 6-4 比较两个整 6-5 无条件转移指令JMP 6-6 循环指令LOOP 6-7 选择结构 6-8 循环结构 课后习题 第7章 算术运算 7-1 定点与浮点 7-2 带符号及无符号 7-3 加法及减法 7-4 乘法 7-5 除法 7-6 BCD十进制运算 7-6-1 BCD加法 7-6-2 BCD减法 7-6-3 BCD乘法 7-6-4 BCD除法 7-6-5 BCD宏应用 7-7 综合例题 课后习题 第8章 宏 8-1 单行宏 8-1-1 %define指令 8-1-2 %undef指令 8-1-3 %assign指令 8-2 多行宏 8-2-1 显示字符串宏 8-2-2 显示字符宏 8-2-3 读取字符宏 8-2-4 显示字节宏 8-2-5 读取字符串宏 8-2-6 字符串转换为值 8-2-7 值转换为字符串 8-2-8 值输出至屏幕 8-3 条件汇编 8-4 预处理循环 8-5 源程序文件的包含内容 8-6 相关宏汇总 课后习题 第9章 过程 9-1 过程的定义 9-2 过程里的局部变量 9-3 传值调用 9-4 传址调用 9-5 堆栈传递参 9-6 内存传递参 课后习题 第10章 字符串处理 10-1 声明字符串 10-2 字符串长度 10-3 基本字符串指令 10-4 转换指令XLATB 10-5 字符串宏 课后习题 第11章 位运算 11-1 位基本运算 11-2 位屏蔽 11-3 AND指令 11-4 OR指令 11-5 XOR指令 11-6 NOT指令 11-7 TEST指令 11-8 改变位位置 11-9 左移及右移 11-10 算术左移及算术右移 11-11 循环位移 11-12 位移及循环位移指令总结 11-13 综合例题 课后习题 第12章 文件处理 12-1 输入及输出层次 12-2 输入及输出概念 12-3 标准的文件代号 12-4 建立一个文件代号 12-5 打开一个文件 12-6 关闭一个文件 12-7 从文件或设备读取据 12-8 据写入文件或设备 12-9 移动文件指针 12-10 检查并修改文件属性 12-11 建立新文件 12-12 删除文件 12-13 文件改名 12-14 建立或删除子目录 12-15 取得当前目录 12-16 改变当前目录 12-17 取得缺省的磁盘驱动器 12-18 改变缺省的磁盘驱动器 12-19 低级输入及输出 课后习题 第13章 据结构 13-1 组声明 13-2 组查找 13-3 使用XLATB指令转换 13-4 排序 13-5 队列 13-6 堆栈 13-7 链表 课后习题 第14章 浮点运算 14-1 80x87协处理器的运算 14-2 浮点堆栈 14-3 状态字 14-4 控制字 14-5 据类型 14-5-1 二进制整 14-5-2 聚集十进制 14-5-3 实 14-5-4 七种据类型值的范围 14-6 80x87指令集 14-7 范例 课后习题 第15章 连接程序 15-1 建立NASM源程序 15-2 将目标文件连接成.exe文件 15-3 显示DOS的BIOS区域据 15-4 系统设备据 15-5 内存容量 课后习题 附录 NASM汇编语言指令

21,459

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧