I am trying to learn assembly by writing a simple calculator in aarch64 assembly (GNU AS) I succeed on prompting user input but I cannot check if the user input is a number or even a char like '+' Here is the code:
.global main
.section .data
op_plus: .byte '+'
temp: .skip 1
debug_msg1: .asciz "True"
debug_msg1_len = . - debug_msg1
message_0:
.asciz "Hello, World!\n"
message_0_len = . - message_0
message_1:
.asciz "Enter mode +,-,*,/: "
message_1_len = . - message_1
message_2:
.asciz "enter the first num: "
message_2_len = . - message_2
message_3:
.asciz "enter the second num: "
message_3_len = . - message_3
message_4:
.asciz "results is "
message_4_len = . - message_4
.section .bss
.lcomm num1,10
.lcomm num2, 10
operator: .skip 1
.section .text
main:
// Writes "Hello, world!"
ldr x1, =message_0 // Load the address of the message
ldr x2, =message_0_len // Length of the message
bl print
/* prompts mode */
ldr x1, =message_1
ldr x2, =message_1_len
bl print
// takes input
ldr x1, =operator
ldr x2, =10
bl input
ldr w0, [x1]
/* fake input to handle enter press
ldr x1, =temp
ldr x2, =1
bl input*/
/* end prompt mode */
/* prompts first num */
ldr x1, =message_2
ldr x2, =message_2_len
bl print
// takes input
ldr x1, =num1
ldr x2, =10
bl input
/* end prompt first num */
/* prompts second num */
ldr x1, =message_3
ldr x2, =message_3_len
bl print
// takes input
ldr x1, =num2
ldr x2, =10
bl input
ldrb w2,[x1]
/* end prompt second num */
//prints operator
/* results */
ldr x1, =operator
sub x1, x1, '0'
//prints x1 to make sure its correct
ldr x2, =20
bl print
cmp x1, 1
beq add
/* end results */
// Exit the program
bl exit
print:
mov x0, 1 // file descriptor STDOUT
mov w8, 64 // sys call sys write
svc #0 // invoke syscall
ret // branch back to [lr](in this case its _start)
input:
mov x0, 0 // file descriptor STDIN
mov w8, #63 // syscall sys read
svc #0
ret
succes_res:
ldr x1, =message_4
ldr x2, = message_4_len
bl print
ret
add:
add w3, w1, w2
bl succes_res
bl exit
exit:
mov w8, #93 // syscall exit
mov x0, #0 // exit status
svc #0
true:
ldr x1, =debug_msg1
ldr x2, =debug_msg1_len
bl print
ret
exit_err:
mov w8, #93
mov x0, #1
svc #0
sub {register},{register}, '0'
it deletes everything from the registercmp {register}, {value}
where value is immediate or not && is in [1,'+'] even tried to make a data to put the value inside like this op_plus: .ascii "+"
ldr x2, =1
and taking another fake input to handle enter press...Fixed this by doing ldrb instead of ldr Like this:
ldr X1, =operator
ldrb w0, [X1]
ldr X1, =num1
ldrb W1, [X1]
sub w1, w1, '0' // converts to an int
...
cmp w0, '+' //works
NOTE: You have to do that at the end because sometimes w registers have the same value as x registers so if an x changed a w can change (not sure why I don't want to provide false information)
X1 = value
W1 == value
W1 = another_value
X1 = another_value
X1 = new_value
W1 == new_value