cpp
复制代码
; ===================================================
; 程序名称:数组操作演示(求和 & 求最大值)
; 运行环境:emu8086
; 修正:使用 AX 累加,避免溢出
; ===================================================
org 100h ; COM 文件的起始地址
; 数据段
.data
; 定义一个字节数组
my_array DB 15, 42, 7, 89, 23, 56, 34, 71
array_len EQU 8 ; 数组长度
sum_msg DB 'Sum: $'
max_msg DB 13,10,'Max: $' ; 13,10 是回车换行
.code
start:
; 初始化段寄存器(emu8086 需要)
mov ax, @data
mov ds, ax
; ========== 示例1:求数组元素之和(修正版)==========
xor ax, ax ; AX = 0(存放累加结果)
xor bx, bx ; BX = 0(存放临时变量)
mov cx, array_len ; CX = 数组长度(循环计数器)
mov si, 0 ; SI = 索引(从0开始)
sum_loop:
mov bl, [my_array + si] ; 将当前字节元素加载到 BL
add ax, bx ; 加到 AX(16位累加)
inc si ; 索引+1
loop sum_loop ; CX--, 若CX>0则继续
; 此时 AX 中存放的是正确的和 = 337
push ax ; 保存累加结果
; 显示 "Sum: "
mov dx, offset sum_msg
mov ah, 9
int 21h
pop ax ; 恢复累加结果
call print_num ; 调用数字打印子程序
; ========== 示例2:求数组中的最大值 ==========
mov cx, array_len
mov si, 0
mov al, [my_array + si] ; 先假设第一个元素最大
inc si ; 从第二个元素开始比较
max_loop:
cmp al, [my_array + si] ; 当前最大值 vs 当前元素
jge skip_update ; 如果 al >= 当前元素,跳过更新
mov al, [my_array + si] ; 否则更新最大值
skip_update:
inc si
loop max_loop
; 此时 AL 中存放最大值 = 89
push ax ; 保存最大值
; 显示 "Max: "
mov dx, offset max_msg
mov ah, 9
int 21h
pop ax ; 恢复最大值
xor ah, ah ; 确保 AH=0
call print_num ; 显示最大值
; 等待按键退出
mov ah, 0
int 16h
; 退出程序
mov ax, 4c00h
int 21h
; ===================================================
; 子程序:打印 AX 中的无符号整数(0-65535)
; 输入:AX = 要打印的数值
; 输出:在屏幕上显示十进制数字
; ===================================================
print_num proc
push ax
push bx
push cx
push dx
push si
; 处理特殊情况:数字为0
or ax, ax
jnz not_zero
mov dl, '0'
mov ah, 2
int 21h
jmp print_done
not_zero:
; 逐位提取数字并压栈
mov cx, 0 ; 数字位数计数器
mov bx, 10 ; 除数为10
divide_loop:
xor dx, dx ; 清零 DX(放余数)
div bx ; AX / 10,商在 AX,余数在 DX
push dx ; 余数(0-9)压栈保存
inc cx ; 位数+1
or ax, ax ; 商是否为0?
jnz divide_loop ; 不为0则继续
; 弹出并显示所有数字
print_stack:
pop dx
add dl, '0' ; 转换为 ASCII 字符
mov ah, 2
int 21h
loop print_stack
print_done:
pop si
pop dx
pop cx
pop bx
pop ax
ret
print_num endp
end start