Sentinel
Sentinel

Reputation: 461

Comparing signed integer in arm assembly

Loading a global variable and checking to see if it's equal to -1 but my code will not recognize it as equal to -1. It only pass the comparison with local variables.

//setting global variable
    .data
    .global top_m
    top_m:  .word -1

//loading global variable into x21
adrp x28, top_m
add x28, x28, :lo12:top_m
ldr x21, [x28]

//checking value of global variable, it does not branch to exit_stackEmpty
cmp     x21, -1
b.eq    exit_stackEmpty

//but if I compare with a local variable then it does branch
mov x23, -1
cmp     x23, -1
b.eq    exit_stackEmpty

EDIT: In gdb it shows this for x21 and x23

x21 0xffffffff       4294967295 //after loading -1 to x21
x23 0xffffffffffffffff       -1 //after mov x23, -1 

Upvotes: 2

Views: 1151

Answers (1)

Notlikethat
Notlikethat

Reputation: 20924

The data that you're loading is from a .word directive, and thus is 32 bits - 0xffffffff. If you then load 64 bits from that address you get 0x00000000ffffffff, which indeed is not a 64-bit -1 however you look at it. Incidentally, that load also runs off the end of the data section, which is a bad idea, but does means you'll happen to get zeros in the MSBs (or a segfault) - if you had more data following top_m, it would be more obvious what's happening.

If you want to load a 32-bit word and sign-extend it to 64 bits, use the "load a 32-bit word and sign-extend it to 64 bits" instruction: LDRSW.

Upvotes: 2

Related Questions