我试图通过在 aarch64 程序集(GNU AS)中编写一个简单的计算器来学习汇编,我成功提示用户输入,但我无法检查用户输入是否是数字,甚至是像“+”这样的字符,这是代码:
.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'
将输入转换为十进制,它会删除寄存器中的所有内容cmp {register}, {value}
检查输入,其中值是否为立即数 && 位于 [1,'+'] 中,甚至尝试制作数据以将值放入其中,如下所示 op_plus: .ascii "+"
ldr x2, =1
并采用另一个假输入来处理 Enter 键...通过执行 ldrb 而不是 ldr 修复了此问题 像这样:
ldr X1, =operator
ldrb w0, [X1]
ldr X1, =num1
ldrb W1, [X1]
sub w1, w1, '0' // converts to an int
...
cmp w0, '+' //works
注意:您必须在最后执行此操作,因为有时 w 寄存器与 x 寄存器具有相同的值,因此如果 x 更改,w 也会更改(不确定为什么我不想提供虚假信息)
X1 = value
W1 == value
W1 = another_value
X1 = another_value
X1 = new_value
W1 == new_value