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", 0
fmt_s db "%s", 0
fmt_d db "%d", 0
segment .bss
money: resb 8 ; defined money
user_name: resb 8 ; defined username
pass_word: resb 8 ; defined password
choose: resb 8 ; defined choose
withdraw_amount: resb 8 ;
deposit_amount: resb 8 ;
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
;lea rcx, [option4]
;call printf
user_check:
lea rcx, [information_text_username]
call printf; information text for username
mov rax, 0
lea rcx, [fmt_s]
mov rdx, user_name
call scanf; get username
mov rax, 0
lea rcx, [information_text_passw]
call printf; information text for password
mov rax, 0
lea rcx, [fmt_s]
mov rdx, pass_word
call scanf; get password
mov rax, 0
lea rcx, [username]
mov rdx, user_name
call strcmp; compare usernames
test eax, eax
jne not_equal_credentials; if not equal jump to func
lea rcx, [password]
mov rdx, pass_word
call strcmp; compare passwords
test eax, eax
jne not_equal_credentials ; if not equal jump to func
;otherwise
lea rcx, [entrance]
call printf ;welcome sea bank
mov rax, 0
jmp hello_system
user_choices:
lea rcx, [information_text_choice]
call printf; information text for user choices
mov rax, 0
lea rcx, [fmt_s]
mov rdx, choose
call scanf; user input for choice number
mov rax, 0
lea rcx, [choose]
mov rdx, userchoice1
call strcmp
test eax, eax
je choice_1
;jmp user_choices
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
;lea rcx, choose
;mov rdx, userchoice4
;call strcmp
choice_1:
lea rcx, information_text_userchoice1
call printf
mov rax, 0
lea rcx, [fmt_d]
mov rdx, money
call printf; print money
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, withdraw_amount
sub ecx, eax
mov eax, ecx
mov [money], eax
lea rcx, [new_balance]
mov rdx, money
call printf
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, deposit_amount
add ecx, eax
mov eax, ecx
mov [money], eax
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 ecx, [money]
jmp user_check
I wanted to write a simple banking system, I can't see any problem in the user login or other parts, but the value of the money variable in the bss segment does not change at all when I try to add or remove money.
Also, when I first run the program, I think it shows a different number as the output when I choose the 1st option. It happens because I don't specify, how can I fix these two problems?
I use these two commands to compile.
1
-nasm -f win64 -o "main.obj" "main.asm"
2
-link "C:\Users\xx\Desktop\assembly_x64\bank_system\main.obj" /subsystem:console /entry:main /defaultlib:ucrt.lib /defaultlib:msvcrt.lib /defaultlib:legacy_stdio_definitions.lib /defaultlib:Kernel32.lib /nologo /incremental:no /LARGEADDRESSAWARE:NO /opt:ref /out:"main.exe"
CodePudding user response:
When the user chooses to "Withdraw Money", you execute the following code:
mov eax, withdraw_amount sub ecx, eax mov eax, ecx mov [money], eax
Two problems here:
- The ECX register at this point does not contain the current balance.
- You are subtracting the address of the withdraw_amount variable instead of its value. (this also answers your second question)
Solve it with next simple code:
mov eax, [withdraw_amount]
sub [money], eax
or (avoiding Read-Modify-Write sub
) with:
mov eax, [money]
sub eax, [withdraw_amount]
mov [money], eax
The same issue exists for when the user chooses to "Deposit Money".
In your defense, you could have been thinking that the current balance was already in the ECX register since you do have a mov ecx, [money]
right at the start of the program. Sadly, by the time the calculations happen, the ECX register will have been used for a lot of other things already!