为什么多个 B.Cond 语句总是只能解析一种变量输入方式?

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

在 qemu 上使用arm64。

我想检查用户输入的值是负数、正数还是零。我有一条 SUBS 指令,后跟三个 B.Cond 指令。我使用 %d 格式的 scanf 来获取变量,并使用 printf 来输出变量。这是在一个玩具程序中发生的,没有其他功能。

如果我更改 B.Cond 指令的顺序,以防由于我自己的无知或缺乏对细节的关注而导致某些默认行为,则会运行 B.GT 指令。

如果我更改用于与用户值进行比较的值,以防万一我缺少条件分支指令的一些更精细的点,则会运行 B.GT 指令。

如果我将零检查指令更改为 CBZ,以防再次出现 B.Cond 指令的某些方面,则运行 B.GT 指令。

以下是相关代码。我省略了与打印哪个分支相关的部分。


.section .data

input_number:       .asciz  "Please enter a number: "
input_spec:         .asciz  "%d"
error:          .asciz "Please input a positive number \n"
negative:   .asciz "Input is NEGATIVE.\n"
zero:   .asciz "Input is ZERO.\n"
positive:   .asciz "Input is POSITIVE.\n"

.section .text


.global main



main:

LDR x0, =input_number
BL printf

SUB SP, SP, #16
LDR x0, =input_spec
MOV x1, SP
BL scanf
LDUR x9, [SP, #0]
ADD SP, SP, #16

CMP x9, xzr
B.GT POSITIVE
B.LT NEGATIVE
CBZ x10, ZERO

B exit

NEGATIVE:

LDR x0, =negative
BL printf
B exit


ZERO:

LDR x0, =zero
BL printf
B exit


POSITIVE:

LDR x0, =positive
BL printf
B exit


exit:

    mov x0, 0
    mov x8, 93
    svc 0
    ret

根据建议进行编辑并回复。 @Nate Eldridge:我在分支末尾添加了执行代码以及关联的全局变量。
我已将堆栈增量和减量编辑为 16 的倍数。我在其他地方读过该内容,但这样做会导致我的原始递归程序中无限减法,就好像它从未识别出所跟踪的值何时一样变为零,因此无限递归。
我知道

MOV
CMP
宏(说明?)。由于我仍在学习指令集,因此我想在使用更简单的方法之前先学习标准指令。为了便于阅读,我已根据您的建议更改了代码。
我最初确实将
CBZ
设为
B.EQ
,但出于测试目的对其进行了更改。我觉得表明多种类型的条件分支指令受到影响可能很有用,而不仅仅是
B.Cond

assembly conditional-statements qemu arm64
1个回答
0
投票

您对

%d
使用
scanf
格式说明符,它需要一个指向 32 位字的指针。 但是,您随后可以使用
LDUR x9, [SP, #0]
将其从堆栈中加载,这是一个 64 位加载。 因此
x9
(也称为
w9
)的低 32 位将包含数字,但高 32 位将包含垃圾。 如果该垃圾的最高位恰好为零(这很可能是因为所有堆栈内存在程序开始时都被清零),那么生成的有符号 64 位数字将为正数。

修复它的一些方法:

  • 将 32 位加载到带有符号扩展的 64 位寄存器中:

    LDRSW x9, [SP]
    。 (如果您愿意,也可以使用
    LDURSW
    。当它为零时,您无需写入立即偏移量
    #0
    。)然后
    x9
    包含 64 位值,该值在数值上等于堆栈中的 32 位值,您的比较将按预期进行。

  • 将 32 位加载到 32 位寄存器中,然后只需使用 32 位指令:

    LDR w9, [SP]
    后跟
    CMP w9, wzr
    (或原始版本中的
    SUBS w10, w9, wzr
    )。

  • 让 scanf 解析 64 位

    long int
    值:使用
    %ld
    而不是
    %d
    作为格式字符串。 然后其余代码可以保持不变。

© www.soinside.com 2019 - 2024. All rights reserved.