Доступ к элементам большого массива - PullRequest
0 голосов
/ 27 мая 2018

У меня проблема с доступом к элементам одного из моих массивов.Я заранее прошу прощения за длинный код, но необходимо полностью объяснить проблему.У меня есть структура, которую я объявил в заголовочном файле следующим образом:

typedef struct {
    // DC the current value of the Program Counter register
    unsigned short int DC;

    // PSR : Processor Status Register, bit[0] = P, bit[1] = Z, bit[2] = N, bit[15] = privilege bit
    unsigned short int GSR;

    //Registers - 8
    unsigned short int R[8];

    //Control signals 
    ControlSignals control_signals;

    //Memory 
    unsigned short int mem[65536];
} MachineState;

В файле компоновщика я читаю из двоичного файла и сохраняю 16-битные шестнадцатеричные значения в массиве memory struct,Вот соответствующая настройка для этой операции:

//Rectify endianness
        if ((foo_array[0]) == 0xDECA || (foo_array[0]) == 0xB7C3 || (foo_array[0]) == 0x7EF1 || (foo_array[0]) == 0x5E71)
        {
            //Iterate through each element in array, swapping bytes to convert to big endian
            for (i = 0; i < bytes; i++)
            {
                //Swap bytes
                (foo_array[i]) = ((foo_array[i])>>8) | ((foo_array[i])<<8);
            }
        }

        //Iterate through temp array selecting only CADE/DADA instructions to copy to struct array
        for (i = 0; i < bytes; i++)
        {
            if ((foo_array[i]) == 0xCADE || (foo_array[i]) == 0xDADA)
            {

                //Increment to starting address
                i++;

                //Store start address
                start_address = foo_array[i];

                //Increment to n-body word specification
                i++;

                //Find number of words in relevant instructions
                foo = foo_array[i];

                //Increment to beginning of instruction
                i++;

                //Iterate through temp array selecting only CADE/DADA instructions to copy to struct array
                for (count = 0, j = start_address; count < foo; i++, j++, count++)
                {

                    //Assign values from temp array to machine memory array
                    machine->mem[j] = foo_array[i];
                    printf("address %05d in memory is: 0x%04X\n",j, machine->mem[j] );                          
                }

                //Once loop exited, decrement index variable to appropriate values
                if (count == foo)
                {
                    i--;
                }
            }   
        }

Как вы можете себе представить, при выводе в память машины будут шестнадцатеричные значения, некоторые ноль и ненулевое значение следующим образом:

address 32805 in memory is: 0x0201
address 32806 in memory is: 0x0000
address 32807 in memory is: 0x8000
address 32808 in memory is: 0x0000
address 33280 in memory is: 0x9E00
address 33281 in memory is: 0x8000
address 40960 in memory is: 0x0001

Значения, которые я сохранил в массиве, нужно передать в функцию, с которой нужно работать, однако я не могу найти способ передать все те значения, которые заполнилимассив.Массив длинный, от индекса 0x0000 до 0x10000, но единственный способ, которым я рассчитывал передать все значения, - это цикл for, который выбирает, когда я нажимаю на ненулевой элемент в массиве, но проблема в том, чтонулевые значения также очень важны и должны также использоваться.Это моя реализация для цикла:

 //Iterate through each element passing populated elements into function
        for (i = 0; i < (sizeof(machine.mem)) / (sizeof(unsigned short int)); i++)
        {
          //  printf("index is %d\n",i );
            if (machine.mem[i] != 0)
            {        
                printf("machine memory is: 0x%04X\n",machine.mem[i] );

                //Call UpdateMachineState to begin decoding machine instructions and execute one LC4 datapath
               //UpdateMachineState(&machine);   
            }
        } 

Это позволяет мне находить только ненулевые значения, но что, если начальное число или средние значения в массиве были равны нулю?Они будут полностью пропущены.Есть ли способ получить все заполненные значения?Я просто не могу понять это.

РЕДАКТИРОВАТЬ: Из полученных комментариев может показаться, что может быть неясно, в чем именно заключается проблема, поэтому я постараюсь уточнить.После загрузки в память машины его содержимое выглядит следующим образом:

address 00000 in memory is: 0xF020
address 00001 in memory is: 0x9A00
address 00002 in memory is: 0xDBA0
address 00003 in memory is: 0x7B40
address 00004 in memory is: 0xF0FF
address 32800 in memory is: 0x9600
address 32801 in memory is: 0xD7A0
address 32802 in memory is: 0x9802
address 32803 in memory is: 0x78C0
address 32804 in memory is: 0x64C0
address 32805 in memory is: 0x0201
address 32806 in memory is: 0x0000
address 32807 in memory is: 0x8000
address 32808 in memory is: 0x0000
address 33280 in memory is: 0x9E00
address 33281 in memory is: 0x8000
address 40960 in memory is: 0x0001

Здесь индекс 00000 - это начальный адрес, а индекс 40960 - это конечный адрес.Проблема в том, что я не знаю, как настроить цикл for, чтобы я мог передать все содержимое, которое было загружено в структуру machine.mem, в функцию UpdateMachineState(&machine);, если есть элементы, содержащиезначение 0x0000 (адрес 32806 и 32808, например).Когда объявляется структура machine.mem, все ее значения автоматически устанавливаются на ноль, поэтому я не уверен, как различать предварительно установленные значения 0x0000 и те, которые были загружены здесь: machine->mem[j] = foo_array[i].Я могу опубликовать полный код, если это необходимо.

1 Ответ

0 голосов
/ 31 августа 2018

Когда объявляется структура machine.mem, все ее значения автоматически устанавливаются на ноль, поэтому я не уверен, как различать предварительно установленные значения 0x0000 и те, которые были загружены здесь: machine-> mem[j] = foo_array [i].

Вы можете создать структуру, которая включает флаг со значением памяти и установить флаг, когда значение памяти назначено.

Вот так:

typedef struct{
    unsigned short int value;
    bool value_assigned;
}mem_t;

Затем, когда вы объявляете структуру MachineState, вы просто объявляете mem как массив этих структур следующим образом:

typedef struct {
    // DC the current value of the Program Counter register
    unsigned short int DC;

    // PSR : Processor Status Register, bit[0] = P, bit[1] = Z, bit[2] = N, bit[15] = privilege bit
    unsigned short int GSR;

    //Registers - 8
    unsigned short int R[8];

    //Control signals 
    ControlSignals control_signals;

    //Memory 
    mem_t mem[65536];
} MachineState;

Затем в той части кода, которую вы назначаетезначение памяти, вы просто должны быть уверены, чтобы установить этот флаг.

//Iterate through temp array selecting only CADE/DADA instructions to copy to struct array
for (count = 0, j = start_address; count < foo; i++, j++, count++)
{

    //Assign values from temp array to machine memory array
    machine->mem[j].value = foo_array[i];
    machine->mem[j].value_assigned = true;
    printf("address %05d in memory is: 0x%04X\n",j, machine->mem[j]);

}

Теперь вы сможете повторить этот массив и проверить value_assigned == true

...