如何判断一个寄存器内的 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
地址的最佳方式。最好使用 adr
或 adrp
以便您拥有 position-independent 代码。有关概述,请参阅 。但简而言之,使用两条指令且没有文字池数据,您既可以计算地址又可以进行加载。
ADRP X0, string
LDRB W2, [X0, #:lo12:string]
这并不像您的代码那样 post-increment X0,但您的代码实际上从未真正使用增量值。
我正在尝试将字符串的第一个字母加载到寄存器 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
地址的最佳方式。最好使用 adr
或 adrp
以便您拥有 position-independent 代码。有关概述,请参阅
ADRP X0, string
LDRB W2, [X0, #:lo12:string]
这并不像您的代码那样 post-increment X0,但您的代码实际上从未真正使用增量值。