16位汇编无FPU实现十进制转浮点除法输出异常求助
16位汇编无FPU实现十进制数除法输出异常问题分析与修复
核心问题诊断
你的代码存在多处逻辑错误,并非溢出导致输出乱码:
- 需求偏离:代码未实现「十进制数转浮点数及除法」的核心逻辑,反而执行了两个数高低字节的加法操作,完全与目标功能无关。
- 功能混用错误:调用
int 21h的02h功能时,错误用lea dx, [output_string]——02h功能是输出DL中的单个字符,输出字符串需用09h功能,这直接导致乱码。 - 栈不平衡问题:
si变量未被使用,loop float_pop_and_display固定循环6次,但栈中push的余数数量不确定,会弹出栈中无关数据,打印奇怪符号。 - 数据段未初始化:原代码未执行
mov ax, @data; mov ds, ax,导致访问数据段变量时可能出现非法内存访问。
修复后的代码实现
以下是基于定点小数模拟浮点数除法的实现(保留4位小数),完全不依赖FPU:
.model small .stack 100h .data decimal_number1 dw 1234 decimal_number2 dw 5678 output_string db "Result: $" dot db '.' .code start: mov ax, @data mov ds, ax ; 初始化数据段,原代码遗漏关键步骤 ; 输出前缀字符串 mov ah, 09h lea dx, output_string int 21h ; 定点小数处理:将被除数放大10000倍,保留4位小数精度 mov ax, decimal_number1 mov bx, 10000 mul bx ; DX:AX = 1234 * 10000 = 12340000 ; 执行除法操作 mov bx, decimal_number2 div bx ; AX = 商的整数部分,DX = 余数 ; 输出整数部分 push ax call print_decimal pop ax ; 输出小数点 mov ah, 02h mov dl, dot int 21h ; 计算并输出4位小数部分 mov cx, 4 decimal_fraction: mov ax, dx mov bx, 10 mul bx ; 余数*10,准备计算下一位小数 div decimal_number2 ; AX = 当前小数位数字,DX = 新余数 mov dl, al add dl, '0' mov ah, 02h int 21h loop decimal_fraction ; 程序退出 mov ah, 4Ch int 21h ; 辅助子程序:打印AX中的十进制整数 print_decimal: mov bx, 10 mov cx, 0 push_digits: xor dx, dx div bx push dx inc cx test ax, ax jnz push_digits pop_digits: pop dx add dl, '0' mov ah, 02h int 21h loop pop_digits ret end start
关键修复点说明
- 补充数据段初始化,确保变量访问合法。
- 用09h功能输出字符串,02h功能输出单个字符,修正功能混用错误。
- 通过「放大被除数+整数除法」模拟浮点数精度,实现小数除法逻辑。
- 动态计数处理数字位数,避免栈不平衡导致的乱码。
- 分离整数与小数部分,分别转换为ASCII字符输出。
内容的提问来源于stack exchange,提问作者Funny It Is
相关产品推荐
相关产品推荐

