我是汇编语言的新手,正在尝试编写一个计算器,用户可以输入 2 个数字,使用加法或减法来显示结果。我尝试了很多方法,但似乎找不到我哪里出错了!任何建议或解决方案都将不胜感激。提前谢谢 :)
section .data
welcome db 0dh, 0ah, 0dh, 0ah, "**Hey, welcome to this calculator!**", 0dh, 0ah
welcome_length equ $ - welcome
msg_prompt db "Add your calculation (e.g., 24 + 6): ", 0
msg_result db "Result: ", 0
msg_newline db 10, 0
invalid_operator db "Invalid input, please use + or - for operations", 0
section .bss
buffer resb 32
num1 resq 1 ; Number 1
num2 resq 1 ; Number 2
section .text
global _start
_start:
; Print the welcome message
mov rsi, welcome
mov rdx, welcome_length
mov rax, 1
mov rdi, 1
syscall
; Print the message prompt
mov rsi, msg_prompt
mov rdx, 37
mov rax, 1
mov rdi, 1
syscall
; Read the input
mov rsi, buffer
mov rdx, 32
mov rax, 0
mov rdi, 0
syscall
; Convert first number to an int
mov rsi, buffer
call parse_number
mov [num1], rax
; Move to the operator (adjusying rsi based on parsed length)
add rsi, rax
call skip_spaces
; Check the operator
movzx rbx, byte [rsi]
cmp rbx, '+'
je add_numbers
cmp rbx, '-'
je subtract_numbers
; Invalid operator - print error message
mov rsi, invalid_operator
mov rdx, 47
mov rax, 1
mov rdi, 1
syscall
jmp _exit
; Move to the 2nd
add_numbers:
inc rsi
call skip_spaces
call parse_number
mov [num2], rax
; Perform additiom
mov rax, [num1]
add rax, [num2]
call print_result
jmp _exit
; Move to the 2nd
subtract_numbers:
inc rsi
call skip_spaces
call parse_number
mov [num2], rax
; Perform subtraction
mov rax, [num1]
sub rax, [num2]
call print_result
jmp _exit
print_result:
; Printing the results
mov rsi, msg_result
mov rdx, 8
mov rax, 1
mov rdi, 1
syscall
; Converting results to a string
call print_number
ret
parse_number:
; Convering a string to a number
xor rax, rax
mov rcx, 0
parse_loop:
movzx rbx, byte [rsi]
test rbx, rbx
jz done_parsing
cmp rbx, '0'
jb done_parsing
cmp rbx, '9'
ja done_parsing
sub rbx, '0'
imul rax, rax, 10
add rax, rbx
inc rsi
inc rcx
jmp parse_loop
done_parsing:
mov rax, rcx
ret
print_number:
; Convert the number in rax to ASCII in buffer and display
mov rsi, buffer + 32
mov rcx, 10
add rsi, 1
mov byte [rsi], 0
; If the number is 0, handle it seperately
cmp rax, 0
je print_zero
print_loop:
xor rdx, rdx
div rcx
dec rsi
add dl, '0'
mov [rsi], dl
test rax, rax
jnz print_loop
jmp print_result_buffer
print_zero:
dec rsi
mov byte [rsi], '0'
jmp print_result_buffer
print_result_buffer:
; display result from buffer
mov rdx, buffer + 32
sub rdx, rsi
mov rax, 1
mov rdi, 1
syscall
ret
skip_spaces:
; skipping any spaces in the buffer
skip_space_loop:
movzx rbx, byte [rsi]
cmp rbx, ' '
jne skip_done
inc rsi
jmp skip_space_loop
skip_done:
ret
_exit:
; Exit the program
mov rax, 60
xor rdi, rdi
syscall
我已经记不清我尝试过的所有变化了。输出确实允许用户输入等式,例如 3 + 2,然后打印结果:,但实际上并没有显示数值计算
首先,错误:
done_parsing
用长度覆盖解析的数字print_result
在打印之前销毁该号码print_result_buffer
打印的字符比需要的少 1 个(adjusying rsi based on parsed length)
不需要,因为rsi
会自动指向解析停止的位置buffer
接下来是错过的优化:
rip
相对寻址parse_number
不需要计算长度替代版本可能如下所示: