Windows x64汇编中BSS段变量加减失效及初始值问题求助
修复Windows x64汇编简易银行系统的两个问题
问题原因分析与修复方案
1. money变量加减操作后数值无变化
错误出在choice_2和choice_3的金额计算逻辑:
- 直接取
withdraw_amount/deposit_amount的地址而非存储的数值(mov eax, withdraw_amount是取地址,正确应为mov eax, [withdraw_amount]) - 未加载当前
money的数值就进行加减操作,导致计算基于随机值而非实际余额
修复逻辑:
- 先将当前
money的值加载到寄存器 - 读取输入的金额数值(而非地址)
- 执行加减操作后写回
money变量
2. 首次查看余额显示随机数值
BSS段的变量默认未初始化,money初始值为内存随机值。需要在程序启动时显式初始化money为0。
修复后的完整代码
default rel bits 64 segment .data username db "saave", 0 password db "root", 0 information_text_username db "please enter your username: ", 0 information_text_passw db "please enter your password: ", 0 not_equal db "username or password is incorrect", 0xa, 0 entrance db "WELCOME TO SEA BANK", 0xa, 0 option1 db "1-Show Balance", 0xa, 0 option2 db "2-Withdraw Money", 0xa, 0 option3 db "3-Deposit Money", 0xa, 0 option0 db "exit", 0xa ,0 ;option4 db "calculate interest", 0xa userchoice0 db "0", 0 userchoice1 db "1", 0 userchoice2 db "2", 0 userchoice3 db "3", 0 ;userchoice4 db "4", 0 information_text_choice db "Please choose your operation: ", 0 information_text_userchoice1 db "Current balance: ", 0 information_text_userchoice2 db "Enter the amount you want to withdraw: ", 0 information_text_userchoice3 db "Enter the amount you want to deposit: ", 0 new_balance db "new balance: %d", 0xa, 0 ; 新增换行符,优化输出格式 fmt_s db "%s", 0 fmt_d db "%d", 0 segment .bss money: resq 1 ; 用resq定义8字节变量,明确为64位整数 user_name: resb 8 ; 存储用户名 pass_word: resb 8 ; 存储密码 choose: resb 8 ; 存储用户选择 withdraw_amount: resd 1 ; 用resd定义4字节整数,匹配%d输入类型 deposit_amount: resd 1 ; 用resd定义4字节整数,匹配%d输入类型 segment .text extern printf, scanf, strcmp, ExitProcess, _CRT_INIT global main exit: xor rax, rax call ExitProcess hello_system: lea rcx, [option1] call printf mov rax, 0 lea rcx, [option2] call printf mov rax, 0 lea rcx, [option3] call printf mov rax, 0 jmp user_choices user_check: lea rcx, [information_text_username] call printf; 提示输入用户名 mov rax, 0 lea rcx, [fmt_s] mov rdx, user_name call scanf; 获取用户名 mov rax, 0 lea rcx, [information_text_passw] call printf; 提示输入密码 mov rax, 0 lea rcx, [fmt_s] mov rdx, pass_word call scanf; 获取密码 mov rax, 0 lea rcx, [username] mov rdx, user_name call strcmp; 比较用户名 test eax, eax jne not_equal_credentials; 不匹配则跳转 lea rcx, [password] mov rdx, pass_word call strcmp; 比较密码 test eax, eax jne not_equal_credentials ; 不匹配则跳转 lea rcx, [entrance] call printf ; 输出欢迎信息 mov rax, 0 jmp hello_system user_choices: lea rcx, [information_text_choice] call printf; 提示选择操作 mov rax, 0 lea rcx, [fmt_s] mov rdx, choose call scanf; 获取用户选择 mov rax, 0 lea rcx, [choose] mov rdx, userchoice1 call strcmp test eax, eax je choice_1 lea rcx, [choose] mov rdx, userchoice2 call strcmp test eax, eax je choice_2 lea rcx, [choose] mov rdx, userchoice3 call strcmp test eax, eax je choice_3 lea rcx, [choose] mov rdx, userchoice0 call strcmp test eax, eax je exit choice_1: lea rcx, information_text_userchoice1 call printf mov rax, 0 lea rcx, [fmt_d] mov rdx, [money] ; 传递money的数值而非地址 call printf; 打印余额 mov rax, 0 call printf ; 打印换行,优化输出格式 mov rax, 0 jmp user_choices choice_2: lea rcx, [information_text_userchoice2] call printf mov rax, 0 lea rcx, [fmt_d] mov rdx, withdraw_amount call scanf mov rax, 0 mov eax, [money] ; 加载当前余额 sub eax, [withdraw_amount] ; 减去取款金额 mov [money], eax ; 写回更新后的余额 lea rcx, [new_balance] mov rdx, [money] ; 传递更新后的余额数值 call printf mov rax, 0 jmp user_choices choice_3: lea rcx, [information_text_userchoice3] call printf mov rax, 0 lea rcx, [fmt_d] mov rdx, deposit_amount call scanf mov rax, 0 mov eax, [money] ; 加载当前余额 add eax, [deposit_amount] ; 加上存款金额 mov [money], eax ; 写回更新后的余额 lea rcx, [new_balance] mov rdx, [money] ; 传递更新后的余额数值 call printf mov rax, 0 jmp user_choices not_equal_credentials: lea rcx, [not_equal] call printf mov rax, 0 jmp user_check main: push rbp mov rbp, rsp sub rsp, 32 mov qword [money], 0 ; 初始化余额为0,解决首次显示随机值问题 jmp user_check
额外优化说明
- 将
money改为resq 1明确为64位整数,withdraw_amount和deposit_amount改为resd 1匹配%d的4字节输入,类型定义更清晰 - 在
new_balance格式字符串中添加换行符,输出排版更整洁 - 修复
choice_1中printf传递的参数为money的数值而非地址,避免错误输出内存地址
内容的提问来源于stack exchange,提问作者DertliSelo
相关产品推荐
相关产品推荐

