|
1.0 UNC miniRISCV Processor Architecture
The UNC miniRISCV is a simple 32-bit processor with 32 registers, and a with main
memory size of 2 gigabytes (231),
or 536,870,912 (229) 32-bit words. It
RV32I compliant and includes a subset of RV32M instructions suffcient for supporting
the C programing language. Memory is byte-addressable, and all instructions occupy one
32-bit word (4-bytes) in memory. Byte addresses of are in little-endian order.
The 32 registers are specified as x0-x31. Each register holds a
32-bit value, which can be interpreted a number, a character, or the address of
some of a some variable or object in memory. Register, x0, is special.
When used as a source operand, the contents of x0 are always 0, and all
updates of x0, when used as a destination, are ignored.
Program execution begins at location 0x80000000 in kernel mode. However, the
program must first be assembled (converted from its symbolic representation to a
sequence of 32-bit words in memory) before it can be executed. If there are
errors in the assembly process, a dialog box will pop up explaining the error.
2.0 Introduction to UNC miniRISCV Assembly Language
A typical line of assembly code specifies a single primitive operation, called
an instruction, and its operands.
The list of all UNC miniRISCV operations (its instruction set) is enumerated
in section 3.
In assembly language instructions are specified via short mneumonics
of the operation specified (usually either abbreviations of acronymns).
A list of comma-separated operands follows each instruction's mneumonic.
The assembler uses this mneumonic and operand list to generate a
binary encoding of the instruction, which is stored as a word in memory.
Thus, an assembly language program is merely a way of generating a sequence
of binary words, that the computer interprets as either (or both) program or data.
To make this discussion concrete, consider the following example line of assembly
code:
|
add |
x3,x4,x4 |
# "add" is the instruction mneumonic |
|
|
|
# "x3,x4,x4" is a list of 3 operands |
Generally, he first operand specifies the destination (output) of the operation,
and subsequent operands specify source (input) operands.
This instruction given tells miniRISCV to add the contents register 4 to
itself and store the result in register 3.
Empty lines are ignored by the assembler (they generate no output to memory),
but they are often used to enhance readability.
Any text following a "#" is considered a comment and the remainder of the line
is ignored by the assembler.
Comments are used to document the intent of the code beyond what is evident from
the instruction specification alone.
Optionally, any line of assembly code can start with a label.
A label is a sequence of characters followed by a colon (":"), which it is
usually a meaningful name.
A label provides a means for referencing the memory location that a particular
instruction or variable is stored at. Instruction labels are often used to specify
targets for branch instuctions. In the case of data, a label might represent
a variable name.
An example using label is shown below:
|
loop: |
addi |
x3,x3,-1 |
# loop is a label |
|
|
bne |
x0,x3,loop |
# here the label is referenced |
The UNC miniRISCV assembler provides a small set of assembler directives,
that are used like instructions.
All assembler directives are prefixed with a "." (period) and they are
generally used for allocating space for data and initializing variables.
A complete list of assembler directives is given in section 4.
Examples are given below.
|
Fib: |
.word |
1,1,2,3,5,8,13,21 |
# first 8 Fibonacci numbers |
|
masks: |
.word |
0x000000ff,0x0000ff00,0x00ff0000,0xff000000 |
# byte masks |
|
Name: |
.string |
"Leonard" |
# 0-terminated string (8 bytes) |
|
array: |
.space |
20 |
# 20 uninitialized words |
The UNC miniRISCV assembler also provides special support for simulation.
Any line of assembly code beginning with an "*" (asterix) will
act as a breakpoint causing the simulator to halt
prior to the execution of the instruction following the mark, or
after marked data is accessed via either a load or store instruction.
One or more breakpoints can be set, and at least one is required to
use the "Run" button.
2.0 UNC miniRISCV Instruction Formats
All RISC-V RV32I instructions are encoded in one of 4 formats:
3.0 UNC miniRISCV Instruction Set
Note: For "Encoding" the bits of rd are shown as d, bits of rs1 are
are s, and bits of rs2 are t.
Math Instructions
- ADD: add registers
-
Syntax:
add rd,rs1,rs2
Encoding: 0000 000t tttt ssss s000 dddd d011 0011
Description:
Reg[rd] ← Reg[rs1] + Reg[rs2]
Add the contents of registers Reg[rs1] and Reg[rs2], and place
the result in Reg[rd]. Overflows are ignored.
Example: add x6,x2,x0 # Encoded as: 0x00010333
- ADDI: add immediate
-
Syntax:
addi rd,rs1,imm12
Encoding: iiii iiii iiii ssss s000 dddd d001 0011
Description:
Reg[rd] ← Reg[rs1] + sign_extend(imm12)
Add a 12-bit sign-extended constant to the contents of Reg[rs1],
and place the result in Reg[rd]. Overflows are ignored.
Example: addi x6,x6,100 # Encoded as: 0x06430313
- SUB: subtract registers
-
Syntax:
sub rd,rs1,rs2
Encoding: 0100 000t tttt ssss s000 dddd d011 0011
Description:
Reg[rd] ← Reg[rs1] - Reg[rs2]
Subtract the contents of Reg[rs2] from Reg[rs1], and place
the result in Reg[rd]. Overflows are ignored.
Example:sub x16,x0,x12 # Encoded as: 0x40C00833
- MUL: multiply registers
-
Syntax:
mul rd,rs1,rs2
Encoding: 0000 001t tttt ssss s000 dddd d011 0011
Description:
Reg[rd] ← Reg[rs1] * Reg[rs2]
Multiply the contents of Reg[rs1] and Reg[rs2], and place
the lower 32-bits of the product in Reg[rd]. Overflows are ignored.
MUL is binary and semantically compliant with the RV32M mul instruction.
Example:mul x5,x6,x7 # Encoded as: 0x027302B3
- DIV: divide registers
-
Syntax:
div rd,rs1,rs2
Encoding: 0000 001t tttt ssss s100 dddd d011 0011
Description:
Reg[rd] ← Reg[rs1] / Reg[rs2]
Divide the contents of Reg[rs1] by Reg[rs2], and place
the quotient in Reg[rd]. A divisor of 0 does not generate an
overflow, and the destination register rd is set to all ones.
DIV is binary and semantically compliant with the RV32M div instruction.
Example:div x7,x5,x6 # Encoded as: 0x0262C3B3
- REM: remainder of a register quotient
-
Syntax:
rem rd,rs1,rs2
Encoding: 0000 001t tttt ssss s110 dddd d011 0011
Description:
Reg[rd] ← Reg[rs1] % Reg[rs2]
Divide the contents of Reg[rs1] by Reg[rs2], and place
the remainder in Reg[rd]. A divisor of 0 does not generate an
overflow and the contents of the destination register rd is set to the dividend, Reg[rs1].
REM is binary and semantically compliant with the RV32M rem instruction.
Example:rem x7,x5,x6 # Encoded as: 0x0262E3B3
- SLT: set if less than
-
Syntax:
slt rd,rs1,rs2
Encoding: 0000 000t tttt ssss s010 dddd d011 0011
Description:
Reg[rd] ← 1 if (Reg[rs1] < Reg[rs2]); 0 otherwise
Set Reg[rd] to '1' if the contents of Reg[rs1] is
less than the contents of Reg[rs2].
Example:slt x17,x18,x19 # Encoded as: 0x013928B3
- SLTU: set if less than unsigned
-
Syntax:
sltu rd,rs1,rs2
Encoding: 0000 000t tttt ssss s011 dddd d011 0011
Description:
Reg[rd] ← 1 if (Reg[rs1] < Reg[rs2]); 0 otherwise
Set Reg[rd] to '1' if the contents of Reg[rs1] is less than
the contents of Reg[rs2]. Both operands (Reg[rs1] and Reg[rs2])
are compared as unsigned integers.
Example:sltu x20,x21,x22 # Encoded as: 0x016ABA33
- SLTI: set if less than immediate
-
Syntax:
slti rd,rs1,imm12
Encoding: iiii iiii iiii ssss s010 dddd d001 0011
Description:
Reg[rd] ← 1 if (Reg[rs1] < sign_extend(imm12)); 0 otherwise
Set Reg[rd] to '1' if the contents of Reg[rs1] is less than
the supplied sign-extended immediate value.
Example:slti x6,x2,10 # Encoded as: 0x00A12313
- SLTIU: set if less than immediate unsigned
-
Syntax:
sltiu rd,rs1,imm12
Encoding: iiii iiii iiii ssss s011 dddd d001 0011
Description:
Reg[rd] ← 1 if (Reg[rs1] < sign_extend(imm16)); 0 otherwise
Set Reg[rd] to '1' if the contents of Reg[rs1] is less than
the supplied sign-extended immediate value. Both arguments are treated as
unsigned integers (despite the sign extension... go figure?).
Example:sltiu x2,x6,0xfff # Encoded as: 0xFFF33113
- AUIPC: Add Upper Immediate to Program Counter
-
Syntax:
auipc rd,label
Encoding: iiii iiii iiii iiii iiii dddd d001 0111
Description:
Reg[rd] ← PC + (sign_extend(imm20)) >> 12
This instruction supports position-independent code. It adds a 20-bit immediate value
(shifted left by 12 bits) to the program counter (pc) and stores the result in Reg[rd].
It's often used with a subsequent addi to load the address of a variable into a register.
Example:here: auipc x1,label # Encoded as: 0x00812583
Logic Instructions
- AND: bitwise-and registers
-
Syntax:
and rd,rs1,rs2
Encoding: 0000 000t tttt ssss s111 dddd d011 0011
Description:
Reg[rd] ← Reg[rs1] & Reg[rs2]
Performs a "bitwise" anding of the contents of registers Reg[rs1] and Reg[rs2]
and places the result in Reg[rd]. The and instruction is commonly used to mask or clear bits.
Example: and x6,x2,x3 # Encoded as: 0x00317333
- ANDI: bitwise-and with immediate
-
Syntax:
andi rd,rs1,imm12
Encoding: iiii iiii iiii ssss s111 dddd d001 0011
Description:
Reg[rd] ← Reg[rs1] & sign_extend(imm12)
Performs a "bitwise" anding of the contents of Reg[rs1] with the
given sign-extended 12-bit constant and places the result in Reg[rd].
The andi instruction is commonly used to mask or clear bits.
Example: andi x6,x2,255 # Encoded as: 0x0FF17313
- OR: bitwise or registers
-
Syntax:
or rd,rs1,rs2
Encoding: 0000 000t tttt ssss s110 dddd d011 0011
Description:
Reg[rd] ← Reg[rs1] | Reg[rs2]
Performs a "bitwise" oring of the contents of Reg[rs1] with Reg[rs2],
and place the result in Reg[rd].
The or instruction is commonly used to set bits.
Example:or x4,x4,x5 # Encoded as: 0x00526233
- ORI: bitwise or with immediate
-
Syntax:
ori rd,rs1,imm12
Encoding: iiii iiii iiii ssss s110 dddd d001 0011
Description:
Reg[rd] ← Reg[rs1] | sign_extend(imm12)
Performs a "bitwise" oring of the contents of Reg[rs1] with
the given sign-extended 12-bit constant and place the result in Reg[rs2].
The ori instruction is commonly used to set bits.
Example:ori x12,x11,0xbcd # Encoded as: 0xBCD5E613
- XOR: bitwise exclusive or registers
-
Syntax:
xor rd,rs1,rs2
Encoding: 0000 000t tttt ssss s100 dddd d011 0011
Description:
Reg[rd] ← Reg[rs1] ^ Reg[rs2]
Perform a "bitwise" exclusive-or of the contents of Reg[rs1] with Reg[rs2]),
and place the result in Reg[rd].
The xor instruction is commonly used to complement bits.
Example:xor x6,x9,x10 # Encoded as: 0x00A4C333
- XORI: bitwise exclusive-or with immediate
-
Syntax:
xori rd,rs1,imm12
Encoding: iiii iiii iiii ssss s100 dddd d001 0011
Description:
Reg[rd] ← Reg[rs1] ^ sign_extend(imm12)
Performs a "bitwise" exclusive-oring of the contents of Reg[rs1] with
the sign-extended 12-bit constant and places the result in Reg[rs2].
The xori instruction is commonly used to complement bits.
Example:xori x6,x12,0xfff # Encoded as: 0xFFF64313
Shift Instructions
- LUI: load upper immediate while filling lower bits with zeros
-
Syntax:
lui rd,imm20
Encoding: iiii iiii iiii iiii iiii dddd d011 0111
Description:
Reg[rd] ← imm20 << 12
Load Reg[rs2] with the given 20-bit constant shifted left by 12 bits.
Vacated bits are filled with 0's. This instruction is frequently followed
by an addi rd,x0,imm12 to initialize a register with a 32-bit
constant. If a label is specified, the upper 20 bits of the absolute address
are used as the constant.
Example: lui sp,0xc0000 # Encoded as: 0xC0000137
- SLL: shift left logical by filling lower bits with zeros
-
Syntax:
slli rd,rs1,imm5
Encoding: 0000 000i iiii ssss s001 dddd d001 0011
Description:
Reg[rd] ← Reg[rs2] << imm5
Shift the contents of Reg[rs2] left the number of positions specified
by the given unsigned constant (0-31) and place the result in
Reg[rd]. Vacated bits are filled with 0's. This instruction is
frequently used to multiply by powers of 2.
Example: slli x6,x10,2 # Encoded as: 0x00251313
- SLL: shift left logical variable; zero-fill lower bits
-
Syntax:
sll rd,rs1,rs2
Encoding: 0000 000t tttt ssss s001 dddd d011 0011
Description:
Reg[rd] ← Reg[rs1] << Reg[rs2]
Shift the contents of Reg[rs1] left the number of positions specified
by the specified by lower 5-bits of Reg[rs2] and place the result in
Reg[rd]. Vacated bits are filled with 0's and the upper 27 bits of Reg[rs2]
are ignored. This instruction is frequently used to multiply by powers of 2.
Example:sll x10,x11,x12 # Encoded as: 0x00C59533
- SRLI: shift right logical filling upper bits with zeros
-
Syntax:
srli rd,rs1,imm5
Encoding: 0000 000i iiii ssss s101 dddd d001 0011
Description:
Reg[rd] ← Reg[rs2] >>> imm5
Shift the contents of Reg[rs2] right the number of positions
specified by the given unsigned constant (0-31). Vacated register
bits are filled with 0's. This instruction can be used to perform unsigned
integer divides by a power of 2.
Example:srli x21,x21,8 # Encoded as: 0x008ADA93
- SRL: shift right logical variable; zero-fill upper bits
-
Syntax:
srl rd,rs1,rs2
Encoding: 0000 000t tttt ssss s101 dddd d011 0011
Description:
Reg[rd] ← Reg[rs2] >>> Reg[rs1]
Shift the contents of Reg[rs2] right the number of positions specified
by the lower 5-bits of Reg[rs1] and place the result in Reg[rd].
Vacated bits are filled with 0's. This instruction is frequently used to
divide unsigned integers by powers of 2.
Example:srl x6,x8,x24 # Encoded as: 0x01845333
- SRAI: shift right arithmetic filling upper-bits with the sign
-
Syntax:
srai rd,rs1,imm5
Encoding: 0100 000i iiii ssss s101 dddd d001 0011
Description:
Reg[rd] ← Reg[rs2] >> imm5
Shift the contents of Reg[rs2] right the number of positions
specified by the given unsigned constant (0-31). Vacated register
bits are filled with copies of the sign bit. An alternate intepretation of
is:
Reg[rd] ← Reg[rs2] / 2imm5
Where the contents of Reg[rd] are treated as a signed integer.
Example:srai x10,x10,24 # Encoded as: 0x41855513
- SRA: shift right variable filling upper-bits with the sign
-
Syntax:
sra rd,rs1,rs2
Encoding: 0100 000t tttt ssss s101 dddd d011 0011
Description:
Reg[rd] ← Reg[rs2] >> Reg[rs1]
Shift the contents of Reg[rs2] right the number of positions specified
by the lower 5-bits of Reg[rs1]. The vacated register bits are filled
with copies of the sign bit.
Example:sra x10,x11,x12 # Encoded as: 0x40C5D533
Memory Access Instructions
- LW: load word
-
Syntax:
lw rd,offset(rs1)
lw rd,offset # implicit rs1 = x0
lw rd,(rs1) # implicit offset = 0
Encoding: iiii iiii iiii ssss s010 dddd d000 0011
Description:
Reg[rd] ← Memory[Reg[rs1]+sign_extend(imm12)]
Load Reg[rd] with the contents of memory at the address given by the
contents of Reg[rs1] plus a sign-extended 12-bit constant.
Example:lw x11,8(x2) # Encoded as: 0x00000297
- LB: load byte
-
Syntax:
lb rd,offset(rs1)
lb rd,offset # implicit rs1 = x0
lb rd,(rs1) # implicit offset = 0
Encoding: iiii iiii iiii ssss s000 dddd d000 0011
Description:
Reg[rd] ← sign_extend(Memory[Reg[rs1]+sign_extend(imm12)])
Loads an 8-bit byte from memory at the calculated address, then sign-extends it to a 32-bit value before storing it in Reg[rd].
Example:lb x10,1(x11)
- LH: load halfword
-
Syntax:
lh rd,offset(rs1)
lh rd,offset # implicit rs1 = x0
lh rd,(rs1) # implicit offset = 0
Encoding: iiii iiii iiii ssss s001 dddd d000 0011
Description:
Reg[rd] ← sign_extend(Memory[Reg[rs1]+sign_extend(imm12)])
Loads a 16-bit halfword from memory at the calculated address, then sign-extends it to a 32-bit value before storing it in Reg[rd].
Example:lh x10,2(x11)
- LBU: load byte unsigned
-
Syntax:
lbu rd,offset(rs1)
lbu rd,offset # implicit rs1 = x0
lbu rd,(rs1) # implicit offset = 0
Encoding: iiii iiii iiii ssss s100 dddd d000 0011
Description:
Reg[rd] ← zero_extend(Memory[Reg[rs1]+sign_extend(imm12)])
Loads an 8-bit byte from memory at the calculated address, then zero-extends it to a 32-bit value before storing it in Reg[rd].
Example:lbu x10,1(x11)
- LHU: load halfword unsigned
-
Syntax:
lhu rd,offset(rs1)
lhu rd,offset # implicit rs1 = x0
lhu rd,(rs1) # implicit offset = 0
Encoding: iiii iiii iiii ssss s101 dddd d000 0011
Description:
Reg[rd] ← zero_extend(Memory[Reg[rs1]+sign_extend(imm12)])
Loads a 16-bit halfword from memory at the calculated address, then zero-extends it to a 32-bit value before storing it in Reg[rd].
Example:lhu x10,2(x11)
- SW: store word
-
Syntax:
sw rs2,offset(rs1)
sw rs2,offset # implicit rs1 = x0
sw rs2,(rs1) # implicit offset = 0
Encoding: iiii iiit tttt ssss s010 iiii i010 0011
Description:
Memory[Reg[s1]+sign_extend(imm12)] ← Reg[rs2]
Save the contents of Reg[rs2] into the memory address given by the
contents of Reg[rs1] plus a sign-extended 12-bit constant.
Example:sw x1,12(x2) # Encoded as: 0x00112623
- SB: store byte
-
Syntax:
sb rs2,offset(rs1)
sb rs2,offset # implicit rs1 = x0
sb rs2,(rs1) # implicit offset = 0
Encoding: iiii iiit tttt ssss s000 iiii i010 0011
Description:
Memory[Reg[rs1]+sign_extend(imm12)] ← Reg[rs2][7:0]
Stores the low-order 8 bits from register Reg[rs2] to memory at the calculated address.
Example:sb x12,3(x11)
- SH: store halfword
-
Syntax:
sh rs2,offset(rs1)
sh rs2,offset # implicit rs1 = x0
sh rs2,(rs1) # implicit offset = 0
Encoding: iiii iiit tttt ssss s001 iiii i010 0011
Description:
Memory[Reg[rs1]+sign_extend(imm12)] ← Reg[rs2][15:0]
Stores the low-order 16 bits from register Reg[rs2] to memory at the calculated address.
Example:sh x12,4(x11)
Branch and Jump Instructions
- BEQ: branch if equal
-
Syntax:
beq rs1,rs2,label
Encoding: iiii iiit tttt ssss s000 iiii i110 0011
Description:
if (Reg[rs1] == Reg[rs2]) {
PC ← PC + sign_extend(offset)
}
If the contents of Reg[rs1] equals the contents of Reg[rs2]
branch to the instruction at the specified by a label.
Example:halt: beq x0,x0,halt # Encoded as: 0x00000063
- BNE: branch if not equal
-
Syntax:
bne rs1,rs2,label
Encoding: iiii iiit tttt ssss s001 iiii i110 0011
Description:
if (Reg[rs1] ≠ Reg[rs2]) {
PC ← PC + sign_extend(offset)
}
If the contents of Reg[rs1] does not equal the contents of
Reg[rs2] branch to the instruction at the specified by a label.
Example:bne x1,x0,skip # Encoded as: 0x14200000
addi x1,x1,1
skip:
- BLT: branch if less than
-
Syntax:
blt rs1,rs2,label
Encoding: iiii iiit tttt ssss s100 iiii i110 0011
Description:
if (Reg[rs1] < Reg[rs2]) {
PC ← PC + sign_extend(offset)
}
Branches to the instruction at the specified label if the signed value in Reg[rs1] is less than the signed value in Reg[rs2].
Example:blt x5,x6,loop_start
- BGE: branch if greater than or equal
-
Syntax:
bge rs1,rs2,label
Encoding: iiii iiit tttt ssss s101 iiii i110 0011
Description:
if (Reg[rs1] ≥ Reg[rs2]) {
PC ← PC + sign_extend(offset)
}
Branches to the instruction at the specified label if the signed value in Reg[rs1] is greater than or equal to the signed value in Reg[rs2].
Example:bge x5,x6,continue
- BLTU: branch if less than, unsigned
-
Syntax:
bltu rs1,rs2,label
Encoding: iiii iiit tttt ssss s110 iiii i110 0011
Description:
if (Reg[rs1] < Reg[rs2]) {
PC ← PC + sign_extend(offset)
}
Branches to the instruction at the specified label if the unsigned value in Reg[rs1] is less than the unsigned value in Reg[rs2].
Example:bltu x5,x6,error_case
- BGEU: branch if greater than or equal, unsigned
-
Syntax:
bgeu rs1,rs2,label
Encoding: iiii iiit tttt ssss s111 iiii i110 0011
Description:
if (Reg[rs1] ≥ Reg[rs2]) {
PC ← PC + sign_extend(offset)
}
Branches to the instruction at the specified label if the unsigned value in Reg[rs1] is greater than or equal to the unsigned value in Reg[rs2].
Example:bgeu x5,x6,success
- JALR: jump and link register
-
Syntax:
jalr rd,offset(rs1)
jalr rd,(rs1) # implicit offset = 0
Encoding: iiii iiii iiii ssss s000 dddd d110 0111
Description:
Reg[rd] ← PC + 4
PC ← (Reg[rs1] + sign_extend(offset)) & ~1
Jump to the instruction given by the contents of (Reg[rs1] + sign_extend(offset)) & ~1, and save
the location of the next instruction in Reg[rd].
Example:jalr x1,(x31) # Encoded as: 0x0020F809
- JAL: jump and link
-
Syntax:
jal rd,offset
Encoding: iiii iiii iiii iiii iiii dddd d110 1111
Description:
Reg[rd] ← PC + 4
PC ← PC + sign_extend(offset)
Jump to the instruction offset from the current instruction by the signed-extended immediate 20-bit constant, which
is usually references a label, and save the location of the next instruction in Reg[rd].
Example:jal x1,main # Encoded as: 0x00C000EF
4.0 Pseudoinstructions
- J: jump
-
Syntax:
j label
Encoding: pseudoinstruction jal x0,label
Description:
PC ← PC + sign_extend(imm20|0)
Jump to the instruction given by 4 times the immediate 26-bit constant, which
is usually references a label.
Example:j 0x00400000 # Encoded as: 0x08100000
- JR: jump register
-
Syntax:
jr rs1
Encoding: pseudoinstruction jalr x0, 0(rs1)
Description:
PC ← Reg[rs1]
Jump to the instruction given by the contents of Reg[rs1].
Example:jr x31 # Encoded as: 0x03e00008
- NEG: negate register
-
Syntax:
neg rd,rs1
Encoding: pseudoinstruction
Description:
Reg[rd] ← -Reg[rs1]
Negates the contents of register Reg[rs1] and places the result in Reg[rd].
Generates an overflow if the sign of the result is the same as the original contents of the source register.
Example: neg x6,x2
- NEGU: negate register and ingore overflows.
-
Syntax:
negu rd,rs1
Encoding: pseudoinstruction
Description:
Reg[rd] ← -Reg[rs1]
Negates the contents of register Reg[rs1] and places the result in Reg[rd]. Overflows are ignored.
Example: negu x6,x2
- NOT: bitwise complement
-
Syntax:
not rd,rs1
Encoding: pseudoinstruction
Description:
Reg[rd] ← ~Reg[rs1]
Performs a "bitwise" complement of the contents of Reg[rs1] and places the result in Reg[rd].
Each '0' is replaced by a '1', and each '1' with a '0';
Example:not x4,x4
- MV: move
-
Syntax:
mv rd,rs1
Encoding: pseudoinstruction addi rd,rs1,0
Description:
Reg[rd] ← Reg[rs1]
Copies the contents of Reg[rs1] to Reg[rd].
Example:mv x1,x4
- LI: load immediate
-
Syntax:
li rd,constant
Encoding: pseudoinstruction
Description:
Reg[rd] ← constant(label)
Loads an immediate constant into Reg[rd]. It will generate either
a one or two instuction sequence depending on the size of the constant:
addi rd, x0, constant .
Example:la x1,y
- LA: load address
-
Syntax:
la rd,label
Encoding: pseudoinstruction
Description:
Reg[rd] ← effective_address(label)
Loads the address of the label into Reg[rd]. It is typically implemented using the
two instruction sequence:
auipc rd, label
addi rd, rd, label .
Example:la x1,y
- SGT: set if greater than
-
Syntax:
sgt rd,rs1,rs2
Encoding: pseudoinstruction
Description:
Reg[rd] ← 1 if (Reg[rs1] > Reg[rs2]); 0 otherwise
Set Reg[rd] to '1' if the contents of Reg[rs1] is
greater than the contents of Reg[rs2].
Example:sgt x17,x18,x19
5.0 Assembler Directives
- .WORD: Specify initialized data
-
Syntax:
.word value1,
value2, ..., valuen
Description:
Successive words in memory are initialized with constant values from the list.
Constants can be decimal numbers, octal numbers prefixed with '0',
hexadecimal numbers prefixed with '0x', or labels, which specify an address.
Example:
.word 10,010,0x10 # Encoded as: 0x0000000a, 0x00000008, 0x00000010
- .SPACE: Specify a block of uninitialized space
-
Syntax:
.space value1,value2, ..., valuen
Description:
Blocks of sizes specified in the list of constant values are reserved.
Constants can be decimal numbers, octal numbers prefixed with '0',
hexadecimal numbers prefixed with '0x', or an address label.
Example:
.space 50 # reserves 50 uninitialized words
- .STRING: Initialize memory with strings
-
Syntax:
.string "string1","string2", ..., "stringn"
Description:
Fills successive memory locations with characters from the given list of
quoted strings, each string is termnated with one or more "0"s. The address
of the first letter of each string is word aligned.
Example:
.string "Tarheels" # Encoded as: 0x54617268, 0x65656C73, 0x00000000
|
|