使用8086汇编语言已知在 DATA 开始的字单元中存放有 10 个无符号整数,试编制程序挑选出其 中的最大值和最小值并显示。
时间: 2024-04-30 22:23:51 浏览: 193
下面是一种可能的解决方案:
```
; 定义数据段
DATA SEGMENT
NUMS DB 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 ; 10 个无符号整数
DATA ENDS
; 定义代码段
CODE SEGMENT
ASSUME CS:CODE, DS:DATA
START:
MOV AX, DATA ; 初始化数据段寄存器
MOV DS, AX
; 找最大值
MOV AL, NUMS ; 初始化最大值为第一个数
MOV BH, 1 ; 初始化循环计数器
MOV BL, 10 ; 初始化循环次数
FIND_MAX:
CMP AL, [NUMS + BH] ; 比较当前最大值和下一个数
JNC SKIP_MAX ; 如果当前最大值大于等于下一个数,跳过
MOV AL, [NUMS + BH] ; 否则更新最大值
SKIP_MAX:
INC BH ; 增加计数器
LOOP FIND_MAX ; 循环找最大值
; 找最小值
MOV AL, NUMS ; 初始化最小值为第一个数
MOV BH, 1 ; 初始化循环计数器
MOV BL, 10 ; 初始化循环次数
FIND_MIN:
CMP AL, [NUMS + BH] ; 比较当前最小值和下一个数
JBE SKIP_MIN ; 如果当前最小值小于等于下一个数,跳过
MOV AL, [NUMS + BH] ; 否则更新最小值
SKIP_MIN:
INC BH ; 增加计数器
LOOP FIND_MIN ; 循环找最小值
; 显示结果
MOV AH, 9 ; 选择 DOS 打印字符串功能
LEA DX, [MSG_MAX] ; 加载最大值字符串
INT 21H ; 打印最大值字符串
CALL PRINT_NUM ; 打印最大值
MOV AH, 9 ; 选择 DOS 打印字符串功能
LEA DX, [MSG_MIN] ; 加载最小值字符串
INT 21H ; 打印最小值字符串
CALL PRINT_NUM ; 打印最小值
MOV AH, 4CH ; 选择 DOS 程序结束功能
INT 21H ; 结束程序
; 子程序:打印一个无符号整数
PRINT_NUM PROC NEAR
PUSH AX ; 保存寄存器内容
PUSH BX
PUSH CX
PUSH DX
MOV BX, 10 ; 初始化除数
XOR CX, CX ; 初始化位数计数器
DIV_LOOP:
XOR DX, DX ; 清空余数
DIV BX ; 除以 10
PUSH DX ; 保存余数
INC CX ; 增加位数计数器
TEST AX, AX ; 检查商是否为 0
JNZ DIV_LOOP ; 如果不是,继续循环
; 反向输出数字
MOV AH, 2 ; 选择 DOS 打印字符功能
PRINT_LOOP:
POP DX ; 弹出一个余数
ADD DL, '0' ; 转换为 ASCII 码
INT 21H ; 打印字符
LOOP PRINT_LOOP ; 继续循环,直到所有位数都输出
; 恢复寄存器内容
POP DX
POP CX
POP BX
POP AX
RET
PRINT_NUM ENDP
; 定义字符串常量
MSG_MAX DB 'Max: ', 0
MSG_MIN DB 'Min: ', 0
CODE ENDS
END START
```
这个程序首先将数据段寄存器指向 DATA 段,然后使用两个循环分别找到最大值和最小值。在找最大值和最小值的循环中,我们使用了循环计数器 BH 和循环次数 BL 来遍历 NUMS 数组中的所有元素。我们使用 CMP 指令比较当前最大值或最小值和下一个数,并使用 JNC 和 JBE 指令跳过比较,如果当前最大值或最小值小于下一个数,就更新最大值或最小值。在找到最大值和最小值后,我们使用 PRINT_NUM 子程序打印它们。
PRINT_NUM 子程序将一个无符号整数转换为字符串并打印出来。它使用了 DIV 指令来除以 10,然后使用 PUSH 指令将余数压入栈中,最后使用 POP 指令将余数弹出栈并转换为 ASCII 码打印出来。为了反向输出数字,我们将余数保存在栈中,然后再从栈中弹出它们打印出来。
阅读全文