在 emu8086 中可以直接编译运行的完整汇编程序,演示数组的定义、遍历、求和、求最大值。

1.程序

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

2.运行结果

相关推荐
Hyyy35 分钟前
理解LLM的基本工作原理:预训练、微调、推理的区别
前端
Gatlin1 小时前
前端逆向与反逆向:一场猫鼠游戏的底层逻辑与实战
前端
代码煮茶1 小时前
React 组件封装方法论 —— 以 Todo App 为例
javascript·react.js
Pedantic1 小时前
本地通知(Local Notifications)学习笔记
前端
任沫1 小时前
Agent之Function Call
javascript·人工智能·go
森蓝情丶2 小时前
我给 AI 搭了个法庭:一个前端仔的 LangGraph 实战全记录
前端·后端
爱勇宝2 小时前
干了近 8 年,一夜之间被裁:AI 时代,程序员最该害怕的不是 AI
前端·后端·程序员
Pedantic2 小时前
Combine 框架学习笔记
前端
runnerdancer2 小时前
Agent如何加载执行Skill的脚本
前端·agent
yingyima3 小时前
VS Code 正则替换技巧:从凌晨3点的服务器报警开始
前端