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

EMU8086猜数字游戏代码报错:mov al,1h指令参数错误求助

问题:EMU8086环境下猜数字游戏MOV指令报错

我正在EMU8086中编写猜数字游戏,但第27行的mov al, 1h指令持续报错。尝试改为mov ah, 1h、mov ah, 01h后问题依旧,报错提示为:

(27) wrong parameters: MOV al, 1h;(27) probably no zero prefix for hex; or no 'h' suffix; or wrong addressing; or undefined var: 1h

以下是我的汇编代码:

.model small
.stack 100h

.data
    prompt db '0 ile 9 arasinda bir sayi girin:', 0DH, 0AH, '$'
    mesaj_1 db 'Girdiginiz sayi çok küçük', 0DH, 0AH, '$'
    mesaj_2 db 'Girdiginiz sayi çok büyük', 0DH, 0AH, '$'
    mesaj_3 db 'Dogru tahmin\\\! Tebrikler\\\!', 0DH, 0AH, '$'
    mesaj_4 db 'Oyuncu Tanitimi', 0DH, 0AH, '$'

.code

start:
  ; Veri segmenti kayitlarini ayarlama
  mov ax, @data
  mov ds, ax

  ; Oyuncu tanitim mesajini görüntüleme
  mov dx, offset mesaj_4
  mov ah, 9h
  int 21h

  ; Rastgele sayi üretme fonksiyonunu çagir
  call rand_num

  ; Kullanicidan karsilastirma degerini alma (tek haneli sayi varsayilir)
  mov al, 1h; Karakter giris kesmesi (sistemlere göre degisebilir)
  int 21h   ; Kesmeyi baslatma

  ; Karsilastirma degerini CL'ye saklama
  mov cl, al  ; AL'yi (giris) CL'ye tasima

; -- Giris döngüsü baslangici ---
döngü:
  ; Istemi görüntüleme
  mov dx, offset prompt
  mov ah, 9h
  int 21h

  ; Kullanici girisini okuma
  mov ah, 01h ; Karakter giris kesmesi (sistemlere göre degisebilir)
  int 21h   ; Kesmeyi baslatma

  ; ASCII girisini sayisal degere dönüstürme
  sub al, 30h ; Sayisal degeri elde etmek için '0' (0'in ASCII degeri) çikarma

  ; Geçerli girisi kontrol etme (0-9)
  cmp al, 0     ; 0 ile karsilastirma
  jl invalid  ; 0'dan küçükse (geçersiz) atlama
  cmp al, 9     ; 9 ile karsilastirma
  jg invalid  ; 9'dan büyükse (geçersiz) atlama

  ; Girilen sayiyi karsilastirma degeriyle karsilastirma
  cmp al, cl
  jl smaller   ; Küçükse atlama
  jg bigger    ; Büyükse atlama
  je correct   ; Esitse atlama

; -- Giris döngüsü sonu ---

invalid:
  ; Geçersiz giris için hata mesaji görüntüleme
  mov dx, offset mesaj_5
  mov ah, 9h
  int 21h

  ; Geçerli giris almak için döngüye geri dön
  jmp döngü

smaller:
  ; Daha küçük sayi için mesaji görüntüleme
  mov dx, offset mesaj_1
  mov ah, 9h
  int 21h
  jmp döngü ; Döngüye geri dön

bigger:
  ; Daha büyük sayi için mesaji görüntüleme
  mov dx, offset mesaj_2
  mov ah, 9h
  int 21h
  jmp döngü ; Döngüye geri dön

correct:
  ; Dogru tahmin için mesaji görüntüleme
  mov dx, offset mesaj_3
  mov ah, 9h
  int 21h

  ; Oyunu bitirme
  mov ah, 4ch  ; Program sonlandirma kesmesi (sistemlere göre degisebilir)
  int 21h

; -- Rastgele sayi üretme fonksiyonu ---
rand_num:
  mov ax, 1345h  ; Seed degeri (degistirilebilir)
  int 21h       ; Kesmeyi baslat (DOS için)
  mov bx, ax     ; Rastgele sayiyi BX'e tasi

  ret            ; Fonksiyondan dön

; -- Hata mesaji ---
mesaj_5 db 'Geçersiz bir sayi gir

解决方法

1. 修复MOV指令的参数错误

报错核心原因有两点:

  • DOS中断int 21h的功能号必须存入AH寄存器,而非AL。你要调用的是读取单个字符的功能(功能号01h),所以必须把功能号放到AH中。
  • EMU8086对十六进制数的写法要求严格,补前导零写成01h可避免编译器识别错误。

将第27行代码替换为:

mov ah, 01h ; Karakter giris kesmesi (sistemlere göre degisebilir)

2. 修正随机数生成逻辑

原rand_num函数逻辑错误,DOS下生成0-9随机数的正确方式是用int21h的2Ch功能获取系统时间作为种子,取模后得到目标范围的数值:

替换rand_num函数为:

; -- Rastgele sayi üretme fonksiyonu ---
rand_num:
  mov ah, 2Ch   ; DOS中断21h的2Ch功能:获取系统时间
  int 21h       ; CH=小时, CL=分钟, DH=秒, DL=百分秒
  mov ax, dx    ; 用秒和百分秒作为随机种子
  xor dx, dx    ; DX清零,准备除法操作
  mov bx, 10    ; 除数设为10,得到0-9的余数
  div bx        ; AX除以BX,余数存入DX
  mov cl, dl    ; 把0-9的随机数存入CL,作为要猜的数字
  ret            ; Fonksiyondan dön

3. 补全未闭合的字符串定义

代码末尾的mesaj_5定义不完整,缺少字符串闭合、换行符和DOS字符串结束符$,修复为:

; -- Hata mesaji ---
mesaj_5 db 'Geçersiz bir sayi gir!', 0DH, 0AH, '$'

4. 移除多余的用户输入逻辑

调用rand_num后读取用户输入并覆盖CL的代码是多余的,会替换掉随机生成的目标数字,删除以下两行:

mov ah, 01h ; Karakter giris kesmesi (sistemlere göre degisebilir)
int 21h   ; Kesmeyi baslatma

mov cl, al  ; AL'yi (giris) CL'ye tasima

内容的提问来源于stack exchange,提问作者Cemal Gürsel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 05:55:32