【发布时间】:2019-04-12 13:31:16
【问题描述】:
Assembly 是一门有趣的学习语言。我还有很大的进步空间。我正在尝试制作一个简单的掷骰子游戏,该游戏应该根据用户输入随机掷骰子 x 次。我的代码如下:
TITLE Program Template (main.asm)
INCLUDE Irvine32.inc
.data
diceOne DWORD ?
diceTwo DWORD ?
win DWORD 7, 11
lose DWORD 2, 3, 12
mark DWORD 4, 5, 6, 8, 9, 10
markCounter DWORD ?
userInput BYTE 'Enter integer: ', 0
numRolls DWORD ?
printWon BYTE 'Won: ', 0
wonCounter DWORD ?
printWin BYTE ' You win!', 0
printLost BYTE 'Lost: ', 0
lostCounter DWORD ?
printLose BYTE ' You lose!', 0
printTotal BYTE 'Total: ', 0
space DWORD ' ', 0
printPlus BYTE ' + ', 0
printMark BYTE ' Mark ', 0
.code
main PROC
call randomize ; set random seed
mov ecx, 6 ; counter set to 6
mov edx, offset userInput ; print string
call writeString
call readInt ; read input
mov numRolls, eax ; store input in variable
mov ecx, numRolls
mov eax, 0
mov edi, offset win
call gamesRolled
exit
main ENDP
;number of games rolled based on user input
gamesRolled PROC uses eax ecx
DICEROLLS:
call crlf
;diceOne roll
mov eax, 5 ;move value into eax to pass as parameter for randomrange
call randomRange ;randomrange stored in eax 0-5
inc eax
mov diceOne, eax ;mov the value of randomrange into variable
call writeDec
push edx ;push edx off stack to print space
mov edx, OFFSET printPlus
call writeString
pop edx
;diceTwo roll
mov eax, 6
call randomRange
inc eax
mov diceTwo, eax
call writeDec
add eax, diceOne ; add diceOne roll to diceTwo roll
cmp eax, win ; comp eax value to win
je wins
cmp eax, lose
je losses
cmp eax, mark
je marks
LOOP DICEROLLS
ret
gamesRolled ENDP
wins PROC uses edi ecx
mov edi, offset win
mov ecx, lengthof win
cmp eax, [edi]
add edi, type win
push edx
mov edx, offset printWin
call writeString
pop edx
jmp gamesRolled
ret
wins ENDP
losses PROC uses edi ecx
mov edi, offset lose
mov ecx, lengthof lose
cmp eax, [edi]
add edi, type lose
push edx
mov edx, offset printLose
call writeString
pop edx
jmp gamesRolled
ret
losses ENDP
marks PROC uses edi ecx
mov edi, offset lose
mov ecx, lengthof lose
cmp eax, [edi]
add edi, type lose
push edx
mov edx, offset printMark
call writeString
pop edx
jmp gamesRolled
ret
marks ENDP
END main
所以从我看到的例子和解释来看,这似乎很简单。我正在使用cmp/je 在循环掷骰子时像 if 语句一样工作。这个想法是增加胜负或分数并将其全部打印出来。如果没有 cmp/je 部分,它可以正常工作。我可以打印随机骰子,但是,一旦我开始尝试cmp/je,我会遇到一些奇怪的冻结,有时甚至会崩溃。我正在尝试学习如何在汇编中更好地编码。请您帮助我理解为什么这不能按我认为的方式工作。我想如果我比较包含diceOne + diceTwo 的组合总数的eax 寄存器,它应该跳转到其他函数,并且在这些函数中edi 应该像一个计数器,在打印表示获胜的字符串时进行计数,丢失或标记。比如:
Enter integer: 5
2 + 3 Mark
1 + 5 Mark
5 + 6 You win!
5 + 1 Mark
2 + 6 Mark
Wins: 1 Losses: 0 Marks: 4
我还没有进入最后一部分,因为我在处理代码时遇到了问题。感谢您对此的任何帮助。我很茫然。
这是我现在得到的实际结果:
Enter integer: 5
3 + 2
3 + 5
2 + 5 You win!
3 + 6
5 + 5
【问题讨论】:
-
我知道有些变量没有使用,请忽略。
-
我不理解规则 (tldr),但我看到你只与值 7、2 和 4 进行比较,而不是与数组的所有成员进行比较。这是故意的吗?
-
第一个
call randomRange将只产生 0-4 范围内的值(mov eax,5提前) -
我看不出您当前的版本会如何冻结或崩溃,它应该在没有任何消息的情况下执行
ecx多次循环,并显示值 7、2 的消息赢/输/标记, 4(那些带有消息的抛出不计算在内,如果只产生这样的抛出,则可以无限循环)。你能确认你发布的代码到底是什么吗? (我只是在脑海中“运行”它,所以我可能是错的)......哦..确实是......这些消息抛出也会将ecx重置为2、3或6,所以它可能会循环更长的时间......