GNU AS 程序集无法将用户输入转换为十进制

问题描述 投票:0回答:1

我试图通过在 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 "+"
  • 通过使输入仅 1 个字符长来删除新行
    ldr x2, =1
    并采用另一个假输入来处理 Enter 键...
assembly arm64 gnu-assembler
1个回答
0
投票

通过执行 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
© www.soinside.com 2019 - 2024. All rights reserved.