Я попытался прокомментировать код и проверить, где он дает мне ошибку сегментации, но не смог ее найти. Я даже не могу установить отладчик gcc для проверки. Пожалуйста помоги!
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
FILE *file;
char *registers[] = {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7"};
char *regInBinary[] = {"000", "001", "010", "011", "100", "101", "110", "111"};
char delimiters[4] = " ,\n";
char binaryInstruction[17];
void convertToBinary(char *line);
void binaryToHex();
// Converting each line of source file into 16 bit binary
void convertToBinary(char *line){
int count = 0;
char *token = strtok(line, delimiters);
while(token != NULL){
// Opcodes
if(strcmp(token, "add") == 0)
strcpy(binaryInstruction, "0001");
if(strcmp(token, "and") == 0)
strcpy(binaryInstruction, "0101");
// if(strcmp(token, "halt") == 0)
// main();
int i;
for(i = 0; i < 8; i++){ // appends registers in binary
if(strcmp(token, registers[i]) == 0){
strcat(binaryInstruction, regInBinary[i]);
count++;
if(count == 2){
strcat(binaryInstruction, "000");
}
}
}
token = strtok(NULL, delimiters);
}
}
// Converting 16 bit binary into hex
void binaryToHex(){
char hex[5];
int i, j;
for(i = 0; i < 16; i = i + 0){
for(j = 0; j < 4; j++){
hex[j] = binaryInstruction[i];
i++;
}
printf("%x", (int)strtol(hex, NULL, 2));
}
printf("\n");
}
// Starting program Part1
int main(int argc, char *argv[]) {
char line[40];
if(argc != 2)
printf("Usage: %s source_file\n", argv[0]);
else
file = fopen(argv[1], "t1.asm"); // open source file
while(fgets(line, sizeof(line), file)){
convertToBinary(line);
binaryToHex();
}
//printf("f025")
fclose(file);
return 0;
}
поэтому этот код отлично компилируется на моем терминале Mac с gcc, но выдает ошибку сегментации, когда я загружаю файл t1.asm.
Это программа на C для перевода инструкций языка ассемблера AND, ADD и HALT LC3 в машинный код.
Спасибо!
char binaryInstruction[17];
слишком малы для того, что вы в них впихиваете, и ваша программа взрывается. - person tadman   schedule 23.10.2017for(i = 0; i < 16; i = i + 0){
.. технически это не проблема, так как вы увеличиваетеi
в теле цикла, но это странно. Измените его на циклwhile
или измените запоздалую/инкрементную часть наi=i+4
. - person yano   schedule 23.10.2017stderr
, а неstdout
. например: это:printf("Usage: %s source_file\n", argv[0]);
должно быть:fprintf( stderr, "Usage: %s source_file\n", argv[0]);
- person user3629249   schedule 24.10.2017fopen()
всегда проверяйте (!=NULL) возвращаемое значение, чтобы убедиться, что операция выполнена успешно. - person user3629249   schedule 24.10.2017int i; for(i = 0; i < 8; i++)
данные должны храниться у пользователей этих данных. т.е. ограничить объем данных. Предложить:for( int i = 0; i < 8; i++)
- person user3629249   schedule 24.10.2017main()
: когда количество параметров командной строки неверно, после вывода сообщения об ошибке следует вызватьexit()
, НЕ продолжать выполнение программы. Аналогичные соображения существуют при проверке результатов вызоваfopen()
и т. д. - person user3629249   schedule 24.10.2017void
между скобками. В противном случае компилятор сгенерирует код, принимающий любое число и любые параметры. Не то, что вы действительно хотите. - person user3629249   schedule 24.10.2017binaryToHex()
локальный массив:hex[5];
имеет только первые 4 байта, т.е. пятый байт содержит мусор (какой бы мусор ни находился в стеке в этом месте. Функция:strtol()
ожидает указатель на строку с завершением NUL. Настоятельно рекомендуется объявлять массивhex[]
как:char hex[5] = {'\0'};
- person user3629249   schedule 24.10.2017file = fopen(argv[1], "t1.asm");
1) второй параметр - это "режим", а не какое-то имя файла. 2) проверьте (!=NULL) возвращаемое значение. предложить:FILE *file = fopen( argv[1], "r" ); if( NULL == file ) { perror( "fopen failed" ); exit( EXIT_FAILURE ); }
- person user3629249   schedule 24.10.2017// if(strcmp(token, "halt") == 0) // main();
НИКОГДА не вызывайтеmain()
рекурсивно, фактически, никогда не вызывайтеmain()
из вашего кода - person user3629249   schedule 24.10.2017convertToBinary()
нужно много работать - person user3629249   schedule 24.10.2017for(i = 0; i < 16; i = i + 0)
это неверно, так как индексная переменнаяi
не изменяется. Кроме того, объем данных должен быть максимально ограничен. учитывая размещенный код, предложите: удалить оператор:int i, j;
и заменить:for(i = 0; i < 16; i = i + 0) { for(j = 0; j < 4; j++)
на:for( int i = 0; i < 16; i += 4 ) { for( int j=0; j < 4; j++ )
- person user3629249   schedule 24.10.2017