20

I was using a disassembler when I came across MOVZ and was a bit confused, since I had only used MOV before.

The ARMv8 ISA manual explains of course all the details, and that MOV is an alias for the other three depending on the context, but maybe someone can provide some rationale here, and give concrete examples to speedup the learning process.

Ciro Santilli
  • 3,693
  • 1
  • 18
  • 44
  • What's your manual? http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0802a/MOVZ.html describes the differences in quite a short way, so I'm kind of confused what you are looking for. – domen Nov 13 '18 at 08:19
  • @domen https://developer.arm.com/docs/ddi0487/latest/arm-architecture-reference-manual-armv8-for-armv8-a-architecture-profile seems a bit better. But I'm guessing it must be there somewhere. – Ciro Santilli Nov 13 '18 at 09:42
  • I think I don't understand your question. `movz - Move shifted 16-bit immediate to register.` Then: `movn - Move inverse of shifted 16-bit immediate to register.` How much shorter do you want it? – domen Nov 13 '18 at 10:00
  • @domen one could explain the encoding of immediate to new users I think, and show why we need the three encoding types. – Ciro Santilli Nov 13 '18 at 10:36
  • @Close voters: can you explain rationale? There are thousands of assembly questions on SO, so it seems like a well established topic. You should likely open a meta post instead to decide once and for all for all of them instead of close-voting one by one. – Ciro Santilli Nov 16 '18 at 07:01
  • Was not one of the voters, but I think the rationale would be that questions reads like a request to do work (summarise, test maybe) instead of you rather then a genuine specific question. – domen Nov 16 '18 at 13:39
  • @domen OK, thanks for feedback. – Ciro Santilli Nov 16 '18 at 18:31

1 Answers1

35

MOV

This instruction can take many forms, depending on the value needed to be moved. And it changes if the value is a register or if it is an immediate. If it is in a register, then it produces an ORR instruction (ORR <Xd>, XZR, <Wm>)*. If it is using the SP (Stack Pointer) it produces an ADD instruction (ADD <Xd|XSP>, <Xn|XSP>, #0)*. If moving an immediate, then it is one of the MOVZ, MOVK or MOVN instructions.

*These are the 64-bit prototypes. XZR is the zero register and its value is always zero. The XZR and the SP share are identified by the same number (31), that is why an ORR instruction cannot be used when the SP is the destination or an operand. Instead the ADD instruction is used.

MOVZ and MOVK

These two instructions are sometimes used one after the other. And they are used to move immediate values. MOVZ moves an immediate value (16-bit value) to a register, and all the other bits outside the immediate value are set to Zero. The immediate can be shifted to the left 0, 16, 32 or 48. MOVK moves an immediate value but leaves the other bits of the register untouched (the K is for keep). For example, let's say you need to move this value 0x7fb7fb1f88 to register x0. First, you will move the first 16 bits (bits 0 to 15) with a MOVZ instruction, so the rest bits of the register are set to zero. And then you will move the second 16 bits (bits 16 to 31) with a MOVK instruction, so the value moved before (the first 16 bits) remains in the register, and you do the same with the other resting bits.

      instruction                     value of x0
mov    x0, #0x1f88           |        0x1f88
movk   x0, #0xb7fb, lsl #16  |        0xb7fb1f88
movk   x0, #0x7f, lsl #32    |        0x7fb7fb1f88 

MOVN

MOVN is usually used for moving bitmasks, here the N stands for negated. Let's say you want to move the bitmask 0xffffffff0000ffff to x0. Then you will move 0xffff shifted to the left 16, that will make the value 0x00000000ffff0000. Negating this values becomes 0xffffffff0000ffff.

Here is an example:

      instruction                     value of x0
MOVN x0, 0xFFFF, lsl 16       |       0xffffffff0000ffff
BrodieG
  • 51,669
  • 9
  • 93
  • 146
Capybara
  • 1,313
  • 8
  • 12