You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FASM汇编:使用CMOVG指令从内存向AX赋值时程序崩溃的解决

16位实模式FASM程序CMOVG指令崩溃问题解决

问题概述

使用FASM编写16位实模式程序(org 0100h),需在VGA图形模式12h下通过Graphic子程序重绘指定区域背景:遍历280-487列、368-385行像素,检测到黑色像素时,用CMOVG指令将全局变量barvy_kontrola的值加载到AX(AH固定为0Ch,AL为像素值),再调用BIOS中断int 10h的0Ch功能写入像素。程序首次执行CMOVG时崩溃,问题位于Graphic子程序.writePixel子标签内的第4、13、16行(原代码行236附近)。

测试代码(用于在80×25文本区23行35列输出text_b内容):

pusha
mov si, text_b
call print_string_end2
popa

核心原因分析

  1. 指令兼容性问题:CMOVG属于IA-32架构的条件移动指令,仅在Pentium Pro及后续CPU支持,而16位实模式的传统DOS环境可能运行在不支持该指令的早期CPU上,执行时会触发非法指令异常导致崩溃。
  2. 操作数宽度不匹配:16位模式下CMOVG要求源和目标操作数宽度完全一致,若代码中直接将字节型的barvy_kontrola赋值给AX(16位寄存器),或使用了不符合16位寻址规则的内存操作数,会触发操作数错误。

解决方案

方案1:用传统条件分支替代CMOVG(兼容所有16位CPU)

放弃CMOVG,改用CMP+JG的分支逻辑实现相同功能,这是16位实模式下最稳妥的做法:

; 假设此前已将当前像素颜色读取到AL中
cmp al, 0       ; 判断是否为黑色像素
jg .skip_write  ; 非黑色则跳过写入
mov ah, 0Ch     ; 设置BIOS写像素功能号
mov al, [barvy_kontrola] ; 加载目标像素值
int 10h         ; 调用BIOS中断写入像素
.skip_write:

方案2:修正CMOVG操作数(仅适用于支持该指令的CPU)

若确认目标CPU支持CMOV系列指令,需严格保证操作数宽度匹配:

  • 若barvy_kontrola是字节型变量:
mov ah, 0Ch     ; 固定AH为0Ch
cmp al, 0       ; 检测当前像素是否为黑色
mov bl, [barvy_kontrola] ; 先将像素值加载到8位寄存器BL
cmovg al, bl    ; 条件满足时将BL赋值给AL(保持操作数宽度一致)
int 10h         ; 调用中断写入像素
  • 若barvy_kontrola是字型变量(高字节预存0Ch,低字节为像素值):
; 假设此前已将当前像素的完整颜色(AH=0, AL=像素值)读取到AX中
cmp ax, 0000h   ; 判断是否为黑色像素
cmovg ax, [barvy_kontrola] ; 条件满足时直接替换AX值
int 10h         ; 调用中断写入像素

内容的提问来源于stack exchange,提问作者user22969975

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 21:52:46