正确反汇编机器操作码和寄存器操作数

运行长一点的字符串,机器码和寄存器操作数就乱码了
  • 代码展示
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//定义函数
int convertStrToByteCode1(const char *str1, unsigned char inst1[], int size1);

int main(){
    int argc;
    
    char **argv;
    
    FILE *pFile = NULL;
    
    char buffer[15];
    
    if(argc < 2){
        pFile = fopen("./test2.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};
    convertStrToByteCode1(buffer, instruction, 6);
//    instruction[0]=instruction[0]&0xFF;
//    instruction[1]=instruction[1]&0xFF;
    fclose(pFile);
    
    return 0;
}

int convertStrToByteCode1(const char *str1, unsigned char inst1[], int size1)
{
    char numHexDigits = 0;
    char *endstr;
    //Each instruction should consist of at most 12 hex digits
    numHexDigits = strlen(str1) - 1;
    //Convert the string to integer, N.B. this integer is in decimal
    long long value = strtol(str1, &endstr, 16);
    
    char numBytes = numHexDigits >> 1;
    char byteCount = numHexDigits >> 1;
    
    while (byteCount > 0)
    {
        unsigned long long mask = 0xFF;
        unsigned long shift = (numBytes - byteCount) << 3;
    
        inst1[byteCount - 1] = (value & (mask << shift)) >> shift;
        byteCount--;
    }
    
    //Return the size of the instruction in bytes
    return numHexDigits >> 1;
}


  • 输出结果

img

  • 预期的结果

输入的文本

img


输出的结果

img

这个问题可能是程序中定义数组长度时的问题。在程序中,您定义了一个数组叫做“array”,数组的长度是12。但是在操作这个数组时,您使用的是“array[operandA][operandB]”,也就是说您认为数组array是一个二维数组,其中第一维长度是12,第二维长度是7。但事实上,您定义的数组array是一个一维数组,长度是12。如果您想定义一个二维数组,应该这样定义:

char *array[12][7]={
{"halt"},
{"nop"},
{"rrmovl","cmovle","cmovl","comve","cmovne","comvge","comvg"},
{"irmovl"},
{"rmmovl"},
{"mrmovl"},
{"addl","subl","andl","xorl"},
{"jmp","jle","jl","je","jne","jge","jg"},
{"call"},
{"ret"},
{"pushl"},
{"popl"}
};

如果您要访问array的第一维和第二维,应该使用下标来访问,例如:

//如果要访问array的第0行第0列,应该这样写:
printf("%s\n",array[0][0]);

//如果要访问array的第1行第1列,应该这样写:
printf("%s\n",array[1][1]);


如果你的长字符串在显示时变成了乱码,那么可能是因为你的程序读取到了无效的字符。在您的代码中,可以考虑在读取字符串之前,先进行字符串长度的检查,并判断读取到的字符串是否合法,然后再进行后续的操作。如果发现读取到的字符串不合法,可以直接跳过,避免对结果造成影响。例如:

//在 while 循环中增加判断条件
while (fgets(buffer, 15, pFile) && strlen(buffer) > 1)
{
//判断字符串是否合法
if (!isValidString(buffer))
{
//如果不合法,跳过本次循环
continue;
}
unsigned char instruction[6] = {0, 0, 0, 0, 0, 0};
convertStrToByteCode1(buffer, instruction, 6);
...
}

//定义 isValidString 函数
bool isValidString(const char *str)
{
//只有字符串以十六进制数字组成且长度不超过 12 位,才认为字符串合法
if (strlen(str) > 12)
{
return false;
}
for (int i = 0; i < strlen(str); i++)
{
if (!isxdigit(str[i]))
{
return false;
}
}
return true;


希望能帮到您。