普通网友 2023-12-14 11:26 采纳率: 0%
浏览 10
已结题

c程序添加非法指令报错

请修改代码,当输入非法指令如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;
}


  • 写回答

20条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2023-12-14 11:26
    关注
    获得0.45元问题酬金

    引自强大而免费的微信小程序:皆我知道

    1. 在代码中添加输入验证处理 在程序中添加输入验证处理,判断输入是否合法。如果输入非法指令,直接报错退出。

    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        char cmd[12];
        printf("请输入指令:");
        scanf("%s", cmd);
        
        if (atoll(cmd) > 1000000000) {
            printf("非法指令!\n");
            exit(1);  // 退出程序
        }
        
        // 其他指令处理代码
        
        return 0;
    }
    

    2. 使用自定义函数验证输入 定义一个函数来验证输入的指令是否合法。如果输入非法指令,直接报错退出。

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    bool isValidCmd(const char *cmd) {
        long long int num = atoll(cmd);
        if (num > 1000000000) {
            return false;
        } else {
            return true;
        }
    }
    
    int main() {
        char cmd[12];
        printf("请输入指令:");
        scanf("%s", cmd);
        
        if (!isValidCmd(cmd)) {
            printf("非法指令!\n");
            exit(1);  // 退出程序
        }
        
        // 其他指令处理代码
        
        return 0;
    }
    

    这样,当输入非法指令(大于1000000000)时,会打印"非法指令!"并退出程序。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 12月22日
  • 创建了问题 12月14日