补完三个部分完成的Y86反汇编程序,使得程序能正确完整地完成反汇编功能,反汇编Y86架构中定义的所有指令。
分任务1:能正确反汇编机器操作码。
要求:输入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
输入
3082CDAB0000
5015F4F- f F f -F f(去除-)
40641C040000
7457C00000
7374500000
803A000000
7074000000
3083F- f F f -F f(去除-)
7570A00000
7274000000
7180000000
7612A00000
00
输出
irmovl
mrmovl
rmmovl
jne
je
call
jmp
irmovl
jge
jl
jle
jg
halt
参考代码
#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.\n");
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;
//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;
}
void disassembleInstruction(unsigned char instruction[], int size)
{
switch (instruction[0])
{
case 0x00: // halt
printf("halt\n");
break;
case 0x10: // nop
printf("nop\n");
break;
case 0x20: // rrmovl
printf("rrmovl\n");
break;
case 0x30: // andl
printf("andl\n");
break;
case 0x40: // xorl
printf("xorl\n");
break;
case 0x50: // mrmovl
printf("mrmovl\n");
break;
case 0x60: // addl
printf("addl\n");
break;
case 0x61: // subl
printf("subl\n");
break;
case 0x62: // andl
printf("andl\n");
break;
case 0x63: // xorl
printf("xorl\n");
break;
case 0x70: // jmp
printf("jmp\n");
break;
case 0x71: // jle
printf("jle\n");
break;
case 0x72: // jl
printf("jl\n");
break;
case 0x73: // je
printf("je\n");
break;
case 0x74: // jne
printf("jne\n");
break;
case 0x75: // jge
printf("jge\n");
break;
case 0x76: // jg
printf("jg\n");
break;
case 0x80: // call
printf("call\n");
break;
case 0x90: // ret
printf("ret\n");
break;
case 0xA0: // pushl
printf("pushl\n");
break;
case 0xB0: // popl
printf("popl\n");
break;
default:
printf("TODO: undisassembled opcode\n");
}
}
分任务2:能正确反汇编寄存器操作数。
输入
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
输入
3082CDAB0000
5015F4F- f F f -F f(去除-)
40641C040000
7457C00000
7374500000
803A000000
7074000000
3083F- f F f -F f(去除-)
7570A00000
7274000000
7180000000
7610A00000
00
输出
irmovl $43981, %edx
mrmovl -12(%ebp), %ecx
rmmovl %esi, 1052(%esp)
jne 49239
je 20596
call 58
jmp 116
irmovl $-1, %ebx
jge 41072
jl 116
jle 128
jg 40976
halt
参考代码
#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);
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.\n");
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)
{
unsigned char opcode = instruction[0] >> 4; // Extract the opcode from the first byte
switch (opcode)
{
case 0x0: // No-operand instructions
switch (instruction[0] & 0xF)
{
case 0x0:
printf("halt\n");
break;
case 0x1:
printf("nop\n");
break;
default:
printf("TODO: undisassembled opcode\n");
break;
}
break;
case 0x1: // RRMOVL
printf("rrmovl %s, %s\n", register_names[(instruction[1] >> 4) & 0x7], register_names[instruction[1] & 0x7]);
break;
// ...
// Part 2: Disassemble register operands
case 0x2: // IRMOVL
printf("irmovl 0x%x, %s\n", *(int*)&instruction[2], register_names[instruction[1] & 0x7]);
break;
case 0x3: // RMMOVL
printf("rmmovl %s, 0x%x(%s)\n", register_names[(instruction[1] >> 4) & 0x7], *(int*)&instruction[2], register_names[instruction[1] & 0x7]);
break;
case 0x4: // MRMOVL
printf("mrmovl 0x%x(%s), %s\n", *(int*)&instruction[2], register_names[instruction[1] & 0x7], register_names[(instruction[1] >> 4) & 0x7]);
break;
// ...
}
}
分任务3:读取y86的二进制编码文件,正确反汇编立即数和存储器地址操作数。
麻烦各位别只复制gpt,那种事情我自己会做