补完三个部分完成的Y86反汇编程序,使得程序能正确完整地完成反汇编功能,反汇编Y86架构中定义的所有指令。
分任务1:能正确反汇编机器操作码。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int convertStrToByteCode(const char *str, unsigned char inst[], int size);
void disassembleInstruction(unsigned char instruction[], int size);
int main(int argc, char **argv)
{
FILE *pFile = NULL;
char buffer[15];
if (argc < 2)
{
pFile = fopen("./test1.txt", "r");
}
else
{
pFile = fopen(argv[1], "r");
}
if (pFile == NULL)
{
printf("Error open test file, please make sure they exist.");
return 0;
}
while (fgets(buffer, 15, pFile) && strlen(buffer) > 1)
{
unsigned char instruction[6] = {0, 0, 0, 0, 0, 0};
convertStrToByteCode(buffer, instruction, 6);
disassembleInstruction(instruction, 6);
}
fclose(pFile);
return 0;
}
int convertStrToByteCode(const char *str, unsigned char inst[], int size)
{
int numHexDigits = 0;
char *endstr;
numHexDigits = strlen(str) - 1;
long long value = strtol(str, &endstr, 16);
int numBytes = numHexDigits >> 1;
int byteCount = numHexDigits >> 1;
while (byteCount > 0)
{
unsigned long long mask = 0xFF;
unsigned long shift = (numBytes - byteCount) << 3;
inst[byteCount - 1] = (value & (mask << shift)) >> shift;
byteCount--;
}
return numHexDigits >> 1;
}
void disassembleInstruction(unsigned char instruction[], int size)
{
// TODO: Add your implementation here to disassemble the y86 opcodes and display the result.
// For example, you can use a switch statement or an array of function pointers to handle different opcodes.
// If an undisassembled opcode is found, display it as "TODO: undisassembled opcode".
}
要求:输入10
90
6060
6237
6115
6332
2043
2143
2334
2241
2453
2642
2540
A028
A008
B058
00
输出
nop
ret
addl
andl
subl
xorl
rrmovl
cmovle
cmove
cmovl
cmovne
cmovg
cmovge
pushl
pushl
popl
halt
分任务2:能正确反汇编寄存器操作数。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//This is an array of register mnemonics in y86
const char *register_names[] =
{
"%eax",
"%ecx",
"%edx",
"%ebx",
"%esp",
"%ebp",
"%esi",
"%edi",
"UNKNOWN_REGSITER"};
int convertStrToByteCode(const char *str, unsigned char inst[], int size);
int main(int argc, char **argv)
{
FILE *pFile = NULL;
char buffer[15];
if (argc < 2)
{
pFile = fopen("./test1.txt", "r");
}
else
{
pFile = fopen(argv[1], "r");
}
if (pFile == NULL)
{
printf("Error open test file, please make sure they exist.\n");
return 0;
}
while (fgets(buffer, 15, pFile) && strlen(buffer) > 1)
{
//This unsigned char array stores an instruction read from the file
//As the largest y86 instruction is 6 bytes, there are 6 unsigned char in the array where
//each represents a byte.
unsigned char instruction[6] = {0, 0, 0, 0, 0, 0};
convertStrToByteCode(buffer, instruction, 6);
//TODO: From here, your task is to complete the implementation so that all y86 opcode and operands can be disassembled.
//Any undisassembled opcode should display as "TODO: undisassembled opcode and operands"
printf("TODO: undisassembled opcode and operands. The first byte of the instruction is 0x%X\n", instruction[0]);
}
fclose(pFile);
return 0;
}
/****************************************************************************
N.B. You do not need to modify or work in this function.
Description:
This function converts a line of machine code read from the text file
into machine byte code.
The machine code is stored in an unsigned char array.
******************************************************************************/
int convertStrToByteCode(const char *str, unsigned char inst[], int size)
{
int numHexDigits = 0;
char *endstr;
//Each instruction should consist of at most 12 hex digits
numHexDigits = strlen(str) - 1;
//Convert the string to integer, N.B. this integer is in decimal
long long value = strtol(str, &endstr, 16);
int numBytes = numHexDigits >> 1;
int byteCount = numHexDigits >> 1;
while (byteCount > 0)
{
unsigned long long mask = 0xFF;
unsigned long shift = (numBytes - byteCount) << 3;
inst[byteCount - 1] = (value & (mask << shift)) >> shift;
byteCount--;
}
//Return the size of the instruction in bytes
return numHexDigits >> 1;
}
输入
10
90
6060
6237
6115
6332
2043
2143
2334
2241
2453
2642
2540
A028
A008
B058
00
输出
nop
ret
addl %esi, %eax
andl %ebx, %edi
subl %ecx, %ebp
xorl %ebx, %edx
rrmovl %esp, %ebx
cmovle %esp, %ebx
cmove %ebx, %esp
cmovl %esp, %ecx
cmovne %ebp, %ebx
cmovg %esp, %edx
cmovge %esp, %eax
pushl %edx
pushl %eax
popl %ebp
halt
分任务3:读取y86的二进制编码文件,正确反汇编立即数和存储器地址操作数。
#include <stdio.h>
#include <stdlib.h>
//This is the help function that reads y86 binary code from a file
unsigned int loadBinFromFile(const char *filename, unsigned char memory[], unsigned int memsize);
int main(int argc, char **argv)
{
unsigned int MAX_MEMSIZE = 4096;
unsigned char memory[MAX_MEMSIZE]; //This array represents the 4KB memory space
unsigned int PC = 0; //This is the initial program counter address
if (argc < 2)
{
printf("Usage: please specify a y86 binary program file in the argument.\n");
return -1;
}
unsigned int program_size = loadBinFromFile(argv[1], memory, MAX_MEMSIZE);
if (program_size == 0)
return 0;
//TODO: Implement your disassembler from here
//At the moment, it simply display each byte from the memory.
while (PC < program_size)
{
printf("%02X\n", memory[PC]);
PC++;
}
return 0;
}
/****************************************************************************
N.B. You do not need to modify or work in this function.
Description:
This function reads in a y86 machine bytecode from file and
store them in an unsigned char array.
******************************************************************************/
unsigned int loadBinFromFile(const char *filename, unsigned char memory[], unsigned int memsize)
{
unsigned int bytes_read = 0;
unsigned int file_size = 0;
FILE *pfile = fopen(filename, "rb");
if (!pfile)
{
printf("Unable to load file %s, please check if the path and name are correct.\n", filename);
return 0;
}
fseek(pfile, 0, SEEK_END);
file_size = ftell(pfile);
rewind(pfile);
if (file_size > memsize)
{
printf("Program size exceeds memory size of %d.\n", memsize);
return 0;
}
bytes_read = fread(memory, 1, file_size, pfile);
if (bytes_read != file_size)
{
printf("Bytes read does not match the file size.\n");
return 0;
}
fclose(pfile);
return bytes_read;
}