RISC-V Assembler: Logical
In this post we look at RISC-V logical instructions, such as and and xori. These instructions are included in RV32I, the base integer instruction set. New to the assembler series? Check out the first part on RISC-V arithmetic instructions.
In the last few years, we’ve seen an explosion of RISC-V CPU designs, especially on FPGA. Thankfully, RISC-V is ideal for assembly programming with its compact, easy-to-learn instruction set. This series will help you learn and understand 32-bit RISC-V instructions (RV32) and the RISC-V ABI.
Share your thoughts with @WillFlux on Mastodon or Twitter. If you like what I do, sponsor me. 🙏
AND
The and and andi instructions perform logical AND on individual bits (bitwise). The “and” instructions are commonly used to mask parts of a register. Immediates are sign extended, see arithmetic sign extension for details.
and rd, rs1, rs2 # rd = rs1 AND rs2
andi rd, rs, imm # rd = rs AND imm
These examples select the 4 least significant bits from the register t0:
li t0, 42 # t0 = 42 (0...101010)
li t1, 15 # t1 = 15 (0...001111)
and t2, t0, t1 # t2 = 42 (0...101010) AND 15 (0...001111) = 10 (0...001010)
andi t3, t0, 15 # t3 = 42 (0...101010) AND 15 (0...001111) = 10 (0...001010)
Binary values are in brackets with ...
indicating many identical bits.
OR
The or and ori instructions perform logical OR on individual bits.
or rd, rs1, rs2 # rd = rs1 OR rs2
ori rd, rs, imm # rd = rs OR imm
Examples:
li t0, 42 # t0 = 42 (0...101010)
li t1, 15 # t1 = 15 (0...001111)
or t2, t0, t1 # t2 = 42 (0...101010) OR 15 (0...001111) = 47 (0...101111)
ori t3, t0, 15 # t3 = 42 (0...101010) OR 15 (0...001111) = 47 (0...101111)
XOR
The xor and xori instructions perform logical XOR (exclusive OR) on individual bits.
xor rd, rs1, rs2 # rd = rs1 XOR rs2
xori rd, rs, imm # rd = rs XOR imm
Examples:
li t0, 42 # t0 = 42 (0...101010)
li t1, 15 # t1 = 15 (0...001111)
xor t2, t0, t1 # t2 = 42 (0...101010) XOR 15 (0...001111) = 37 (0...100101)
xori t3, t0, 15 # t3 = 42 (0...101010) XOR 15 (0...001111) = 37 (0...100101)
NOT
The not pseudoinstruction inverts the bits in a register (0 → 1
and 1 → 0
). The assembler converts not to an xori instruction (see example below).
not rd, rs # rd = NOT rs (pseudoinstruction)
Example:
li t0, 42 # t0 = 42 (0...101010)
# these two examples generate the same machine code
not t2, t0 # t2 = NOT (0...101010) = (1...010101)
xori t3, t0, -1 # t3 = (0...101010) XOR (1...111111) = (1...010101)
Notice how -1 is sign extended to 32-bits so all the bits of the immediate are 1.
What’s Next?
The next instalment of RISC-V Assembler covers Shift Instructions.
Other parts of this series include: Arithmetic, Load Store, and Branch Set. Or check out my FPGA & RISC-V Tutorials and my series on early Macintosh History.
References
- RISC-V Technical Specifications (riscv.org)