汇编程序计算(a+b-c)!时fact变量未正确写入内存求助
汇编程序阶乘计算后fact变量赋值失败的问题解决
核心问题分析
你的程序中fact变量始终为0000,主要存在两个关键错误:
1. 错误修改DS寄存器,导致访问错误内存段
计算完rez后,你执行了以下代码:
MOV AX, rez MOV DS, AX
这会把数据段寄存器DS设置为rez的值(即23+1-20=4),但fact变量实际存储在segm_date段中。后续执行MOV fact, CX时,CPU会去DS=4的内存段查找fact的偏移地址,完全偏离了变量实际位置,导致赋值无效,fact保持初始的0值。
2. 程序入口定义重复,执行流程混乱
代码末尾同时写了END et和END start,汇编器只会识别最后一个END后的标签作为程序入口,这会导致实际执行流程偏离预期,引发未知问题。
另外你提到预期fact的值是18,实际上(23+1-20)=4,4! = 24,预期值本身存在计算错误。
修复后的程序代码
; (a+b-c)!; la nivel de W, zona de mem distincte segm_stiva SEGMENT stiva DB 128 DUP (?) segm_stiva ENDS segm_date SEGMENT a DW 23 b DW 1 c DW 20 fact DW ? rez DW ? msg DB "p- Tarcuta Vasile!",'$' segm_date ENDS segm_cod SEGMENT ASSUME CS:segm_cod, DS:segm_date, SS:segm_stiva et: MOV AX, segm_date MOV DS, AX MOV AX, a ADD AX, b SUB AX, c MOV rez, AX ; 移除错误的DS修改代码,直接用rez初始化CX MOV CX, rez MOV AX,1 iar: MUL CX LOOP iar ; 直接将阶乘结果写入fact,无需中转CX MOV fact, AX MOV AX,4C00H INT 21H segm_cod ENDS END et ; 仅保留一个正确的程序入口定义
修复说明
- 删除修改
DS的错误代码,确保始终访问segm_date段的变量 - 直接用
MOV CX, rez初始化阶乘循环的计数器,无需通过DS中转 - 简化赋值操作,直接将阶乘结果从AX写入
fact,减少不必要的寄存器中转 - 移除重复的
END start,仅保留END et作为正确的程序入口 - 修复后,
fact会被正确赋值为24(4的阶乘),符合数学计算结果
内容的提问来源于stack exchange,提问作者Vasile Tarcuta
相关产品推荐
相关产品推荐

