MashiroIsAsleep 2024-09-30 08:18 采纳率: 50%
浏览 8
问题最晚将于10月08日00:00点结题

nasm x86 变量归零

用nasm x86汇编给ms-dos系统写了一个软盘引导扇区贪吃蛇小游戏。问题是重新开始游戏后分数不会归零。
目前尝试过

mov     dword [current_score], 0

但是并没有用。我能想到其他的解决方案都会使编译后的代码超过512字节的限制。不知道有没有佬有办法解决。

org 0x7C00
use16

start_point:

initialize_system:
    xor     ax, ax
    mov     ds, ax
    mov     es, ax
    mov     ss, ax
    mov     sp, 0x7C00

clear_screen:
    mov     ax, 0xB800
    mov     es, ax
    mov     ax, 3
    int     0x10
    inc     ah
    mov     cx, 0x2000
    int     0x10
    xor     di, di
    mov     cx, (160*25)/2
    mov     ax, 0x0720
    pusha
    rep     stosw

setup_game_state:
    mov     di, tick_counter
    stosd
    stosd
    mov     ax, (160*25)/2
    stosw
    add     al, 4
    stosw
    add     al, 4
    stosw
    mov     al, 0xFF
    out     0x60, al
    in      al, 0x61
    and     al, 0xFC
    out     0x61, al
    
    mov     di, (160*12) + 80    
    mov     [snake_ptr], di


draw_game_border:
    mov     ax, 0x072A
    mov     cx, 38
    mov     di, (160*4)+40
    rep     stosw
    mov     cx, 16
border_draw_loop:
    stosw
    pusha
    mov     cx, 41
    xor     ah, ah
    rep     stosw
    mov     ah, 0x07
    stosw
    popa
    add     di, 158
    loop    border_draw_loop
    mov     cx, 38
    mov     di, (160*20)+42
    rep     stosw

display_texts:
    mov     di, (160*3)+42
    mov     si, title_text
    call    render_text
    mov     si, score_text
    mov     di, (160*3)+94
    call    render_text
    mov     si, control_text
    mov     di, (160*21)+42
    call    render_text

main_game_loop:

prepare_game:
    popa

    mov     di, cx
    mov     si, initial_snake    
    call    render_text
    mov     bp, 6               
    call    spawn_food

game_delay:
    xor     eax, eax
    int     0x1A
    mov     ax, cx
    shl     eax, 16
    mov     ax, dx

    mov     ebx, eax
    sub     eax, [tick_counter]

    cmp     eax, 3
    jl      game_delay

    mov     [tick_counter], ebx

    in      al, 0x60

handle_input:
    cmp     al, 177
    je      start_point
    and     al, 0x7F
    cmp     al, 17
    je      move_up
    cmp     al, 30
    je      move_left
    cmp     al, 31
    je      move_down
    cmp     al, 32
    jne     game_delay

move_right:
    mov     al, '>'
    add     di, 4
    jmp     execute_move

move_up:
    mov     al, '|'
    sub     di, 160
    jmp     execute_move

move_down:
    mov     al, '|'
    add     di, 160
    jmp     execute_move

move_left:
    mov     al, '<'
    sub     di, 4

execute_move:
    cmp     byte [es:di], '@'
    sete    ah
    je      safe_move
    cmp     byte [es:di], ' '
    jne     game_over

safe_move:
    stosb
    dec     di

    pusha

    push    es
    push    ds
    pop     es
    mov     cx, bp
    inc     cx
    mov     si, snake_ptr
    add     si, bp
    mov     di, si
    inc     di
    inc     di
    std
    rep     movsb
    cld
    pop     es

    popa
    push    di
    mov     [snake_ptr], di
    mov     di, [snake_ptr+2]
    mov     al, '*'        
    stosb

    cmp     ah, 1
    je      handle_food

    mov     di, [snake_ptr + bp]
    mov     al, ' '       
    stosb

    jmp     continue_game

handle_food:
    inc     bp
    inc     bp

    mov     di, (160*3)+114
    add     dword [current_score], 1
    mov     ax, [current_score]
    mov     bl, 10

update_score_display:
    div     bl
    xchg    al, ah
    add     al, '0'
    stosb
    dec     di
    dec     di
    dec     di
    mov     al, ah
    xor     ah, ah
    or      al, al
    jnz     update_score_display
    call    spawn_food

continue_game:
    pop     di
    jmp     game_delay

game_over:
    mov     di, (160*19)+92
    mov     si, gameover_text
    call    render_text
wait_for_restart:
    in      al, 0x60
    cmp     al, 177
    jne     wait_for_restart
    jmp     start_point

spawn_food:
    pusha
    xor     eax, eax
    xor     bl, bl
    int     0x1A
spawn_seed:
    xor     eax, eax
    xor     bl, bl
    int     0x1A
random_position:
    cmp     bl, 5
    jg      spawn_seed

    mov     ax, dx
    mov     cx, 75
    mul     cx
    movzx   edx, dx
    mov     ecx, 65537
    div     ecx
    mov     ax, dx
    shr     edx, 16
    mov     ecx, (160*20)
    div     cx
    and     dl, 0xFC

    inc     bl
    cmp     dx, (160*5)
    jl      random_position
    mov     di, dx
    cmp     byte [es:di], 0x20
    jne     random_position

    mov     al, '@'
    stosb
    popa
    ret

render_text:
    pusha
render_loop_text:
    lodsb
    or      al, al
    jz      render_done_text
    stosb
    inc     di
    jmp     render_loop_text
render_done_text:
    popa
    ret

title_text:        db 'Snake',0
control_text:      db 'WASD, N - restart',0
gameover_text:     db 'Game Over',0
score_text:        db 'Score:',0
initial_snake:     db '      ',0    

times 510-($-$$) db 0
dw 0xAA55

section .bss
tick_counter:      resd 1
current_score:     resd 1
snake_ptr:         resd 1
  • 写回答

15条回答 默认 最新

  • 阿里嘎多学长 2024-09-30 08:19
    关注

    AIGC生成:


    问题解决方案

    在 NASM 汇编中,变量的地址是通过在数据段中定义变量的方式来实现的。因此,在重新开始游戏时,需要将变量的值设置为 0。

    在你的代码中,可能是因为你没有在数据段中定义 current_score 变量,从而导致无法正确地将其设置为 0。

    解决方案是,在数据段中定义 current_score 变量,然后使用 mov 指令将其设置为 0。例如:

    section .data
    current_score dd 0
    
    section .text
    ; ...
    mov dword [current_score], 0
    ; ...
    

    在上面的代码中,.data 段用于定义数据,current_score 是一个双字长整数变量,初始值为 0。然后,在 .text 段中,可以使用 mov 指令将 current_score 设置为 0。

    这样,在重新开始游戏时,current_score 变量的值将被正确地设置为 0。


    评论

报告相同问题?

问题事件

  • 创建了问题 今天

悬赏问题

  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见
  • ¥15 一共有五道问题关于整数幂的运算还有房间号码 还有网络密码的解答?(语言-python)
  • ¥20 sentry如何捕获上传Android ndk 崩溃
  • ¥15 在做logistic回归模型限制性立方条图时候,不能出完整图的困难
  • ¥15 G0系列单片机HAL库中景园gc9307液晶驱动芯片无法使用硬件SPI+DMA驱动,如何解决?