Home > Mobile >  How does one tell if the ascii character inside a register is equal to the ascii character inside of
How does one tell if the ascii character inside a register is equal to the ascii character inside of

Time:04-25

I'm attempting to load the first letter of a string into the register W2, then compare the value inside that register to the value inside of another register (W5). In the program below, the code refuses to branch even though both characters in each registers are equal. How can I get the code to branch.

     .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:

    // ... 

CodePudding user response:

LDR W5,=charH doesn't load the byte 'H' into W5. Rather, it loads the low 32 bits of the address of the label charH into W5.

If you wanted to get the actual character that is stored in memory at that address, you would need another load. (And use the full 64-bit address to begin with.)

LDR X5, =charH
LDRB W5, [X5]

However, ARM64 has move-immediate instructions that can handle any value up to 16 bits. Thus you can drop charH altogether and simply do

MOV W5, 'H'

For that matter, since CMP can also take an immediate (up to 12 bits), you could skip W5 altogether, and after loading W2 just do:

CMP W2, 'H'
B.EQ equalsH

On another note, LDR X0, =string isn't really the best way to get the address of string. It's better to use adr or adrp so that you have position-independent code. See Understanding ARM relocation (example: str x0, [tmp, #:lo12:zbi_paddr]) for an overview. But in brief, with two instructions and no literal pool data, you can both compute the address and do the load.

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

This doesn't post-increment X0 as your code does, but your code never actually uses the incremented value anyway.

  • Related