C Lab 3
RISC V Lab 4
Disassembler and Emulator
Goals
Review
Bitfields
Unions
Disassembler and Instruction Parsing
Review
Unions and bit-fields are minor extensions to the struct syntax.
Be aware that code based on either is very system dependent, meaning that it is generally not portable across operating systems, hardware, or both
struct statusReg {
unsigned int emptyPaperTray :1;
unsigned int paperJam :1;
:1;
unsigned int count :5;
:1;
unsigned int lowInk :1;
:1;
unsigned int needsCleaning :1;
:1;
};
Empty paper
Paper jam
Low ink
Clean
count
Review: Unions
In structure every member of structure has its own storage
All members of union uses the single memory location
Just bring up why malloc returns a void *, and how we casted it to a char * for the string manipulation last time.
An Instruction – Union Bitfield
Why union ? – Need to reinterpret or cast 4 bytes read from executable file as different instructions.
Why bitfield ? – Dereference bits within an instruction to understand the instruction.
What is a disassembler?
Input: 0x00000433
to
Output: add x8, x0, x0
Mention that the sequence: malloc, free, malloc, free, … , free
is ok.
What is a disassembler?
void load_program(uint8_t *mem, size_t memsize, int startaddr, const char *filename, int disasm) {
FILE *file = fopen(filename, “r”);
………
while (fgets(line, MAX_SIZE, file) != NULL) {
instruction = (int32_t) strtol(line, NULL, 16);
….
decode_instruction((uint32_t) instruction);
}
Line 50-60 riscv.c
Read program from file, decode 4 bytes at a time.
Mention that the sequence: malloc, free, malloc, free, … , free
is ok.
Live : Types.h
typedef union {
/* access opcode with: instruction.opcode */
struct {
unsigned int opcode : 7;
unsigned int rest : 25;
};
/* access rtype with: instruction.rtype.(opcode|rd|funct3|rs1|rs2|funct7) */
struct {
………
} rtype;
} instruction
Answer: If the memory is found in a separate segment of memory, ptr will now point to invalid memory.
Structs in Instruction Union
Rest
opcode
Disas. R-Type : Overview
Rest
opcode
Input: 0x00000433 (0000 0000 0000 0000 0000 0100 0011 0011)
Disas. R-Type : Get opcode
Utils.c – line 15
instruction_bits: 0x00000433
Instruction parse_instruction(uint32_t instruction_bits)
{
Instruction instruction;
/* YOUR CODE HERE. */
instruction.opcode = instruction_bits & ((1U << 7) - 1);
// Shift right to move to pointer to interpret next fields in instruction.
instruction_bits >>= 7;
……
Rest
Instruction
0x33
opcode
Disas. R-Type : Get Rd
Utils.c – line 31
instruction_bits: 0x00000433
Rest
Instruction
0x33
opcode
// instruction: 0000 0000 0000 0000 0000 destination : 01000
instruction.rtype.rd = instruction_bits & ((1U << 5) - 1);
instruction_bits >>= 5;
0x8 (Rd)
Disas. R-Type : Get funct3
Utils.c – line 31
instruction_bits: 0x00000433
Rest
Instruction
0x33
opcode
// instruction: 0000 0000 0000 0000 0 func3 : 000
instruction.rtype.funct3 = instruction_bits & ((1U << 3) - 1);
instruction_bits >>= 3;
0x8 (Rd)
0x0 (funct3)
Disas. R-Type : Get RS1
Utils.c – line 39
instruction_bits: 0x00000433
Rest
Instruction
0x33
opcode
0x8 (Rd)
0x0 (funct3)
// instruction: 0000 0000 0000 src1: 00000
instruction.rtype.rs1 = instruction_bits & ((1U << 5) - 1);
instruction_bits >>= 5;
0x0 (RS1)
Disas. R-Type : Get RS2
Utils.c – line 39
instruction_bits: 0x00000433
Instruction
0x33
opcode
0x8 (Rd)
0x0 (funct3)
// instruction: 0000 0000 0000 src1: 00000
instruction.rtype.rs1 = instruction_bits & ((1U << 5) - 1);
instruction_bits >>= 5;
0x0 (RS1)
0x0 (RS2)
Disas. R-Type : Get Func7
Utils.c – line 15
instruction_bits: 0x00000433
func7
Instruction
// funct7: 0000 000
instruction.rtype.funct7 = instruction_bits & ((1U << 7) - 1);
0x33
0x8 (Rd)
0x0 (funct3)
0x0 (RS1)
0x0 (RS2)