【发布时间】:2015-02-12 04:42:41
【问题描述】:
我的目标是创建一个名为 Pig 的简单游戏。规则是 2 名玩家(你和电脑)正在竞相到达 100 分。每一回合,主动玩家都面临一个决定: a) 保持,轮到你的总数并将其添加到玩家的总总数中。 下一位玩家开始活跃。 b) 滚动,生成一个随机数 1 和 6。 结果是: o 到 1: 失去转弯,没有转弯总数添加到总总数中。 2至6: 将此数字添加到回合总数中。玩家又走了。
当我组装、链接和运行时,我收到:
rogerfleenor@roger-VirtualBox:~/Downloads$ ./pig 欢迎来到猪游戏。 目标与规则:先到100胜。输入 1 跳过轮到你并给电脑你的分数或 2 掷骰子。如果结果为 0 或 1,则转输。如果是 2 到 6,则将其添加到您的分数中。准备好?走! 输入 1 跳过转弯或输入 2 滚动。 2 2你的分数是
上面第一个“2”是我输入的数字,第二个2是从“write_digit2:”生成的
它应该实际输出生成的随机数。所以这引导我 相信我的问题在于“cmpUserDice”并且我将随机数字添加到 空缓冲区错误或类似的东西。特别是当我到达程序结束时 应该打印“userScore”的位置,终端中没有输出任何内容。是否有人能够识别 我的问题?这是我的最后一个项目,两天后到期!我很绝望。
section .bss
userScore: resb 4
pcScore: resb 4
counter: resb 4
digiter: resb 4
number: resb 4
digit: resb 4
count: resb 4
userOption: resb 30
intLen: resd 1
section .data
welcomeMsg db "Welcome to the Game of Pig.",13,10
welcomeLen equ $ - welcomeMsg
ruleMsg dd "Objective and Rules: first to 100 wins. Enter 1 to skip your turn and give the pc your score or 2 to roll the dice. If the outcome is 1, turn lost. If 2 to 6, it is added to your score. Ready? Go!",13,10
ruleLen equ $ - ruleMsg
optionMsg db "Enter 1 to skip turn or 2 to roll.",13,10
optionLen equ $ - optionMsg
userScoreIs db "your score is",13,10
userScoreIsLen equ $ - userScoreIs
section .text
global _start:
_start:
nop
mov ax, 0
call printWelcome
call printRules
call printReadOption
exit:
mov eax, 1
mov ebx, 0
int 80h
printWelcome:
mov edx, welcomeLen
mov ecx, welcomeMsg
mov ebx, 1
mov eax, 4
int 80h
printRules:
mov edx, ruleLen
mov ecx, ruleMsg
mov ebx, 1
mov eax, 4
int 80h
printReadOption:
;prints option
mov edx, optionLen
mov ecx, optionMsg
mov ebx, 1
mov eax, 4
int 80h
;reads option & saves as string
mov edx, 30
mov ecx, userOption
mov ebx, 2
mov eax, 3
int 80h
;save size of string input
dec eax
mov dword [intLen], eax
;convert string to int
mov edi, 10
mov ecx, [intLen]
mov esi, userOption
xor eax, eax
xor ebx, ebx
mov bl, [esi]
cmp bl, '-'
jne next_check
inc eax
inc esi
dec ecx
jmp done_sign
next_check:
cmp bl, '+'
jne done_sign
inc esi
dec ecx
done_sign:
push eax
l1:
mov bl, [esi]
cmp bl, 30h
;jb error
cmp bl, 39h
;ja error
sub bl, 30h
mul edi; eax=eax*10
mov bh, 0
add eax, ebx
inc esi
loop l1
pop ebx
cmp ebx, 1
jne compareInput
neg eax
compareInput:
cmp eax, 2
je userRollDice ;jmp to roll dice
cmp eax, 1 ;jmp to pc turn
je exit ;switch to pic turn
userRollDice: ;randnumgen 0-6
;jmp exit
mov eax, 13
int 80h
add eax, 65535
mov ebx, 30903
mul ebx,
mov edx, 0
mov ecx, 7
div ecx
mov dword[number], edx ;# to print
;call write_number
call cmpUserDice ;decides 1 - 6 effect
write_number:
L01:
mov eax, dword[number]
mov ecx, 0Ah
cdq
div ecx ;eax=number/10,edx=number%10
mov dword[number], eax ;number= number/10
add edx, 30h ;add 48 (30h) to make a printable character
push edx ;push edx in to the stack and
inc dword[count] ;increment count of numbers in the stack
cmp dword[number], 0 ;if number != 0, loop again
jne L01
L02:
pop dword[digit] ;pop the digit from the stack and
call write_digit ;write it
dec dword[count] ;decrement the count
cmp dword[count], 0 ; if count != 0, loop again
jne L02
ret
write_digit: ;Print score
mov eax, 4
mov ebx, 1
mov ecx, digit
mov edx, 4
int 80h
cmpUserDice:
cmp edx, 0
je userRollDice
cmp edx, 1
je printReadOption
cmp edx, 2
add dword[userScore], 2
je printUserScore
;call pcTurn
cmp edx, 3
add dword[userScore], 3
je printUserScore
;call pcTurn
cmp edx, 4
add dword[userScore], 4
je printUserScore
;call pcTurn
cmp edx, 5
add dword[userScore], 5
je printUserScore
;call pcTurn
cmp edx, 6
add dword[userScore], 6
je printUserScore
;call pcTurn
printUserScore:
mov eax, dword[userScore]
mov ecx, 0Ah ;hex for 10
cdq
div ecx ;eax=number/10,edx=number%10
mov dword[userScore], eax ;number= number/10
add edx, 30h ;add 48 (30h) to make a printable character
push edx ;push edx in to the stack and
inc dword[counter] ;increment count of numbers in the stack
cmp dword[userScore], 0 ;if number != 0, loop again
jne printUserScore
loop2:
pop dword[digiter] ;pop the digit from the stack and
call write_digit2 ;write it
dec dword[counter] ;decrement the count
cmp dword[counter], 0 ; if count != 0, loop again
jne loop2
ret
write_digit2: ;Print score
mov eax, 4
mov ebx, 1
mov ecx, digiter
mov edx, 4
int 80h
;prints your score is:
;mov dword[userScore], 2
mov eax, 4
mov ebx, 1
mov ecx, userScoreIs
mov edx, userScoreIsLen
int 80h
mov eax, 4
mov ebx, 1
mov ecx, userScore
mov edx, 4
int 80h
call exit;
【问题讨论】:
-
使用调试器单步执行代码以找出问题所在。我可以立即发现的一件事是您
call write_digit但缺少 `ret`。 -
您确定
.bss中的undefined 值从“0”开始——即initialized? -
@Jongware 是的,
.bss已初始化为零。 -
我找到了问题发生的区域。那就是我可能试图错误地添加到我的“userScore”缓冲区中。我不知道我是否应该先将要添加的数字转换为字符串,然后再添加 dword [userScore], 3' 这是正确的方法吗?因为在我尝试打印我的 'userScore' 之后,没有任何内容显示为空。
标签: linux string assembly x86 nasm