<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>zlfn.space</title>
      <link>https://zlfn.space</link>
      <description></description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://zlfn.space/en/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Fri, 10 Apr 2026 00:00:00 +0000</lastBuildDate>
      <item>
          <title>Computer Architecture and RISC-V</title>
          <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://zlfn.space/en/blog/computer-architecture-riscv/</link>
          <guid>https://zlfn.space/en/blog/computer-architecture-riscv/</guid>
          <description xml:base="https://zlfn.space/en/blog/computer-architecture-riscv/">&lt;p&gt;Let&#x27;s explore computer architecture and the structure of RISC-V CPUs.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The content of this post is based on POSTECH&#x27;s CSED311 course,&lt;br &#x2F;&gt;
supplemented with some additional topics not covered in class.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h1 id=&quot;what-is-architecture&quot;&gt;What is Architecture?&lt;&#x2F;h1&gt;
&lt;p&gt;Computer architecture is the interface specification between hardware and software.
Specifically, it defines the following aspects, centered around the Instruction Set Architecture (ISA) that the CPU understands:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Instructions: What operations (addition, branching, memory access, etc.) are supported and in what format they are expressed&lt;&#x2F;li&gt;
&lt;li&gt;Registers: How many registers there are, how many bits each holds, and what each is used for&lt;&#x2F;li&gt;
&lt;li&gt;Memory model: Address space size, byte order (endianness)&lt;&#x2F;li&gt;
&lt;li&gt;Exception&#x2F;Interrupt handling: How errors and external events are handled&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Architecture&lt;&#x2F;strong&gt; is an &lt;strong&gt;abstraction layer&lt;&#x2F;strong&gt; that remains the same regardless of the actual hardware implementation. As long as a compiler generates code conforming to this specification, the code will run on any chip that implements that architecture. Therefore, even if the manufacturers differ, users can run the same OS and applications as long as the architecture is the same. (Think of AMD and Intel x86-64 CPUs.)&lt;&#x2F;p&gt;
&lt;p&gt;On the other hand, &lt;strong&gt;microarchitecture&lt;&#x2F;strong&gt; is the internal design that implements the &quot;contract&quot; of an architecture in actual hardware. Optimizations and implementation details such as pipelines, out-of-order execution, and branch prediction fall under the microarchitecture.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;types-of-architecture&quot;&gt;Types of Architecture&lt;&#x2F;h2&gt;
&lt;p&gt;The main types of computer architecture include von Neumann architecture, Harvard architecture, and dataflow architecture, among others.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;von-neumann-architecture&quot;&gt;Von Neumann Architecture&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Von Neumann architecture&lt;&#x2F;strong&gt; is the fundamental computer structure proposed by John von Neumann, and it forms the foundation of nearly all general-purpose computers today. Computers before the von Neumann architecture (such as ENIAC) required physically rewiring to change programs.&lt;&#x2F;p&gt;
&lt;p&gt;At the time, Mauchly and Eckert, who developed ENIAC, conceived the idea of storing both programs and data in the same memory while designing the successor computer EDVAC. This approach had the advantage that simply loading a program into memory allowed different tasks to be performed with a single set of wiring. (Later, von Neumann distributed a report summarizing this idea as the sole author, which is how this structure came to be named the von Neumann architecture.)&lt;&#x2F;p&gt;
&lt;p&gt;The von Neumann architecture executes programs by having the CPU repeatedly fetch instructions from memory, decode them, and execute them. Since instructions and data share the same memory and the same data bus, no matter how fast the CPU is, performance is limited by memory bandwidth — this is known as the Von Neumann Bottleneck. For this reason, while modern CPUs are based on the von Neumann architecture, they do not use the traditional von Neumann structure as-is, but rather combine it appropriately with the Harvard architecture described below.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;harvard-architecture&quot;&gt;Harvard Architecture&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Harvard architecture&lt;&#x2F;strong&gt; is an architecture that originated from Harvard University&#x27;s Mark I computer around the same time as the von Neumann architecture. Since the Mark I read instructions from punched tape and data from mechanical counters separately, unlike the von Neumann architecture, it has a structure where instruction memory and data memory are physically completely separated.&lt;&#x2F;p&gt;
&lt;p&gt;The Harvard architecture separates the buses for instructions and data, allowing instructions and data to be read simultaneously, which provides higher throughput. However, the capacity between the two memories cannot be flexibly divided, and a separate mechanism is needed to transfer programs to instruction memory. In modern times, the Harvard architecture is used in some fields such as microcontrollers (like the AVR found in Arduino) and DSPs (Digital Signal Processors).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;modified-harvard-architecture&quot;&gt;Modified Harvard Architecture&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Modified Harvard architecture&lt;&#x2F;strong&gt; is a compromise between the von Neumann and Harvard architectures, adopted by most modern CPUs. At the L1 cache level, the I-cache and D-cache are separated to gain the benefit of high bandwidth from the Harvard architecture, while the memory below that level is unified to maintain the flexibility of the von Neumann architecture. From the CPU&#x27;s perspective, since the L1 cache memory is separated into instruction and data portions, it operates like a Harvard architecture; but from the perspective of compilers and programmers, who do not directly manage the cache, the computer can be treated as having a single address space.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;dataflow-architecture&quot;&gt;Dataflow Architecture&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Dataflow architecture&lt;&#x2F;strong&gt; is a fundamentally different architectural paradigm from the Harvard or von Neumann architectures described above. In the von Neumann approach, a program counter sequentially specifies the &quot;next instruction to execute.&quot; Dataflow architecture was designed to break free from the limitation of sequential instruction execution in the von Neumann approach, and it has no program counter.
In a dataflow architecture, instructions execute immediately once all required data is ready, without a program counter sequentially specifying which instruction to perform. Rather than having the programmer or hardware determine the order of program execution, the data itself determines the flow of execution.&lt;&#x2F;p&gt;
&lt;p&gt;In a dataflow architecture, a program is represented not as a sequential list of instructions, but as a directed graph. When performing an operation like &lt;code&gt;(a + b) * (c - d)&lt;&#x2F;code&gt;, the addition node and subtraction node have no dependency on each other, so they execute simultaneously. When the results of both operations arrive at the multiplication node, the multiplication operation fires. Even without the programmer explicitly specifying parallel operations, all operations are automatically executed in parallel.&lt;&#x2F;p&gt;
&lt;p&gt;The dataflow architecture, which first appeared in the 1970s, was actively researched as a next-generation computer in the 1980s-1990s, but failed to become commercially viable due to various limitations. The operations required for dataflow architecture were very expensive in hardware, there were difficulties in handling large-scale data structures, and all existing software infrastructure was written assuming a sequential execution model — these were compounding problems.&lt;&#x2F;p&gt;
&lt;p&gt;Pure dataflow computers have now disappeared, but the ideas continue to live on to the present day. The out-of-order execution (OoO) structure within the von Neumann model and circuit design in FPGAs carry on the design philosophy of dataflow architecture. Recently, AI accelerator processors have been reapplying dataflow principles to hardware, and although dataflow architecture was never commercialized as a general-purpose computing machine, research continues on using dataflow architecture in various special-purpose hardware.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;isa&quot;&gt;ISA&lt;&#x2F;h2&gt;
&lt;p&gt;ISA stands for &lt;strong&gt;Instruction Set Architecture&lt;&#x2F;strong&gt;, and can be described as the interface between software and hardware. The ISA determines the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;What operations exist in the instruction set, and what the encoding format of each instruction is&lt;&#x2F;li&gt;
&lt;li&gt;What data types the hardware directly supports, and what the byte order is (little-endian, big-endian)&lt;&#x2F;li&gt;
&lt;li&gt;Register organization, including the number of registers, their bit widths, and their purposes&lt;&#x2F;li&gt;
&lt;li&gt;Addressing modes and how instructions specify the location of operands&lt;&#x2F;li&gt;
&lt;li&gt;The address space size of the memory model&lt;&#x2F;li&gt;
&lt;li&gt;Under what conditions (division by zero, page fault, illegal instruction) exceptions occur, and how interrupts are handled&lt;&#x2F;li&gt;
&lt;li&gt;Privilege levels, the distinction between protected mode&#x2F;kernel mode, the range of registers and instructions accessible in each mode, and virtual memory-related aspects&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;On the other hand, the ISA does not specify matters related to the microarchitecture beneath it (clock speed, pipeline stages, cache structure, etc.) or software layer conventions (ABI, memory map, firmware interface).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Programmer Visible State&lt;&#x2F;strong&gt; refers to all hardware state that a programmer (compiler) can directly read or write through instructions in the ISA. The semantics of a program are defined by changes to these states. Specifically, this includes general-purpose registers, the program counter, the stack pointer, flag registers, and the entire memory address space.&lt;&#x2F;p&gt;
&lt;p&gt;Conversely, invisible state (microarchitectural state) includes cache contents, branch predictor history, reorder buffer, reservation station, physical register file, TLB entries, and so on. These only affect performance and do not change the logical results of a program.&lt;&#x2F;p&gt;
&lt;p&gt;For any chip implementing the same ISA, as long as changes to the &lt;strong&gt;Programmer Visible State&lt;&#x2F;strong&gt; are identical, the implementation is correct, and all other internal state is free to differ.&lt;&#x2F;p&gt;
&lt;p&gt;The instructions provided by an ISA can be classified by function as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Arithmetic&#x2F;Logical&lt;&#x2F;strong&gt;: Performs operations on registers or immediate values. Results are typically stored in a register, and flags may be updated as a side effect.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Data Transfer&#x2F;Memory&lt;&#x2F;strong&gt;: Moves data between registers and memory, or between registers.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Control Flow&lt;&#x2F;strong&gt;: Changes the program counter to alter the flow of execution. This includes unconditional jumps, conditional branches, function calls&#x2F;returns, and so on.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;System&#x2F;Privileged&lt;&#x2F;strong&gt;: Instructions for OS or hardware control. This includes entering the kernel from user mode, interrupt control, and so on. In modern microprocessors, most such instructions can only be executed in kernel mode, and executing them in user mode causes an exception.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These instructions must be executed &lt;strong&gt;atomically&lt;&#x2F;strong&gt;. A single instruction may change multiple Programmer Visible States, but these intermediate changes must not be exposed to the programmer. In actual hardware, instructions may be processed in stages within a pipeline — writing to a register first and updating the PC later — but this is microarchitectural state, not Programmer Visible State.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;history-of-the-isa&quot;&gt;History of the ISA&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;edsac&quot;&gt;EDSAC&lt;&#x2F;h3&gt;
&lt;p&gt;EDSAC was one of the first stored-program computers and had a very simple ISA.&lt;&#x2F;p&gt;
&lt;p&gt;An instruction consisted of a 5-bit opcode + a reserved bit + a 10-bit memory address (n), using a single accumulator structure. There was only one register, the Acc, and all operations revolved around this Acc register. Examples of instructions include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A n: Adds &lt;code&gt;M[n]&lt;&#x2F;code&gt; to &lt;code&gt;ACC&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;T n: Moves the contents of &lt;code&gt;ACC&lt;&#x2F;code&gt; to &lt;code&gt;M[n]&lt;&#x2F;code&gt; and clears ACC&lt;&#x2F;li&gt;
&lt;li&gt;E n: If &lt;code&gt;ACC&amp;gt;=0&lt;&#x2F;code&gt;, jumps to &lt;code&gt;M[n]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;I n: Reads the next character from tape and stores it at the address pointed to by &lt;code&gt;M[n]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Z  : Halts the program and rings the bell&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A notable characteristic is that all memory addresses are hardcoded in instructions. However, this leads to the following problems:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;When executing a function in code, the function must return to the call site.
However, since EDSAC has return addresses hardcoded in instructions,
it was difficult to specify the return address when calling the same function from multiple locations.&lt;&#x2F;li&gt;
&lt;li&gt;When accessing array elements, since array addresses are hardcoded in instructions,
iterating through an array in a loop required modifying the instruction itself each time to change the address.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;evolution-of-the-isa&quot;&gt;Evolution of the ISA&lt;&#x2F;h3&gt;
&lt;p&gt;To solve these problems, subsequent CPUs evolved in various ways.&lt;&#x2F;p&gt;
&lt;p&gt;First, register architecture evolved from using only a single accumulator register to adding registers for program address specification, and in the modern era, multiple general-purpose registers (GPR, General Purpose Register) have been added so that any register can be used for any purpose.&lt;&#x2F;p&gt;
&lt;p&gt;Second, instructions gained the ability to specify various operands. A structure like EDSAC where an instruction has an implicit operand (ACC) and only one explicit operand is called &lt;strong&gt;Monadic&lt;&#x2F;strong&gt;; a structure like &lt;code&gt;OP inout, in2&lt;&#x2F;code&gt; where there are 2 operands and one of the inputs is overwritten with the result is called &lt;strong&gt;Dyadic&lt;&#x2F;strong&gt;; and a structure like &lt;code&gt;OP out, in1, in2&lt;&#x2F;code&gt; that explicitly specifies both the output and two inputs is called &lt;strong&gt;Triadic&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In CISC architectures described below, a single instruction like &lt;code&gt;ADD [mem], reg&lt;&#x2F;code&gt; can perform both memory access and computation simultaneously, whereas RISC architectures restrict memory access to load&#x2F;store instructions only. (load-store architecture)&lt;&#x2F;p&gt;
&lt;p&gt;Third, instructions gained the ability to specify various memory addresses.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Absolute&lt;&#x2F;strong&gt; - &lt;code&gt;LD rt, 100&lt;&#x2F;code&gt;: The address is specified as a constant in the instruction, like EDSAC.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Register Indirect&lt;&#x2F;strong&gt; - &lt;code&gt;LD rt, (r_base)&lt;&#x2F;code&gt;: Uses the value in a register as the address. Pointer dereferencing works this way.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Displaced&lt;&#x2F;strong&gt; - &lt;code&gt;LD rt, offset(r_base)&lt;&#x2F;code&gt;: Creates an address by adding a constant offset to the register value. Useful for struct access.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Indexed&lt;&#x2F;strong&gt; - &lt;code&gt;LD rt, (r_base, r_index)&lt;&#x2F;code&gt;: Creates an address by adding two register values.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Memory Indirect&lt;&#x2F;strong&gt; - &lt;code&gt;LD rt, ((r_base))&lt;&#x2F;code&gt;: Reads a value from a memory address and uses that value as an address again. This corresponds to double pointer dereferencing.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Auto increment&#x2F;decrement&lt;&#x2F;strong&gt; - &lt;code&gt;LDR rt, (r_base)&lt;&#x2F;code&gt;: Uses the register value as an address, but automatically increments&#x2F;decrements the register value before or after access. Useful for sequentially traversing arrays.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;the-emergence-of-risc&quot;&gt;The Emergence of RISC&lt;&#x2F;h3&gt;
&lt;p&gt;Early CPU development progressed by making the initially simple ISA increasingly complex, adding various features to the instruction set. At the time, programming directly in assembly was common, and adding diverse instructions could simplify the programmer&#x27;s coding work. Additionally, since memory size and performance were limited, it was useful to process frequently-used complex operations in a single step.&lt;&#x2F;p&gt;
&lt;p&gt;However, as compiler technology advanced, cases where programmers directly used complex assembly instructions became rare. The complex instructions designed for human use were difficult for compilers to optimize, and since execution time and memory access counts varied wildly between instructions, it was also difficult to design efficient pipelines.&lt;&#x2F;p&gt;
&lt;p&gt;Against this backdrop, RISC (Reduced Instruction Set Computer) emerged. RISC CPUs were built with the philosophy of keeping the instruction set simple — all instructions the same size, memory access only through designated instructions, simple individual instructions but with a generous number of registers. RISC shifted complexity from hardware to the compiler, making the hardware simple while delegating optimization burden to the now-advanced compilers.&lt;&#x2F;p&gt;
&lt;p&gt;RISC made pipelines easier to build and was advantageous for increasing clock speeds. Since the hardware was simple, transistors could be invested in areas that help performance such as caches and branch predictors, and verification, debugging, and design cycles were shorter.&lt;&#x2F;p&gt;
&lt;p&gt;In contrast to RISC, pre-RISC architectures (x86, M68K, Z80, etc.) are called CISC (Complex Instruction Set Computer). While many CISC architectures like M68K and Z80 disappeared, x86 survived due to its massive software ecosystem. Instead, it adopted a compromise of maintaining a CISC external ISA while internally being RISC, introducing a design where complex instructions are decomposed into RISC operations internally within the CPU.&lt;&#x2F;p&gt;
&lt;p&gt;A leading representative of modern RISC architectures is ARM. ARM initially penetrated the emerging mobile market quickly, leveraging high performance-per-watt through simple design. Until the 2020s, RISC architectures were used in low-power designs such as mobile and embedded systems, while CISC architectures were used in workstation, desktop, and server environments that required high performance at the cost of higher power consumption.&lt;&#x2F;p&gt;
&lt;p&gt;However, this situation was largely reversed after Apple Silicon released the M1 chip in the 2020s. Apple&#x27;s M1 and other ARM CPUs, as RISC architecture-based CPUs, have been rapidly growing market share with high performance and improved performance-per-watt compared to CISC CPUs. Beyond Apple, ARM-based Windows&#x2F;Linux laptops are now being sold, and RISC architectures are gradually expanding their share beyond the mobile market.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;risc-v&quot;&gt;RISC-V&lt;&#x2F;h1&gt;
&lt;p&gt;RISC-V is an open-source ISA that started at UC Berkeley in 2010. It was designed from scratch as a clean RISC ISA without legacy, incorporating lessons learned over the past 30 years since RISC-I and RISC-II, the first RISC processors designed in 1981. (The V stands for the fifth RISC design developed at Berkeley: RISC-I, RISC-II, SOAR, SPUR, RISC-V.)&lt;&#x2F;p&gt;
&lt;p&gt;Unlike ARM and x86 which are tied to specific companies, anyone can freely build processors implementing the RISC-V ISA, and startups, universities, and large corporations can all freely design chips. Additionally, it was developed using a modular design — rather than a single monolithic ISA, it has a small ISA with a minimal set of instructions to which necessary extensions are attached.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;programmer-visible-state-of-risc-v&quot;&gt;Programmer Visible State of RISC-V&lt;&#x2F;h2&gt;
&lt;p&gt;RISC-V has 32 integer general-purpose registers by default, from x0 to x31. x0 is always fixed at 0, because fixing x0 to 0 allows various operations to be expressed using existing instructions, thereby reducing the number of instruction types needed. (For example, NOP can be expressed as &lt;code&gt;ADDI x0, x0, 0&lt;&#x2F;code&gt;, and loading an immediate value as &lt;code&gt;ADDI x1, x0, 42&lt;&#x2F;code&gt;.)&lt;&#x2F;p&gt;
&lt;p&gt;Additionally, there is a PC register that is not included in the general-purpose registers, as well as floating-point registers included in the F&#x2F;D extensions that provide floating-point operations.&lt;&#x2F;p&gt;
&lt;p&gt;Memory uses byte addressing, and is little-endian by default. Every byte of memory is Programmer Visible State, and little-endian alignment is used by default.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;risc-v-extension-system&quot;&gt;RISC-V Extension System&lt;&#x2F;h2&gt;
&lt;p&gt;RISC-V has a structure where necessary extensions are combined with a small base ISA.&lt;&#x2F;p&gt;
&lt;p&gt;The base ISAs are as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;RV32I&lt;&#x2F;strong&gt;: 32-bit integer base. Contains only the minimal instructions for integer arithmetic&#x2F;logic, load&#x2F;store, etc.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;RV64I&lt;&#x2F;strong&gt;: 64-bit integer base. Adds 64-bit operations and doubleword instructions to RV32I.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;RV128I&lt;&#x2F;strong&gt;: 128-bit integer base. However, since it is still unclear when an address space larger than 64 bits would be needed, the specification has not been fully frozen yet.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;RV32E&lt;&#x2F;strong&gt;, &lt;strong&gt;RV64E&lt;&#x2F;strong&gt;: Reduced ISA for embedded use, cutting registers from 32 to 16 to lower the cost of ultra-small microcontrollers.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The following standard extensions exist:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;M&lt;&#x2F;strong&gt;: Integer multiplication and division: Adds native integer multiplication instructions such as &lt;code&gt;MUL&lt;&#x2F;code&gt;, &lt;code&gt;MULH&lt;&#x2F;code&gt; using a hardware multiplier. On ultra-small embedded devices, multiplication and division can be replaced with other operations like bit manipulation without hardware multiplication, which is why multiplication and division are in a separate extension.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;A&lt;&#x2F;strong&gt;: Atomic operations: Instructions for inter-core memory sharing in multi-core environments. Defines functionality for atomically performing reads and writes to memory, reserving memory, etc.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;F&lt;&#x2F;strong&gt;: 32-bit floating-point operations: Adds hardware floating-point operations via the FPU. Adds 32 floating-point registers f0-f31 and the fcsr flag that records the results of floating-point operations.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;D&lt;&#x2F;strong&gt;, &lt;strong&gt;Q&lt;&#x2F;strong&gt;: Add 64-bit double-precision floating-point and 128-bit quadruple-precision floating-point operation instructions, respectively.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;C&lt;&#x2F;strong&gt;: Enables encoding of frequently used instructions in 16 bits. This can reduce code size, making it useful in embedded environments where flash memory size is severely constrained.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;V&lt;&#x2F;strong&gt;: Vector extension. Supports various vector operations similar to SIMD.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;H&lt;&#x2F;strong&gt;: Hypervisor extension. Supports the virtualization layer provided by hypervisors.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In addition to single-letter extensions, there are also more fine-grained extensions prefixed with Z:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Zicsr&lt;&#x2F;strong&gt;: CSR access instructions&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Zifencei&lt;&#x2F;strong&gt;: Instruction cache synchronization, ensures I-Cache and D-Cache coherence for self-modifying code and JIT compilation&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Zba&lt;&#x2F;strong&gt;, &lt;strong&gt;Zbb&lt;&#x2F;strong&gt;, &lt;strong&gt;Zbc&lt;&#x2F;strong&gt;, &lt;strong&gt;Zbs&lt;&#x2F;strong&gt;: Address computation acceleration, basic bit manipulation, carry-less multiplication, and other detailed bit manipulation instructions&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Zfinx&lt;&#x2F;strong&gt;: Performs floating-point operations in integer registers&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Ztso&lt;&#x2F;strong&gt;: Guarantees Total Store Ordering memory model. Useful for x86 binary translation&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Zicond&lt;&#x2F;strong&gt;: Conditional operations. Conditionally selects values without branching&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Because there are so many extensions, &lt;strong&gt;RISC-V profiles&lt;&#x2F;strong&gt; exist that bundle frequently used extensions for software compatibility.
For example, &lt;strong&gt;RVA20U64&lt;&#x2F;strong&gt; is defined to mandatorily include the I, M, A, F, D, C, Zicsr, and Zifencei extensions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;risc-v-instruction-formats&quot;&gt;RISC-V Instruction Formats&lt;&#x2F;h2&gt;
&lt;p&gt;RISC-V defines 6 basic instruction formats. In RV32I, all are 32 bits of fixed length, and the positions of opcode, rd, rs1, and rs2 are arranged as consistently as possible across formats to simplify decoding.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;r-type&quot;&gt;R-Type&lt;&#x2F;h3&gt;
&lt;p&gt;Used for register-to-register operations.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[31:25]  [24:20]  [19:15]  [14:12]  [11:7]  [6:0]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;funct7   rs2      rs1      funct3   rd      opcode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7 bits   5 bits   5 bits   3 bits   5 bits  7 bits&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Operates on two source registers rs1 and rs2, and stores the result in rd. &lt;code&gt;funct7&lt;&#x2F;code&gt; and &lt;code&gt;funct3&lt;&#x2F;code&gt; distinguish the specific type of operation.&lt;&#x2F;p&gt;
&lt;p&gt;Example: &lt;code&gt;ADD x1, x2, x3&lt;&#x2F;code&gt;: x1 &amp;lt;- x2 + x3&lt;&#x2F;p&gt;
&lt;h3 id=&quot;i-type&quot;&gt;I-Type&lt;&#x2F;h3&gt;
&lt;p&gt;Used for immediate value operations, loads, JALR, etc.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[31:20]     [19:15]  [14:12]  [11:7]  [6:0]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;imm[11:0]   rs1      funct3   rd      opcode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;12 bits     5 bits   3 bits   5 bits  7 bits&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The 12-bit immediate value is sign-extended before use. This is the R-type format with the &lt;code&gt;funct7&lt;&#x2F;code&gt; and &lt;code&gt;rs2&lt;&#x2F;code&gt; fields replaced by the immediate value.&lt;&#x2F;p&gt;
&lt;p&gt;Example: &lt;code&gt;ADDI x1, x2, 10&lt;&#x2F;code&gt;: x1 &amp;lt;- x2 + 10&lt;&#x2F;p&gt;
&lt;p&gt;Since &lt;code&gt;funct7&lt;&#x2F;code&gt; is absent compared to R-type, there are some instruction differences. For example, ADD&#x2F;SUB which are distinguished by &lt;code&gt;funct7&lt;&#x2F;code&gt; in R-type — in I-type, SUB is unnecessary since negative immediate values can be used instead, and there are cases where the immediate field is split to distinguish sub-instructions.
(In RV32I, shift instructions like SLLI, SRLI, and SRAI, which need at most 5 bits for the immediate value, use the upper 7 bits as an instruction specifier and the remaining 5 bits as the shift immediate value.)&lt;&#x2F;p&gt;
&lt;p&gt;Load instructions that fetch values from memory are also I-Type, with &lt;code&gt;0000011&lt;&#x2F;code&gt; in the &lt;code&gt;opcode&lt;&#x2F;code&gt; field to indicate a Load, &lt;code&gt;rs1&lt;&#x2F;code&gt; as the base, and the 12-bit &lt;code&gt;imm&lt;&#x2F;code&gt; as the offset. Depending on &lt;code&gt;funct3&lt;&#x2F;code&gt;, these are distinguished into &lt;code&gt;LW&lt;&#x2F;code&gt; which reads 32 bits, &lt;code&gt;LH&lt;&#x2F;code&gt; which reads 16 bits with sign extension, &lt;code&gt;LHU&lt;&#x2F;code&gt; which reads 16 bits with zero extension, &lt;code&gt;LB&lt;&#x2F;code&gt; which reads 8 bits, &lt;code&gt;LBU&lt;&#x2F;code&gt;, and so on.&lt;&#x2F;p&gt;
&lt;p&gt;Also, immediate values are always limited to 12 bits. Immediate values used in programs are typically small values, and cases requiring large constants are usually rare, so this is an intentional design for optimization. When large constants are absolutely necessary, they can be constructed using U-type instructions or AUIPC, described below. This follows the RISC philosophy of not trying to do everything with a single instruction, but instead solving problems with combinations of simple instructions.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;s-type&quot;&gt;S-Type&lt;&#x2F;h3&gt;
&lt;p&gt;Used for storing values to memory.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[31:25]   [24:20]  [19:15]  [14:12]  [11:7]   [6:0]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;imm[11:5] rs2      rs1      funct3   imm[4:0] opcode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7 bits    5 bits   5 bits   3 bits   5 bits   7 bits&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Since results are not written to a register, there is no &lt;code&gt;rd&lt;&#x2F;code&gt;; instead, the lower bits of the immediate go in the &lt;code&gt;rd&lt;&#x2F;code&gt; position, and the upper bits of the immediate go in the &lt;code&gt;funct7&lt;&#x2F;code&gt; position.&lt;&#x2F;p&gt;
&lt;p&gt;Example: &lt;code&gt;SW x3, 12(x2)&lt;&#x2F;code&gt;: &lt;code&gt;MEM[x2 + 12]&lt;&#x2F;code&gt; &amp;lt;- x3&lt;&#x2F;p&gt;
&lt;h3 id=&quot;b-type-sb-type&quot;&gt;B-Type (SB-Type)&lt;&#x2F;h3&gt;
&lt;p&gt;Used for conditional branches.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[31]     [30:25]    [24:20]  [19:15]  [14:12]  [11:8]   [7]     [6:0]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;imm[12]  imm[10:5]  rs2      rs1      funct3   imm[4:1] imm[11] opcode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1 bit    6 bits     5 bits   5 bits   3 bits   4 bits   1 bit   7 bits&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Similar to S-Type, but with a different immediate bit arrangement. The immediate is used as a branch offset, and since RISC-V instructions are aligned to at least 16-bit boundaries, the least significant bit of the branch offset is always 0 and is not encoded. Therefore, a branch range of 13 bits is possible.&lt;&#x2F;p&gt;
&lt;p&gt;Example: &lt;code&gt;BEQ x1, x2, offset&lt;&#x2F;code&gt;: If &lt;code&gt;x1 == x2&lt;&#x2F;code&gt;, then PC &amp;lt;- PC + offset&lt;&#x2F;p&gt;
&lt;p&gt;The reason the bit arrangement is peculiarly scrambled is to share as many bit positions as possible with S-type to simplify hardware. Due to this similarity with S-Type, B-Type is also sometimes called SB-Type.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;u-type&quot;&gt;U-Type&lt;&#x2F;h3&gt;
&lt;p&gt;Instructions that use a 20-bit upper immediate value.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[31:12]     [11:7]  [6:0]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;imm[31:12]  rd      opcode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;20 bits     5 bits  7 bits&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The 20-bit immediate is placed in the upper 20 bits, and the lower 12 bits are filled with 0. Since I-Type instructions can use immediate values of up to 12 bits, this instruction was created to complement that limitation.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;LUI&lt;&#x2F;strong&gt; (Load Upper Immediate): rd &amp;lt;- imm &amp;lt;&amp;lt; 12, used in combination with ADDI to create large constants. To create &lt;code&gt;0x12345678&lt;&#x2F;code&gt;, &lt;code&gt;LUI x1, 0x12345&lt;&#x2F;code&gt; fills the upper 20 bits, and &lt;code&gt;ADDI x1, x1, 0x678&lt;&#x2F;code&gt; fills the lower 12 bits.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;AUIPC&lt;&#x2F;strong&gt; (Add Upper Immediate to PC): rd &amp;lt;- PC + (imm &amp;lt;&amp;lt; 12), used for PC-relative address calculation, and can create addresses within a +&#x2F;-2GB range from the current position when combined with JAL and load.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;j-type-uj-type&quot;&gt;J-Type (UJ-Type)&lt;&#x2F;h3&gt;
&lt;p&gt;Used for unconditional jumps.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[31]     [30:21]    [20]     [19:12]    [11:7]  [6:0]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;imm[20]  imm[10:1]  imm[11]  imm[19:12] rd      opcode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1 bit    10 bits    1 bit    8 bits     5 bits  7 bits&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Uses a 20-bit immediate as a jump offset, and like B-Type, bit 0 is always 0 so it is not encoded. Therefore, a jump range of 21 bits (+&#x2F;-1MB) is possible.&lt;&#x2F;p&gt;
&lt;p&gt;Similar to B-Type, it is designed to share as many bit positions as possible with U-Type. Hence it is also sometimes called UJ-Type.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rv32i-instruction-set&quot;&gt;RV32I Instruction Set&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;integer-arithmetic-logic-r-type&quot;&gt;Integer Arithmetic&#x2F;Logic (R-type)&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Instruction&lt;&#x2F;th&gt;&lt;th&gt;Operation&lt;&#x2F;th&gt;&lt;th&gt;Description&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ADD rd, rs1, rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- rs1 + rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Addition&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SUB rd, rs1, rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- rs1 - rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Subtraction&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;AND rd, rs1, rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- rs1 &amp;amp; rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Bitwise AND&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;OR rd, rs1, rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- rs1 | rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Bitwise OR&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;XOR rd, rs1, rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- rs1 ^ rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Bitwise XOR&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SLL rd, rs1, rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- rs1 &amp;lt;&amp;lt; rs2[4:0]&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Logical left shift&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SRL rd, rs1, rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- rs1 &amp;gt;&amp;gt; rs2[4:0]&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Logical right shift (zero-fill)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SRA rd, rs1, rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- rs1 &amp;gt;&amp;gt;&amp;gt; rs2[4:0]&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Arithmetic right shift (sign-preserving)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SLT rd, rs1, rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- (rs1 &amp;lt; rs2) ? 1 : 0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Signed comparison&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SLTU rd, rs1, rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- (rs1 &amp;lt; rs2) ? 1 : 0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Unsigned comparison&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;immediate-arithmetic-logic-i-type&quot;&gt;Immediate Arithmetic&#x2F;Logic (I-type)&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Instruction&lt;&#x2F;th&gt;&lt;th&gt;Operation&lt;&#x2F;th&gt;&lt;th&gt;Description&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ADDI rd, rs1, imm&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- rs1 + sext(imm)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Immediate addition&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ANDI rd, rs1, imm&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- rs1 &amp;amp; sext(imm)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Immediate AND&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ORI rd, rs1, imm&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- rs1 | sext(imm)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Immediate OR&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;XORI rd, rs1, imm&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- rs1 ^ sext(imm)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Immediate XOR&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SLLI rd, rs1, shamt&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- rs1 &amp;lt;&amp;lt; shamt&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Immediate logical left shift&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SRLI rd, rs1, shamt&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- rs1 &amp;gt;&amp;gt; shamt&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Immediate logical right shift&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SRAI rd, rs1, shamt&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- rs1 &amp;gt;&amp;gt;&amp;gt; shamt&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Immediate arithmetic right shift&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SLTI rd, rs1, imm&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- (rs1 &amp;lt; sext(imm)) ? 1 : 0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Immediate signed comparison&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SLTIU rd, rs1, imm&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- (rs1 &amp;lt; sext(imm)) ? 1 : 0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Immediate unsigned comparison&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;upper-immediate-u-type&quot;&gt;Upper Immediate (U-type)&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Instruction&lt;&#x2F;th&gt;&lt;th&gt;Operation&lt;&#x2F;th&gt;&lt;th&gt;Description&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LUI rd, imm&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- imm &amp;lt;&amp;lt; 12&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Load upper 20 bits&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;AUIPC rd, imm&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- PC + (imm &amp;lt;&amp;lt; 12)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Add upper 20 bits relative to PC&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;load-i-type&quot;&gt;Load (I-type)&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Instruction&lt;&#x2F;th&gt;&lt;th&gt;funct3&lt;&#x2F;th&gt;&lt;th&gt;Operation&lt;&#x2F;th&gt;&lt;th&gt;Description&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LB rd, imm(rs1)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- sext(MEM8[rs1 + sext(imm)])&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Load byte (sign extension)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LH rd, imm(rs1)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;001&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- sext(MEM16[rs1 + sext(imm)])&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Load halfword (sign extension)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LW rd, imm(rs1)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;010&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- MEM32[rs1 + sext(imm)]&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Load word&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LBU rd, imm(rs1)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;100&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- zext(MEM8[rs1 + sext(imm)])&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Load byte (zero extension)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LHU rd, imm(rs1)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;101&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- zext(MEM16[rs1 + sext(imm)])&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Load halfword (zero extension)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;store-s-type&quot;&gt;Store (S-type)&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Instruction&lt;&#x2F;th&gt;&lt;th&gt;funct3&lt;&#x2F;th&gt;&lt;th&gt;Operation&lt;&#x2F;th&gt;&lt;th&gt;Description&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SB rs2, imm(rs1)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;MEM8[rs1 + sext(imm)] &amp;lt;- rs2[7:0]&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Store byte&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SH rs2, imm(rs1)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;001&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;MEM16[rs1 + sext(imm)] &amp;lt;- rs2[15:0]&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Store halfword&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;SW rs2, imm(rs1)&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;010&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;MEM32[rs1 + sext(imm)] &amp;lt;- rs2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Store word&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;conditional-branches-b-type&quot;&gt;Conditional Branches (B-type)&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Instruction&lt;&#x2F;th&gt;&lt;th&gt;funct3&lt;&#x2F;th&gt;&lt;th&gt;Operation&lt;&#x2F;th&gt;&lt;th&gt;Description&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BEQ rs1, rs2, offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;000&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;if (rs1 == rs2) PC &amp;lt;- PC + offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Branch if equal&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BNE rs1, rs2, offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;001&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;if (rs1 != rs2) PC &amp;lt;- PC + offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Branch if not equal&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BLT rs1, rs2, offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;100&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;if (rs1 &amp;lt; rs2) PC &amp;lt;- PC + offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Signed less than&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BGE rs1, rs2, offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;101&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;if (rs1 &amp;gt;= rs2) PC &amp;lt;- PC + offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Signed greater than or equal&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BLTU rs1, rs2, offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;110&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;if (rs1 &amp;lt; rs2) PC &amp;lt;- PC + offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Unsigned less than&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BGEU rs1, rs2, offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;111&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;if (rs1 &amp;gt;= rs2) PC &amp;lt;- PC + offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Unsigned greater than or equal&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;jumps&quot;&gt;Jumps&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Instruction&lt;&#x2F;th&gt;&lt;th&gt;Type&lt;&#x2F;th&gt;&lt;th&gt;Operation&lt;&#x2F;th&gt;&lt;th&gt;Description&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;JAL rd, offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;J-type&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- PC+4, PC &amp;lt;- PC + offset&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Direct jump (function call)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;JALR rd, rs1, imm&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;I-type&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;rd &amp;lt;- PC+4, PC &amp;lt;- (rs1 + sext(imm)) &amp;amp; ~1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Indirect jump (function return, etc.)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;memory-ordering&quot;&gt;Memory Ordering&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Instruction&lt;&#x2F;th&gt;&lt;th&gt;Description&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;FENCE pred, succ&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Ensures memory access ordering (pred&#x2F;succ: combinations of I, O, R, W)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h3 id=&quot;system-instructions&quot;&gt;System Instructions&lt;&#x2F;h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Instruction&lt;&#x2F;th&gt;&lt;th&gt;Operation&lt;&#x2F;th&gt;&lt;th&gt;Description&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ECALL&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Generates environment call trap&lt;&#x2F;td&gt;&lt;td&gt;System call (OS entry)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;EBREAK&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Generates debug trap&lt;&#x2F;td&gt;&lt;td&gt;Breakpoint&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Previously, the &lt;code&gt;Zicsr&lt;&#x2F;code&gt; and &lt;code&gt;Zifencei&lt;&#x2F;code&gt; extensions were included in RV32I, but they were separated into independent extensions in version 2.1, so currently a total of 40 instructions constitute RV32I.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;risc-v-abi-conventions&quot;&gt;RISC-V ABI Conventions&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;register-conventions&quot;&gt;Register Conventions&lt;&#x2F;h3&gt;
&lt;p&gt;These are recommended register usage conventions for all systems, though they are not enforced at the ISA level. Only &lt;code&gt;x0 = 0&lt;&#x2F;code&gt; is the sole constraint enforced by the ISA; all other registers are equivalent from a hardware perspective. In practice, adherence to these conventions is the role of the ABI and calling convention.&lt;&#x2F;p&gt;
&lt;p&gt;However, since most compilers, operating systems, and debuggers follow these conventions, they should be adhered to except in very special cases such as bare-metal embedded environments that do not use any external libraries.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Register&lt;&#x2F;th&gt;&lt;th&gt;ABI Name&lt;&#x2F;th&gt;&lt;th&gt;Purpose&lt;&#x2F;th&gt;&lt;th&gt;Caller&#x2F;Callee Saved&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;zero&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Always 0 (fixed at ISA level)&lt;&#x2F;td&gt;&lt;td&gt;--&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;ra&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Return Address&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;sp&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Stack Pointer&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x3&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;gp&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Global Pointer&lt;&#x2F;td&gt;&lt;td&gt;--&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x4&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;tp&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Thread Pointer&lt;&#x2F;td&gt;&lt;td&gt;--&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x5&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;t0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Temporary register&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x6&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;t1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Temporary register&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x7&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;t2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Temporary register&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x8&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s0&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;fp&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Saved register &#x2F; Frame Pointer&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x9&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Saved register&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x10&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;a0&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Function argument 1 &#x2F; Return value 1&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x11&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;a1&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Function argument 2 &#x2F; Return value 2&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x12&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;a2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Function argument 3&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x13&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;a3&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Function argument 4&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x14&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;a4&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Function argument 5&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x15&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;a5&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Function argument 6&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x16&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;a6&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Function argument 7&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x17&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;a7&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Function argument 8&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x18&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s2&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Saved register&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x19&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s3&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Saved register&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x20&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s4&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Saved register&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x21&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s5&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Saved register&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x22&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s6&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Saved register&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x23&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s7&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Saved register&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x24&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s8&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Saved register&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x25&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s9&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Saved register&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x26&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s10&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Saved register&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x27&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;s11&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Saved register&lt;&#x2F;td&gt;&lt;td&gt;Callee&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x28&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;t3&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Temporary register&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x29&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;t4&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Temporary register&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x30&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;t5&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Temporary register&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;x31&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;t6&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Temporary register&lt;&#x2F;td&gt;&lt;td&gt;Caller&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
</description>
      </item>
      <item>
          <title>Tree Rerooting (All-Direction Tree DP)</title>
          <pubDate>Fri, 12 Apr 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://zlfn.space/en/blog/rerooting/</link>
          <guid>https://zlfn.space/en/blog/rerooting/</guid>
          <description xml:base="https://zlfn.space/en/blog/rerooting/">&lt;p&gt;I looked into Tree DP — specifically All-Direction Tree (全方位木) DP — after seeing it used in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;atcoder.jp&#x2F;contests&#x2F;abc348&quot;&gt;AtCoder ABC #348&lt;&#x2F;a&gt;&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;atcoder.jp&#x2F;contests&#x2F;abc348&#x2F;tasks&#x2F;abc348_e&quot;&gt;E - Minimize Sum of Distance&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This algorithm is called &lt;strong&gt;Rerooting&lt;&#x2F;strong&gt; outside of Japan, and is a useful technique for finding the optimal root in an unrooted tree. In Korea it&#x27;s treated as a subcategory of dynamic programming on trees, but abroad it seems to appear frequently enough in competitive programming to have its own name.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;concept&quot;&gt;Concept&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;tree-dfs&quot;&gt;Tree DFS&lt;&#x2F;h3&gt;
&lt;p&gt;First, let&#x27;s think about how to find the &lt;strong&gt;total edge cost to all other nodes&lt;&#x2F;strong&gt; from a specific node. This can be implemented in $O(n)$ using DFS+DP.
&lt;img src=&quot;https:&#x2F;&#x2F;zlfn.space&#x2F;en&#x2F;blog&#x2F;rerooting&#x2F;IMG_0140.png&quot; alt=&quot;IMG_0140&quot; title=&quot;IMG_0140&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rerooting&quot;&gt;Rerooting&lt;&#x2F;h3&gt;
&lt;p&gt;So how can we find the node with the &lt;strong&gt;smallest total edge cost to all other nodes&lt;&#x2F;strong&gt;? We could use the tree DFS described above for each node, but that would take $O(n^2)$ and would time out once the number of vertices exceeds $10^5$.&lt;br &#x2F;&gt;
This is exactly when we use the &lt;strong&gt;rerooting technique&lt;&#x2F;strong&gt;. It exploits the fact that moving the root of a DFS+DP tree can be done in $O(1)$.&lt;&#x2F;p&gt;
&lt;p&gt;In the figure above, let&#x27;s calculate B&#x27;s total distance sum using A&#x27;s total distance sum of 30. The distances from A and the nodes beyond it — A(0), C(3), F(7) — increase by the cost of the A-B edge (5), becoming A(5), C(8), F(12). The distances from B and the nodes below it — B(5), D(8), E(7) — decrease by the A-B edge cost (5), becoming B(0), D(3), E(2). Since A&#x27;s increase and B&#x27;s decrease cancel out:&lt;br &#x2F;&gt;
&lt;code&gt;(A&#x27;s total distance) - {(nodes beyond A) - (nodes below B)} * (A-B edge cost)}&lt;&#x2F;code&gt; gives us B&#x27;s total distance sum.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;zlfn.space&#x2F;en&#x2F;blog&#x2F;rerooting&#x2F;IMG_0141.png&quot; alt=&quot;IMG_0141&quot; title=&quot;IMG_0141&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Using this method, when we know A&#x27;s total distance sum, we can compute B&#x27;s total distance sum in $O(1)$.&lt;br &#x2F;&gt;
If you think of this as moving the root, it&#x27;s the rerooting technique; if you think of it as running DFS searching in both directions, it&#x27;s called all-direction tree DP. As with most algorithms, the name doesn&#x27;t really matter.&lt;&#x2F;p&gt;
&lt;p&gt;The number of nodes beyond A and below B can be obtained by &lt;strong&gt;storing the count of subnodes&lt;&#x2F;strong&gt; during the initial DFS that computes A&#x27;s total distance sum. In the example above, &lt;code&gt;A&#x27;s subnode count&lt;&#x2F;code&gt; - &lt;code&gt;B&#x27;s subnode count&lt;&#x2F;code&gt; gives the number of nodes beyond A, and &lt;code&gt;B&#x27;s subnode count&lt;&#x2F;code&gt; directly gives the number of nodes below B.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;examples&quot;&gt;Examples&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;boj-27730-gyeonwoo-and-jiknyeo&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.acmicpc.net&#x2F;problem&#x2F;27730&quot;&gt;BOJ 27730 : Gyeonwoo and Jiknyeo&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;A problem where the above example can be applied directly. Run it on two trees and output the node with the smallest distance sum from both sides.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;boj-7812-central-tree&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.acmicpc.net&#x2F;problem&#x2F;7812&quot;&gt;BOJ 7812 : Central Tree&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Find the central node using rerooting, then run DFS again to output distances from all nodes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;abc-348-e&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;atcoder.jp&#x2F;contests&#x2F;abc348&#x2F;tasks&#x2F;abc348_e&quot;&gt;ABC#348 E&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;This is the problem where I first learned about the rerooting technique. Instead of edge costs, &lt;strong&gt;vertex costs&lt;&#x2F;strong&gt; are given.
That is, &lt;code&gt;(number of edges needed to reach a vertex) * (vertex cost)&lt;&#x2F;code&gt; becomes the edge cost.&lt;br &#x2F;&gt;
This problem can be solved by keeping track of both the vertex cost sum &lt;code&gt;c[x]&lt;&#x2F;code&gt; and the distance sum &lt;code&gt;c[x]*d&lt;&#x2F;code&gt;.
The solution code is below, and please refer to the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;atcoder.jp&#x2F;contests&#x2F;abc348&#x2F;editorial&#x2F;9774&quot;&gt;editorial&lt;&#x2F;a&gt; for the explanation.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;lt;bits&#x2F;stdc++.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;using namespace&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;&quot;&gt; std&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F9E2AF;&quot;&gt;#define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; llint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; long long int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; main&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cin &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    vector&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    vector&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;vector&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; tree&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cin &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tree&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tree&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]].&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    vector&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;llint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        cin &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    vector&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;llint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; sub_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; sub_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    auto&lt;&#x2F;span&gt;&lt;span&gt; dfs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;](&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;auto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; par&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;) -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; pair&amp;lt;llint, llint&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; tree&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;t &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; par&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; continue&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;            auto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; [&lt;&#x2F;span&gt;&lt;span&gt;child_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; child_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            sub_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; child_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            sub_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; child_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        sub_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; sub_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        sub_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span&gt; c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; {&lt;&#x2F;span&gt;&lt;span&gt;sub_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;],&lt;&#x2F;span&gt;&lt;span&gt; sub_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;    };&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; dfs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;dfs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    vector&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;llint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    auto&lt;&#x2F;span&gt;&lt;span&gt; reroot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;    =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;](&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;auto&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; par&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; llint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; par_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;font-style: italic;&quot;&gt; llint&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt; par_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;) -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; sub_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; par_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; t &lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; tree&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;t &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; par&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt; continue&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            llint nc &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; par_sum_c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;                    +&lt;&#x2F;span&gt;&lt;span&gt; sub_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;                    -&lt;&#x2F;span&gt;&lt;span&gt; sub_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            llint nd &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; par_sum_d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;                    +&lt;&#x2F;span&gt;&lt;span&gt; sub_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;                    -&lt;&#x2F;span&gt;&lt;span&gt; sub_sum_d&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; sub_sum_c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;                    +&lt;&#x2F;span&gt;&lt;span&gt; nc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; v&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; nc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; nd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;    };&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt; reroot&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;reroot&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cout &lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&amp;lt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;min_element&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;begin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(),&lt;&#x2F;span&gt;&lt;span&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;end&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;())&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; endl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;see-also&quot;&gt;See Also&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeforces.com&#x2F;topic&#x2F;76681&#x2F;en17&quot;&gt;Codeforces - Rerooting Technique&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nicotina04.tistory.com&#x2F;169&quot;&gt;nicotina04 - Rerooting Technique on Tree&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeforces.com&#x2F;blog&#x2F;entry&#x2F;76150&quot;&gt;Codeforces - Online Query Based Rerooting Technique&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Building a Linux Lab Environment with Docker</title>
          <pubDate>Tue, 29 Aug 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://zlfn.space/en/blog/linux-demo-docker/</link>
          <guid>https://zlfn.space/en/blog/linux-demo-docker/</guid>
          <description xml:base="https://zlfn.space/en/blog/linux-demo-docker/">&lt;p&gt;I was tasked with giving a Linux seminar to junior members of our club. That means I need to set up a lab environment.&lt;&#x2F;p&gt;
&lt;p&gt;Two years ago, the seniors told everyone to install VirtualBox. Last year, I ran the seminar myself and gave each junior an account on my Linux server.&lt;&#x2F;p&gt;
&lt;p&gt;This year, my Linux and virtualization knowledge has grown a lot, and I&#x27;ve &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zlfn.space&#x2F;blog&#x2F;rocky-linux&quot;&gt;cleanly rebuilt my server&lt;&#x2F;a&gt;, so I decided to use virtualization to give everyone their own server.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;googling&quot;&gt;Googling&lt;&#x2F;h3&gt;
&lt;p&gt;Originally I was trying to open multiple containers and set up SSH reverse proxies or jump forwarding, but it was harder than expected. While struggling, I found this post:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;unix.stackexchange.com&#x2F;questions&#x2F;126426&#x2F;replicate-and-isolating-user-environments-on-the-fly&quot;&gt;Replicate and Isolating user environments on the fly&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This was exactly what I wanted, so I decided to modify it to fit my environment.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;creating-the-image&quot;&gt;Creating the Image&lt;&#x2F;h3&gt;
&lt;p&gt;The post above went through the process of modifying a container and turning it back into an image, but that&#x27;s too tedious, so I decided to use a Dockerfile.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;# Dockerfile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;FROM&lt;&#x2F;span&gt;&lt;span&gt; ubuntu:latest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; apt-get update&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; apt-get install -y vim sudo man-db gcc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; yes | unminimize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; useradd -ms &#x2F;bin&#x2F;bash guest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; echo &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;#39;guest:password&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; | chpasswd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;RUN&lt;&#x2F;span&gt;&lt;span&gt; usermod -a -G sudo guest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;USER&lt;&#x2F;span&gt;&lt;span&gt; guest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;WORKDIR&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;home&#x2F;guest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Install the packages needed for the lab: &lt;code&gt;vim&lt;&#x2F;code&gt;, &lt;code&gt;sudo&lt;&#x2F;code&gt;, &lt;code&gt;man-db&lt;&#x2F;code&gt;, &lt;code&gt;gcc&lt;&#x2F;code&gt;, and run &lt;code&gt;unminimize&lt;&#x2F;code&gt; to make &lt;code&gt;man&lt;&#x2F;code&gt; work.&lt;&#x2F;p&gt;
&lt;p&gt;Then create a user called guest so that when you connect to the container, you log in as a user rather than root. This gives a more similar feel to SSH-ing directly into a server.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;docker&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; build --tag sandbox .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Build the image with this command.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;creating-the-user&quot;&gt;Creating the User&lt;&#x2F;h3&gt;
&lt;p&gt;Now create a user so that when they connect via SSH, they enter a fake shell.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;mkdir&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &#x2F;home&#x2F;guest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;cat&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &#x2F;home&#x2F;guest&#x2F;sandbox&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;EOF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;#!&#x2F;bin&#x2F;sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;exec docker run -t -i --rm=true sandbox &#x2F;bin&#x2F;bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;EOF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;chmod&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; +x &#x2F;home&#x2F;guest&#x2F;sandbox&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;font-style: italic;&quot;&gt;# useradd guest -g docker -s &#x2F;home&#x2F;guest&#x2F;sandbox &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;useradd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; guest -s &#x2F;home&#x2F;guest&#x2F;sandbox&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;chown&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; guest &#x2F;home&#x2F;guest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89B4FA;font-style: italic;&quot;&gt;passwd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; guest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Since I&#x27;m using Podman rather than Docker, I didn&#x27;t need to give the user the &lt;code&gt;docker&lt;&#x2F;code&gt; group to run &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;access.redhat.com&#x2F;documentation&#x2F;ko-kr&#x2F;red_hat_enterprise_linux&#x2F;8&#x2F;html&#x2F;building_running_and_managing_containers&#x2F;proc_setting-up-rootless-containers_assembly_starting-with-containers&quot;&gt;Rootless Podman&lt;&#x2F;a&gt;. If you&#x27;re using Docker, you&#x27;ll need to add the &lt;code&gt;docker&lt;&#x2F;code&gt; group.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;--rm=true&lt;&#x2F;code&gt; argument on the &lt;code&gt;docker&lt;&#x2F;code&gt; command ensures the container is deleted immediately when you exit, and the fake shell launches Docker when the user logs in.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;complete&quot;&gt;Complete&lt;&#x2F;h3&gt;
&lt;p&gt;With the above setup, when you SSH in as the &lt;code&gt;guest&lt;&#x2F;code&gt; user, you get trapped in a temporarily created container.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;zlfn.space&#x2F;en&#x2F;blog&#x2F;linux-demo-docker&#x2F;Screenshot_20230829_113449.png&quot; alt=&quot;Screenshot_20230829_113449&quot; title=&quot;Screenshot_20230829_113449&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;(The username differs from what&#x27;s shown on the blog.)&lt;&#x2F;p&gt;
&lt;p&gt;In this environment, you can install as many packages as you want or modify the system (as long as it&#x27;s not kernel-related), and even running &lt;code&gt;sudo rm -rf &#x2F;&lt;&#x2F;code&gt; won&#x27;t affect the host system running the container.&lt;&#x2F;p&gt;
&lt;p&gt;When you log out and log back in, everything is reset and a new container is created — a great environment for practice.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo rm -rf --no-preserve-root &#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Try running this and see that the system doesn&#x27;t break.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2024-07-15-update&quot;&gt;2024.07.15 Update&lt;&#x2F;h3&gt;
&lt;p&gt;With the container setup above, there are issues where the container sometimes doesn&#x27;t get properly deleted on logout, and a Refreshing Error occurs on login.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ERRO[0001] Refreshing container 2e3d121a75ec00add6a35694cdc26e6442bb98a7e993b918569dd7584597bca6: acquiring lock 0 for container 2e3d121a75ec00add6a35694cdc26e6442bb98a7e993b918569dd7584597bca6: file exists&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For the container not being deleted on logout, I added &lt;code&gt;docker stop sandbox&lt;&#x2F;code&gt; to the &lt;code&gt;guest&lt;&#x2F;code&gt; account&#x27;s &lt;code&gt;.bash_logout&lt;&#x2F;code&gt; file — I&#x27;m not 100% sure but it seems to have fixed it.
The error seems to be resolved by enabling lingering mode for the account with &lt;code&gt;loginctl enable-linger guest&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
</description>
      </item>
    </channel>
</rss>
