Я пишу ассемблерную программу на C, которая берет ассемблерный код (составленной архитектуры) и манипулирует им для создания исполняемой программы.
Строка, которую я пытаюсь проанализировать:
jmp L1
Это код, который я использую:
int line_count = 0;
char line[MAX_LINE_LENGTH];
char original_line[MAX_LINE_LENGTH];
char *first_field;
char label[MAX_LABEL_LENGTH];
char *argument;
int arguments_in_line = 0;
while(fgets(line, MAX_LINE_LENGTH, fp) != NULL) {
line_count++;
strcpy(original_line, line);
first_field = strtok(line, delimit);
if(is_valid_label(first_field)) { /* first field is label */
strcpy(label,first_field);
first_field = strtok(NULL, delimit);
}
if(!is_entry_or_external(first_field)) {
arguments_in_line = get_num_operands(original_line);
if(arguments_in_line == UNEXPECTED_ERROR)
return UNEXPECTED_ERROR;
else if(arguments_in_line == 0) {
continue;
}
else if(arguments_in_line == 1) {
argument = strtok(NULL, delimit);
if(is_valid_label_name(argument)) /* SEGFAULT HERE!!! */
printf("found needed replacement at line %d, replace label: %s", line_count, argument);
}
}
}
Итак, во втором или третьем (зависит от ввода, для строки примера это второй) вызов strtok,Аргумент получает значение NULL, и происходит ошибка.Значения перед вызовом strtok:
(gdb) p line
$1 = "jmp L1\000\000\000\000\000\000[q\346\267\000\360... /* more values */
После первого вызова:
(gdb) p line
$2 = "jmp\000L1\000\000\000\000\000\000[q\346\267\000\360... /* more values */
И второй возвращает NULL.
Метод get_num_operands
выглядит следующим образом:
int get_num_operands(char *src_line) {
char line_copy[MAX_LINE_LENGTH];
char *first_field;
strcpy(line_copy, src_line);
first_field = strtok(line_copy, delimit);
if(is_valid_label(first_field)) /* first field is label */
first_field = strtok(NULL, delimit); /* make sure first field is a command or instruciton */
if (first_field == NULL)
return UNEXPECTED_ERROR;
else
return get_num_arguments_for_command(first_field);
}
Есть идеи относительно того, почему это происходит?