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
相关产品推荐
相关产品推荐

