S0 SEGMENT STACK DW 20 DUP(?) TOP LABEL WORD S0 ENDS S1 SEGMENT TIP DB "Please enter ten numbers separated by spaces:", 0DH, 0AH, 24H ARY DW 20 DUP(0) CRLF DB 0DH, 0AH, 24H N DW 0 S1 ENDS S2 SEGMENT ASSUME SS:S0, DS:S1, CS:S2, ES:S1 P PROC FAR MOV AX, S0 MOV SS, AX LEA SP, TOP MOV AX, S1 MOV DS, AX MOV AX, S1 MOV ES, AX LEA DX, TIP MOV AH, 9 INT 21H LEA SI, ARY XOR DX, DX MOV BL, 10 MOV CX, 10 INPUT: MOV AH, 1 INT 21H CMP AL, 20H ;空格分隔字符 JE SAVE;输入十进制数,将数存入SI对应的内存单元 MOV DL, AL MOV AX, [SI] MUL BL SUB DL, 30H ADD AL, DL MOV [SI], AX JMP INPUT SAVE: ADD SI, 2 LOOP INPUT;数组保存完毕 LEA SI, ARY MOV DI, SI ADD DI, 2 ;DI位于数组的第二元素的位置 MOV BP, 9 ;SI移动的次数和每一次比较的次数,第一次为9 GO: MOV CX, BP ;每一次比较的循环次数 MOV BX, [SI] ;第一个数 CMPA: CMP BX, [DI] ;比较后面的数是否比当前的小 JBE CON ;大于就比较下一个 MOV BX, [DI] ;将寄存器中的值替换为最小的值 MOV AX, DI ;AX存放最小值的偏移地址 CON: ADD DI, 2 LOOP CMPA CMP AX, 0 ;如果AX为0,则表示后面的值没有比当前值小 JE NO ;此时SI加一,移动到第二个数 下一次循环比较开始 CHANGE: MOV DX, [SI] ;78-83行替换当前值与最小值 PUSH DX MOV [SI], BX POP DX MOV DI, AX MOV [DI], DX NO: ADD SI, 2 MOV DI, SI ADD DI, 2 CALL PRINT DEC BP ;循环的次数减一 XOR AX, AX ;清除AX的内容,以便76行判断 CMP BP, 1 JNE GO EXIT: MOV AH, 4CH INT 21H P ENDP PRINT PROC NEAR PUSH SI PUSH CX PUSH AX PUSH DX LEA DX, CRLF MOV AH, 9 INT 21H LEA SI, ARY MOV CX, 10 L1: MOV AX, [SI] MOV N, AX CALL OUTPUT ADD SI, 2 MOV DX, 20H MOV AH, 2 INT 21H LOOP L1 POP DX POP AX POP CX POP SI RET PRINT ENDP OUTPUT PROC NEAR PUSH AX PUSH BX PUSH CX PUSH DX XOR CX, CX MOV AX, N MOV BX, 10 L2: XOR DX, DX DIV BX PUSH DX INC CX CMP AX, 0 JNE L2 L3: POP DX ADD DX, 30H MOV AH, 2 INT 21H LOOP L3 POP DX POP CX POP BX POP AX RET OUTPUT ENDP S2 ENDS END P一共123行每行都是干什么的
时间: 2023-06-20 11:10:12 浏览: 201
这是一段汇编语言代码,用于对输入的十个数字进行排序并输出。下面是每行的功能:
- 第1-5行:定义堆栈区域S0,用于存储程序的堆栈信息;定义数据区域S1,用于存储程序的变量和常量;定义代码区域S2,用于存储程序的指令。
- 第6行:将SS寄存器(堆栈段)设置为S0区域的起始地址。
- 第7行:将SP寄存器(堆栈指针)设置为堆栈区域的顶部(TOP)。
- 第8-10行:将DS寄存器(数据段)和ES寄存器(附加数据段)设置为S1区域的起始地址。
- 第11-15行:显示提示信息。
- 第16-18行:定义一个数组ARY,用于存储输入的十个数字;定义一个计数器N,用于记录已经输入的数字个数。
- 第19行:定义一个换行符CRLF。
- 第20行:定义一个变量BP,用于记录每次循环需要比较的次数。
- 第21-22行:定义程序入口点P。
- 第23-24行:将AX寄存器设置为堆栈段的起始地址,并将SS寄存器设置为AX的值,相当于将堆栈段的起始地址赋给SS寄存器。
- 第25行:将堆栈指针设置为堆栈顶部。
- 第26-27行:将DS和ES寄存器设置为S1区域的起始地址。
- 第28-32行:显示提示信息。
- 第33行:将SI寄存器(源变址寄存器)设置为数组ARY的起始地址。
- 第34-35行:将DX寄存器清零。
- 第36行:将BL寄存器设置为10,用于将输入的字符转换为十进制数。
- 第37-38行:将CX寄存器设置为10,用于记录还需要输入多少个数字。
- 第39-41行:输入一个字符并将其保存在AL寄存器中。
- 第42-43行:如果输入的是空格分隔字符,则跳转到SAVE标签保存输入的数字。
- 第44-49行:将输入的字符转换为十进制数,并将其存储在SI对应的内存单元中。
- 第50行:跳转到INPUT标签继续输入下一个字符。
- 第51-52行:将SI寄存器加2,指向下一个空闲的内存单元,并将CX计数器减1。
- 第53行:如果CX计数器不为零,则跳转到INPUT标签继续输入下一个数字。
- 第54-55行:将SI寄存器设置为数组ARY的起始地址。
- 第56-57行:将DI寄存器(目的变址寄存器)设置为数组ARY的第二个元素的位置。
- 第58行:将BP寄存器设置为9,表示需要进行9轮排序。
- 第59行:跳转到GO标签开始排序。
- 第60行:将CX寄存器设置为BP,即每轮需要比较的次数。
- 第61行:将BX寄存器设置为当前需要比较的数字,即SI指向的数字。
- 第62-63行:比较DI指向的数字是否小于BX,如果是,则跳转到CON标签。
- 第64-65行:将DI指向的数字赋值给BX寄存器,作为当前最小的数字。
- 第66-67行:将AX寄存器设置为DI的值,即当前最小数字的偏移量。
- 第68行:跳转到CON标签。
- 第69行:将DI寄存器加2,指向下一个数字。
- 第70行:将CX计数器减1。
- 第71行:如果CX计数器不为零,则跳转到CMPA标签继续比较下一个数字。
- 第72-73行:如果AX寄存器为零,则表示后面的数字都不比当前数字小,跳转到NO标签。
- 第74行:将SI寄存器加2,指向下一个数字。
- 第75行:将DI寄存器重新设置为数组ARY的第二个元素的位置。
- 第76行:调用PRINT子过程输出当前排完序的数组。
- 第77行:将BP计数器减1。
- 第78行:如果BP计数器不为1,则跳转到GO标签继续排序下一轮。
- 第79-81行:将AH寄存器设置为4CH,即程序结束的系统调用。
- 第82行:调用INT 21H中断,结束程序。
- 第83行:定义PRINT子过程,用于输出数组中的数字。
- 第84-85行:将SI寄存器设置为数组ARY的起始地址。
- 第86-87行:将CX寄存器设置为10,即数组中有10个数字需要输出。
- 第88-89行:循环输出数组中的每个数字。
- 第90-93行:将当前数字存储在N变量中,并调用OUTPUT子过程输出它。
- 第94-97行:将SI寄存器加2,指向下一个数字,并输出一个空格。
- 第98-99行:如果CX计数器不为零,则跳转到L1标签继续输出下一个数字。
- 第100-104行:恢复寄存器的值,并返回到调用它的位置。
- 第105行:定义OUTPUT子过程,用于将十进制数转换为字符串并输出。
- 第106-109行:保存现场。
- 第110-111行:将CX计数器清零。
- 第112-113行:将AX寄存器设置为要转换的数字。
- 第114-115行:将BX寄存器设置为10,用于取余和除法运算。
- 第116-117行:循环取余并将其压入堆栈中,同时将CX计数器加1。
- 第118-119行:如果AX寄存器不为零,则跳转到L3标签继续取余。
- 第120-121行:循环从堆栈中取出数字并输出。
- 第122-123行:恢复现场并返回到调用它的位置。
- 第124行:结束程序。
阅读全文