如何使emu8086程序输出结果?8086除法乘法显示问题求助
8086汇编除法乘法结果显示问题修复
问题描述
作业要求:使用8086通过逐次减法法实现两个8位数字的除法,将结果与7365相乘,通过中断在输出屏幕第19行、第14列、页码0处以蓝色显示该结果。
以下是编写的汇编代码(使用emu8086 4.08编译),但结果无法显示在屏幕上:
; You may customize this and other start-up templates; ; The location of this template is c:\emu8086\inc\0_com_template.txt ; You may customize this and other start-up templates; ; The location of this template is c:\emu8086\inc\0_com_template.txt org 100h dividend db 25; Example dividend divisor db 5; Example divisor result db 0; To store the quotient remainder db 0; To store the remainder main: mov ax, @data; Initialize the data segment mov ds, ax mov al, 16h; Load dividend into AL mov bl, 4h; Load divisor into BL xor ah, ah; Clear AH to store quotient xor dh, dh; Clear DH to store remainder divide_loop: cmp al, bl; Compare AL and BL jl divide_done; Jump if AL < BL, division is done sub al, bl; Subtract BL from AL inc ah; Increment quotient jmp divide_loop; Repeat the loop divide_done: mov 1000h, ah; Store quotient in memory mov 1001h, al; Store remainder in memory mult: mov bx, 7365h mov ax, 1000h mul bx mov 1002h, ax display_result: mov ah, 13h; Set interrupt for write string mov bh, 0; Set page number to 0 mov bl, 0011_1011b; Set text color to white on black mov cx, 2; Set number of characters to write mov dl, 10; Set column position to 10 mov dh, 19; Set row position to 19 mov bx, 1002h; Point to the data to display mov es, bx; Set data segment for the string lea dx, [bx]; Load address of the string into DX int 10h; Call interrupt to write the string end main ret
错误分析
- COM程序模型误用:
org 100h是COM程序的起始标记,这类程序无独立数据段,DS、CS、SS指向同一段,mov ax, @data和mov ds, ax属于无效操作,会导致DS地址错误。 - 变量未实际调用:代码定义了
dividend、divisor变量,但除法逻辑直接硬编码数值,未遵循作业要求的变量使用逻辑。 - 内存操作错误:
- 直接向绝对地址
1000h写入数据,COM程序内存从100h开始,该地址可能超出程序可用范围或覆盖关键数据; mov ax, 1000h是将地址值加载到AX,而非读取该地址存储的商,正确写法应为mov ax, [1000h]。
- 直接向绝对地址
- INT 10h功能13h参数错误:
- 功能13h要求
ES:DX指向ASCII字符串,但代码传入二进制数值地址,无法直接显示; - 颜色设置错误:要求蓝色显示,
0011_1011b是白字蓝底,正确蓝色前景(黑底)应为01h; - 列位置错误:作业要求第14列(从0计数为13),代码设置为
dl=10; - ES寄存器赋值错误:将
1002h传入ES,导致段地址完全错误,COM程序中ES应与DS保持一致。
- 功能13h要求
- 缺少数值转ASCII步骤:乘法结果为二进制数,必须转换为十进制ASCII字符才能显示。
修正后的代码
org 100h ; 定义变量 dividend db 25 ; 8位被除数 divisor db 5 ; 8位除数 quotient db 0 ; 存储除法商 remainder db 0 ; 存储除法余数 product dw 0 ; 存储乘法结果(16位) ascii_buf db 5 dup(0) ; ASCII转换缓冲区,最多存5位十进制数 main: ; 逐次减法实现8位除法 mov al, [dividend] mov bl, [divisor] xor ah, ah ; AH初始化0,用作商计数器 divide_loop: cmp al, bl jl divide_done ; AL < BL时除法完成 sub al, bl inc ah jmp divide_loop divide_done: mov [quotient], ah; 保存商 mov [remainder], al; 保存余数 ; 商与7365(7365h=29541十进制)相乘 mov ax, 0 mov al, [quotient] mov bx, 7365h mul bx mov [product], ax ; 保存16位乘法结果 ; 将二进制结果转换为十进制ASCII字符串 mov ax, [product] mov di, offset ascii_buf + 4 ; 从缓冲区末尾开始填充 mov cx, 10 ; 除数10,用于取余 convert_loop: xor dx, dx div cx ; AX=AX/10,DX=AX%10 add dl, '0' ; 余数转ASCII字符 mov [di], dl dec di cmp ax, 0 jne convert_loop ; 计算有效字符长度 mov si, di inc si ; SI指向第一个非零字符(或'0') mov cx, 0 count_len: cmp [si], 0 je count_done inc cx inc si jmp count_len count_done: ; 处理结果为0的特殊情况,确保显示一个'0' cmp cx, 0 jne display_setup mov [ascii_buf], '0' mov cx, 1 mov si, offset ascii_buf display_setup: ; 调用INT 10h功能13h显示字符串 mov ah, 13h ; 功能号:写字符串 mov al, 01h ; 模式1:更新光标,字符串含属性 mov bh, 0 ; 页码0 mov bl, 01h ; 颜色:蓝色前景,黑色背景 mov dh, 19 ; 行号19(从0计数) mov dl, 13 ; 列号13(对应第14列,从0计数) mov bp, si ; ES:BP指向ASCII字符串(COM程序ES=DS) int 10h ret
修正说明
- 遵循COM程序模型,移除无效的数据段初始化代码;
- 使用定义的变量完成除法运算,符合作业逻辑;
- 新增二进制转ASCII的转换逻辑,将数值转换为可显示的字符;
- 修正INT 10h功能13h的所有参数:设置正确的蓝色、行列位置,确保段地址正确;
- 处理结果为0的特殊情况,保证显示有效性。
内容的提问来源于stack exchange,提问作者Somisetti Sridhar
相关产品推荐
相关产品推荐

