请修改代码,当输入非法指令如40000000000时会报错。现在输入非法指令只会显示halt
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.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)
{
fopen_s(&pFile, "./test2.txt", "r");
}
else
{
fopen_s(&pFile, 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"
// 假设 'instruction' 是一个字节数组,表示指令
switch (instruction[0]) {
case 0x00:
if (strcmp(buffer, "halt") == 0) {
printf("halt\n");
}
else {
printf("Error: invalid input for opcode 00\n");
}
break;
case 0x10:
printf("nop\n");
break;
case 0x20:
printf("rrmovl %s, %s\n", register_names[instruction[1] >> 4], register_names[instruction[1] & 0x0F]);
break;
case 0x21:
printf("cmovle %s, %s\n", register_names[instruction[1] >> 4], register_names[instruction[1] & 0x0F]);
break;
case 0x22:
printf("cmovl %s, %s\n", register_names[instruction[1] >> 4], register_names[instruction[1] & 0x0F]);
break;
case 0x23:
printf("cmove %s, %s\n", register_names[instruction[1] >> 4], register_names[instruction[1] & 0x0F]);
break;
case 0x24:
printf("cmovne %s, %s\n", register_names[instruction[1] >> 4], register_names[instruction[1] & 0x0F]);
break;
case 0x25:
printf("cmovge %s, %s\n", register_names[instruction[1] >> 4], register_names[instruction[1] & 0x0F]);
break;
case 0x26:
printf("cmovg %s, %s\n", register_names[instruction[1] >> 4], register_names[instruction[1] & 0x0F]);
break;
case 0x30:
printf("irmovl $%d, %s\n", *(int32_t*)(instruction + 2), register_names[instruction[1] & 0x0F]);
break;
case 0x40:
// 注意 "%s, %d(%s)" 中寄存器的顺序已经调整
printf("rmmovl %s, %d(%s)\n", register_names[instruction[1] >> 4], *(int32_t*)(instruction + 2), register_names[instruction[1] & 0x0F]);
break;
case 0x50:
// 注意 "%d(%s), %s" 中寄存器的顺序已经调整
printf("mrmovl %d(%s), %s\n", *(int32_t*)(instruction + 2), register_names[instruction[1] & 0x0F], register_names[instruction[1] >> 4]);
break;
case 0x70:
printf("jmp %d\n", *(int32_t*)(instruction + 1));
break;
case 0x71:
printf("jle %d\n", *(int32_t*)(instruction + 1));
break;
case 0x72:
printf("jl %d\n", *(int32_t*)(instruction + 1));
break;
case 0x73:
printf("je %d\n", *(int32_t*)(instruction + 1));
break;
case 0x74:
// 错误:这个应该是jne,而不是jge
printf("jne %d\n", *(int32_t*)(instruction + 1));
break;
case 0x75:
// 错误:这个应该是jge,而不是jg
printf("jge %d\n", *(int32_t*)(instruction + 1));
break;
case 0x76:
// 添加缺失的jg指令
printf("jg %d\n", *(int32_t*)(instruction + 1));
break;
case 0x80:
printf("call %d\n", *(int32_t*)(instruction + 1));
break;
case 0xC0:
// 错误:应该是jmp,而不是jne
printf("jmp %d\n", *(int32_t*)(instruction + 1));
break;
case 0x60:
printf("addl %s, %s\n", register_names[instruction[1] >> 4], register_names[instruction[1] & 0x0F]);
break;
case 0x61:
printf("subl %s, %s\n", register_names[instruction[1] >> 4], register_names[instruction[1] & 0x0F]);
break;
case 0x62:
printf("andl %s, %s\n", register_names[instruction[1] >> 4], register_names[instruction[1] & 0x0F]);
break;
case 0x63:
printf("xorl %s, %s\n", register_names[instruction[1] >> 4], register_names[instruction[1] & 0x0F]);
break;
case 0x90:
printf("ret\n");
break;
case 0xA0:
printf("pushl %s\n", register_names[instruction[1] >> 4]);
break;
case 0xB0:
printf("popl %s\n", register_names[instruction[1] >> 4]);
break;
default:
printf("Unknown opcode: 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.
******************************************************************************/
// 修改 convertStrToByteCode 函数
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 = strtoll(str, &endstr, 16);
int numBytes = numHexDigits >> 1;
int byteCount = numHexDigits >> 1;
for (int i = 0; i < numBytes; ++i)
{
// Calculate the shift based on endianness (big-endian assumed here)
unsigned long shift = ((numBytes - 1) - i) << 3;
// Extract each byte and store it in the array
inst[i] = (value >> shift) & 0xFF;
}
// Return the size of the instruction in bytes
return numBytes;
}