普通网友 2023-12-07 13:41 采纳率: 0%
浏览 28
已结题

用C语言反汇编y86指令

补完三个部分完成的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,那种事情我自己会做

  • 写回答

18条回答 默认 最新

  • 叫兽-郭老师 新星创作者: Java技术领域 2023-12-07 13:42
    关注
    获得1.00元问题酬金

    由人工智能和答主提供,可以参考如下,如果回答的不正确,及时评论区回复,我追加回答,谢谢。


    此问题可以参考threenewbee答主,如果threenewbee不能满足您的要求,请在我的评论区留言回复。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 12月15日
  • 创建了问题 12月7日