我正在尝试用一个内核在NASM汇编中做一个猜谜游戏。 Boot 加载程序只是指向内核文件。内核文件存储了所有的东西。游戏的所有函数和变量;而我已经打印出了游戏的说明。当我使用if语句时,它会打印出获胜消息,不管它的数字是否正确。我希望内核在选择正确的数字时打印出正确的获胜消息。我的内核代码如下...
org 0
bits 16
_start:
push cs
pop ds
mov si, msg
jmp BeginLoop
PrintLoop:
mov ah, 0x0E
int 0x10
BeginLoop:
mov al, [si]
inc si
or al, al
jz GameLoop
test al, al
jnz PrintLoop
GameLoop:
xor ax, ax
int 16h
mov ah, 0x0E
int 0x10
cmp ax, 0x5
jne GameWon
GameWon:
mov si, won
mov al, [si]
inc si
or al, al
jz GameLoop
test al, al
jnz PrintLoop
cli
hlt
jmp $-2
msg db 'Welcome To My Guessing Game: ', 10, 13, 'Pick A Number Between 1 - 10 ', 10, 13, 0
won db 'You Guessed The Correct Number!', 10, 13, 0
loss db 'You Guessed The Incorrect Number!' 10, 13
TIMES 512 - ($ - $$) db 0
更新了可正常工作的代码
org 0
bits 16
_.start:
push cs
pop ds
mov si, msg
jmp Print
GameLoop:
mov ah, 00h
int 1ah
mov ax, dx
xor dx, dx
mov cx, 10
div cx
add dl, '0'
mov ah, 0x00
int 16h
mov ah, 0x0E
int 0x10
GameCondition:
mov si, won
cmp al, dl
je GameWon
jmp GameLost
GameLost:
mov si, loss
jmp Print
GameWon:
jmp Print
Print:
jmp BeginLoop
PrintLoop:
mov ah, 0x0E
int 0x10
BeginLoop:
mov al, [si]
inc si
or al, al
jz GameLoop
test al, al
jnz PrintLoop
ret
; -------------------
msg db 'Welcome To My Guessing Game: ', 10, 13, 'Pick A Number Between 0 - 9 ', 10, 13, 0
won db 'You Guessed The Correct Number!', 10, 13, 0
loss db 'You Guessed The Incorrect Number!', 10, 13, 0
times 512 - ($-$$) db 0
2条答案
按热度按时间pes8fvy91#
在根据比较结果进行分支的代码中,如果条件为真,则执行跳转,但如果条件不为真,则继续执行下面的代码行。我们称之为“falling through”。在您的程序中,您总是会到达 GameWon。
这是另一个不了解代码福尔斯原理的例子。当
test al, al
指令确定AL为0时,PrintLoop 将不会继续,执行将进入 GameLoop。因此,使用添加的两行(or al, al
jz GameLoop
)检查空AL是完全多余的。游戏循环等待一个密钥,将其回显到屏幕,然后将该密钥与值
0x5
进行比较。BIOS在AL寄存器中提供了密钥的ASCII码**,在AH寄存器中提供了密钥的扫描码**。
cmp ax, 0x5
指令(比较完整的16位)不起作用的原因有3个:你的程序输出了几条消息。你不能继续使用我在前面的答案中写的 PrintLoop。你需要把这段代码变成一个子例程,你可以
call
多次:提示:最好是0到9之间的一位数。数字10不是一个好的选择,因为它没有一个ASCII码。
你最新的编辑表明你也想实现一个随机数生成器。在8086随机数生成器中掌握它(不仅仅是使用系统时间)?。
div ax, 3
行不是有效指令!并且xor ax, ax
需要改为xor dx, dx
。接下来是一个正确的除法运算,当然(57/3)+1并不令人惊讶:
2hh7jdfx2#
有几件事是错误的。首先,正如@vitsoft之前所说的,你没有GameLoss条件。你正在检查某个值是否为5,基本上忽略了这个条件。
要修复上述代码,可以:
还有这个东西
您要将0x 0 E移动到
ah
,然后期望ax
的值为0x 5。这是不可能的,因为据我所知,int 0x10
不会修改ah
。因此代码应为:这里是一个简单的猜谜游戏的代码,我还没有尝试过这个本身,尝试它,并适应自己:
编辑:
这段代码是错误的:
这甚至没有意义:
你正在比较两个值,如果它们相等,就执行
GameWon
。如果它们不相等,你什么也不做,你的代码继续执行,无论如何都到达GameWon
。我在这篇文章中多次提到这个问题,它实际上是文章的第二句话。要修复代码,它应该是:现在你要检查
al
和dl
是否相同,如果不相同,你就跳到GameLost
,如果相等,你就自动执行GameWon
。这与@SepRoland的注解相结合,使您的最终代码如下: