0

I run into a roadblock and not sure where to go from here. I know MOV can only store a maximum of 0-65535 in decimal. However, the value I'm trying to store is 30,402,460.

I was going to use MVN as some source mention that can store bigger number in this format: MVN X9, #(num), #(num). However 30402460 / 110 = only equals 276,386 which is still above the decimal value of 65535 so I can't use MVN.

My question is; how do we store 30402460 to X9?

KojTug
  • 351
  • 1
  • 8
  • You are not running with 16-bit processing; your tag says "arm64". 65535 is the largest unsigned 16 bit integer. Looking here:https://developer.arm.com/documentation/100076/0100/a64-instruction-set-reference/a64-general-instructions/mov--to-or-from-sp-?lang=en, MOV handles 32 or 64 bits. So I am not sure I understand your question. – Basya Jul 01 '21 at 11:11
  • I am not familiar with that site. What really matters is how it works on your hardware. – Basya Jul 01 '21 at 15:21
  • I see... I’ll get back to you on this. As I mention I tried mov x9, #30402460 with no luck. Tried with add x9, x9, #30402460. The resource that you listed there mention it’s an alternative to the add instruction. – KojTug Jul 01 '21 at 16:00
  • That could be done by loading values from memory pool `ldr x9, =30402460`. About loading by `MOVZ`, `MOVK`, `MOVN` you could read elaborated answer of @Peter Cordes here: https://stackoverflow.com/questions/55112772/lower16-upper16-for-aarch64-absolute-address-into-register – user3124812 Jul 03 '21 at 00:06

1 Answers1

1

MOV is not a real instruction. It's an alias that will be turned into either MOVK, MOVN or ORR as appropriate. But each of those have their own constraints:

  • MOVZ can load an arbitrary 16 bits, left-shifted by 0, 16, 32 or 48 bits. So you can only use this for values with 48 bits of all zeroes.
  • MOVN does the same as MOVZ, but inverts the register value. So you can only use this for values with at least 48 bits of all ones.
  • ORR can construct a really complicated bitmask which, as best as I can tell, can be any sequence of consecutive runs of zeroes, ones, zeroes or ones, zeroes, ones, repeated by any power of two that is a dividend of the register width. So you can load values like 0xaaaaaaaaaaaaaaaa, 0xfffffff00fffffff and 0x18, but not values like 0x0 or 0x5.

The value 30402460 matches none of these constraints. The usual practice for loading such values is to use MOVZ followed by MOVK, the latter of which allows replacing 16 bits of a register without changing the other bits. So in your case:

movz x9, 0x1cf, lsl 16
movk x9, 0xe79c
Siguza
  • 21,155
  • 6
  • 52
  • 89