I'm interested to know what this assembly code do knowing that X1 is full of zeroes.

ori  X2, X0, 0xFFF
slli X2, X2, 12
ori  X2, X2, 0xFFF
slli X2, X2, 8
ori  X2, X2, 0xFF
xor  X2, X2, X1
addi X2, X2, 1
and  X2, X2, X1

The problem is that I don't understand what 0xFFF and 0xFF are. How am I supposed to know their values at all?

  • \$\begingroup\$ This is not a very well posed question, as you do not give any context for the origin of this code. Can someone figure it out? Probably, but omitting such information is just needlessly wasteful of people's time. Additionally, something you have to keep in mind any time you are looking at a disassembly is that it's entirely possible that what you are looking at is not code at all, but rather data being mistakenly disassembled as if it were code. \$\endgroup\$ Commented Dec 27, 2020 at 16:55
  • 1
    \$\begingroup\$ @awjlogan why did you remove the original asker's architecture tag from this question? \$\endgroup\$ Commented Dec 27, 2020 at 16:59
  • 1
    \$\begingroup\$ @ChrisStratton The question was really what does 0xFF mean, rather than anything to do with a specific architecture. But, not a big edit, just came up in the queue :) \$\endgroup\$
    – awjlogan
    Commented Dec 27, 2020 at 20:48

2 Answers 2


These look like instructions for a RISC-V microprocessor.

  • ori is the "OR Immediate" instruction.
  • slli is a "Left Shift Logical Immediate" instruction.
  • xor is an "Exclusive Or" instruction.
  • addi is an "Add Immediate" Instruction.
  • and is a "Bitwise AND instruction".

The problem is that I can't understand what are those 0xFFF and 0xFF how am I supposed to know their values at all?

These are integer literal values written in hexadecimal. The value shown literally is their value. We can guess based on the fact that these are all literal type instructions that the numeric operands are literals rather than a memory address.

  • 0xFF is 11111111 in binary or 255 in decimal.
  • 0xFFF is 111111111111 in binary or 4095 in decimal.

Writing the numbers in hexadecimal improves the readability of the code. Especially because the code contains several bit-wise instructions.

Note that the X0 register is a hardwired zero per page 109 of the "RISC-V User-Level ISA V2.2".

ORI  X2, X0, 0xFFF //X2 <= 1111 1111 1111 1111 1111 1111 1111 1111
SLLI X2, X2, 12    //X2 <= 1111 1111 1111 1111 1111 0000 0000 0000
ORI  X2, X2, 0xFFF //X2 <= 1111 1111 1111 1111 1111 1111 1111 1111
SLLI X2, X2, 8     //X2 <= 1111 1111 1111 1111 1111 1111 0000 0000
ORI  X2, X2, 0xFF  //X2 <= 1111 1111 1111 1111 1111 1111 1111 1111
XOR  X2, X2, X1    //X2 <= 1111 1111 1111 1111 1111 1111 1111 1111
                   //      since it was given that X1 is all 0s.
ADDI X2, X2, 1     //X2 <= 0000 0000 0000 0000 0000 0000 0000 0000
AND  X2, X2, X1    //X2 <= 0000 0000 0000 0000 0000 0000 0000 0000
                   // since X1 was all 0s, the AND operation would
                   // clear X2 no matter what its prior value.
  • 1
    \$\begingroup\$ how did you know that 0xFF isn't location in memory? \$\endgroup\$
    – MrCalc
    Commented Dec 20, 2020 at 23:35
  • 11
    \$\begingroup\$ @MrCalc Because its and "OR Immediate" instruction. An immediate type instruction always uses a literal rather than a memory address or another register value in the operation. A common naming convention is that assembly instructions that end with the letter "I" operate on immediate (literal) values. \$\endgroup\$
    – user4574
    Commented Dec 20, 2020 at 23:44
  • 1
    \$\begingroup\$ What I'm wondering is why someone would go through this six-instruction rigmarole when they could just do xori x2, x2, -1. \$\endgroup\$
    – zwol
    Commented Dec 21, 2020 at 13:42
  • 1
    \$\begingroup\$ @user4574 in the first line, shouldn't all ???? be actually 0000 as per x0 is always 0? \$\endgroup\$
    – Marandil
    Commented Dec 21, 2020 at 14:29
  • 2
    \$\begingroup\$ Actually, I'm now practically sure that x2 should be all-ones after the first instruction, as "ANDI, ORI, XORI are logical operations that perform bitwise AND, OR, and XOR on register rs1 and the sign-extended 12-bit immediate", so 0xFFF would become 0xFFFFFFFF. \$\endgroup\$
    – Marandil
    Commented Dec 21, 2020 at 14:36

If X1 were not 0, then this code would calculate 2^Y, with Y the index of the lowest significant bit of X1, and store it in X2. The first 6 lines are an unnecessarily complicated way to store the one's complement of X1 in X2, the 7th lines adds 1 to that, making X2 the two's complement of X1 (in other words the negation of X1 if X1 were a signed integer in the usual two's-complement-encoding) and the 8th line stores the bitwise logical AND of X2 and X1 in X2.

The bitwise logical AND of a signed integer in two's-complement-encoding and its own negation just happens to be 2^(the index of its least significant bit). I.e. if X1==7==0b111, the output would be 1==2^0 (because the 0th bit was set); if X1==8==0b1000, the output would be 8==2^3 (because the 0th to 2nd bit were not set, but the 3rd bit was); if X1==12=0b1100, the output would be 4==2^2.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.