【问题标题】:Am i adding an integer to a resb wrong? and how to correct?我是否将整数添加到 resb 错误?以及如何纠正?
【发布时间】: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


【解决方案1】:

一个。如果输入有一个减号,那么 EAX 将是错误的。你需要在push eaxl1: 之间的xor eax,eax

b. BH的清算要么是多余的,要么是不够的!你选择。

c。 write_digit 例程错过了 RET 指令,EDX 必须设置为 1 而不是 4

write_digit:    ;Print score

mov eax, 4
mov ebx, 1
mov ecx, digit
mov edx, 4
int 80h

d。有几次你使用了类似的代码:

cmp edx, 2
add dword[userScore], 2
je printUserScore

条件跳转将基于加法而不是比较的结果!这可能不是你的意图。

【讨论】:

    猜你喜欢
    • 2014-06-03
    • 1970-01-01
    • 2019-02-10
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    • 2021-09-06
    • 2016-06-23
    • 1970-01-01
    相关资源
    最近更新 更多