如何判断一个寄存器内的 ascii 字符是否等于 64 位 ARM 汇编中另一个寄存器内的 ascii 字符

How does one tell if the ascii character inside a register is equal to the ascii character inside of another register in 64-bit ARM assembly

我正在尝试将字符串的第一个字母加载到寄存器 W2 中,然后将该寄存器中的值与另一个寄存器 (W5) 中的值进行比较。在下面的程序中,即使每个寄存器中的两个字符都相等,代码也拒绝分支。我怎样才能让代码分支。

     .data 

string: .asciz "Hello"       // Loads string the ascii character "Hello"

charH:  .asciz "H"           // Initializes charH with 'H'

    .global _start      // Provide program with starting address to linker
    .text

_start:

    LDR X0,=string  // Loads the string "Hello" into X0
    LDR W5,=charH   // Loads the character "H" into W5

 // Should Load the first letter of string into the W2 register and then post-increments the pointer to the next byte of the string
    
    LDRB    W2, [X0], #1    

    CMP W2, W5       // Compares W2 with W5
    B.EQ equalsH     // Branches if both equal  

end:
    
    MOV X0, #0  // Use 0 return code

    MOV X8, #93 // Service command code 93 to terminate the program

    SVC 0       // Call linux to terminate

    .end

// The Goal is to get the condition to branch here! "equalsH"

    equalsH:

    // ... 

LDR W5,=charH 不会将字节 'H' 加载到 W5 中。相反,它将标签 charH 地址 的低 32 位加载到 W5.

如果您想获取存储在该地址内存中的实际字符,则需要再次加载。 (并使用完整的 64 位地址作为开头。)

LDR X5, =charH
LDRB W5, [X5]

但是,ARM64 有 move-immediate 指令可以处理最多 16 位的任何值。因此你可以完全放弃 charH 并简单地做

MOV W5, 'H'

就此而言,由于 CMP 也可以采用立即数(最多 12 位),您可以完全跳过 W5,加载 W2 后只需执行:

CMP W2, 'H'
B.EQ equalsH

另一方面,LDR X0, =string 并不是获取 string 地址的最佳方式。最好使用 adradrp 以便您拥有 position-independent 代码。有关概述,请参阅 。但简而言之,使用两条指令且没有文字池数据,您既可以计算地址又可以进行加载。

ADRP X0, string
LDRB W2, [X0, #:lo12:string]

这并不像您的代码那样 post-increment X0,但您的代码实际上从未真正使用增量值。