我正在嘗試將字串的第一個字母加載到暫存器 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:
// ...
uj5u.com熱心網友回復:
LDR W5,=charH不會將位元組加載'H'到 W5 中。相反,它將標簽地址的低 32 位加載charH到 W5 中。
如果您想獲取存盤在該地址的記憶體中的實際字符,則需要再次加載。(并使用完整的 64 位地址開始。)
LDR X5, =charH
LDRB W5, [X5]
但是,ARM64 具有可以處理高達 16 位的任何值的立即移動指令。因此,您可以完全放棄charH并簡單地做
MOV W5, 'H'
就此而言,由于CMP也可以采用立即數(最多 12 位),您可以完全跳過 W5,在加載 W2 之后執行以下操作:
CMP W2, 'H'
B.EQ equalsH
另一方面,LDR X0, =string這并不是獲取string. 最好使用adroradrp以便您擁有與位置無關的代碼。有關概述,請參閱了解 ARM 重定位(示例:str x0、[tmp、#:lo12:zbi_paddr])。但簡而言之,使用兩條指令且沒有文字池資料,您既可以計算地址又可以進行加載。
ADRP X0, string
LDRB W2, [X0, #:lo12:string]
這不會像您的代碼那樣后遞增 X0,但您的代碼實際上從未使用過遞增的值。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/463854.html
