assembly 在windows x64程序集中从bss段中的变量减去或加上一个数字

oknwwptz  于 2022-11-13  发布在  Windows
关注(0)|答案(1)|浏览(92)
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

我想写一个简单的银行系统,我看不出用户登录或其他部分有任何问题,但是当我尝试添加或删除货币时,bss段中的 money 变量的值根本没有改变。
另外,当我第一次运行程序时,我想当我选择第一个选项时,它会显示一个不同的数字作为输出。发生这种情况是因为我没有指定,我该如何解决这两个问题?
我使用这两个命令进行编译。

1

-nasm -f win 64-o“主.对象”“主. asm”

2

-link“C:\用户\xx\桌面\组件_x64\银行_系统\main. obj”/子系统:控制台/入口:主/默认库:ucrt.lib /默认库:msvcrt.lib /默认库:legacy_stdio_definitions.lib /默认库:Kernel32.lib /nologo /增量:无/大的地址软件:无/opt:引用/输出:“main.exe”

jfgube3f

jfgube3f1#

当用户选择“提款”时,执行以下代码:

mov eax, withdraw_amount
sub ecx, eax
mov eax, ecx
mov [money], eax

这里有两个问题:

  • ECX寄存器此时不包含当前余额。
  • 您减去的是 withdraw_amount 变量的地址,而不是其。(这也回答了您的第二个问题)

用下面的简单代码求解:

mov  eax, [withdraw_amount]
sub  [money], eax

或(避免读取-修改-写入sub),使用:

mov  eax, [money]
sub  eax, [withdraw_amount]
mov  [money], eax

当用户选择“存款”时存在相同的问题。
你可能会认为当前的余额已经在ECX寄存器中了,因为你在程序开始的时候就有一个mov ecx, [money]。遗憾的是,当计算发生的时候,ECX寄存器已经被用于很多其他的事情了!

相关问题