Эмуляция памяти компьютера

Последнее обновление: 01.03.2024

Как правило, данные, котоорыми оперирует программа, размещаются в памяти. Для симуляции памяти в Python можно использовать список. Например:

mem = [0,0,0,0,0,0,0,0]
# или
mem = [0] * 8

Переменная mem представляет условно память из 8 ячеек, каждая из которых хранит значение 0.

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

0x00000x00010x00020x00030x00040x00050x00060x0007
mem[0]mem[1]mem[2]mem[3]mem[4]mem[5]mem[6]mem[7]

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

mem = [0]*8                 # Память из 8 ячеек
mem[0] = 4                  # По адресу 0x0000 сохраняем число 4
mem[1] = 5                  # По адресу 0x0001 сохраняем число 5
sum = mem[0] + mem[1]       # Складываем значения ячеек 0x0000 и 0x0001
mem[2] = sum                # Сохраняем сумму в ячейку 0x0002
print("mem[2] =", mem[2])   # Выводим на консоль значение из ячейки 0x0002
print("Memory =", mem)      # печать всей памяти

Консольный вывод:

mem[2] = 9
Memory = [4, 5, 9, 0, 0, 0, 0, 0]

Косвенная адресация

Косвенная адресация представляет ситуацию, когда одна ячейка памяти хранит адрес другой ячейки памяти. И таким образом, через одну ячейку памяти можно обратиться к другой. Например:

mem = [5,6,7,0,0,3,5,0]     # Условная память
val0 = mem[mem[0]]          # val0 = 3
val1 = mem[mem[1]]          # val1 = 5
sum = val0 + val1           # sum = 8
mem[mem[2]] = sum           # Сохраняем результат в ячейку по адресу mem[2]
print("Memory =", mem)      # Memory = [5, 6, 7, 0, 0, 3, 5, 8]

Здесь первые три элемента в списке mem представляют индексы других элементов из списка mem (то есть условно адреса других ячеек в памяти). Например, возьмем следующее выражение

val0 = mem[mem[0]]

Здесь сначала получаем значение из mem[0] - индекс или адрес некоторого другого значения. Затем по этому индексу/адресу берем значение и помещаем в переменную val0. Таким образом, процесс разбивается на две части:

mem[0] -> 5
mem[5] -> 3

Собственно поэтому адресация называется косвенной - так как надо сначала получить адрес ячейки памяти, а лишь потом можно получить собственно значение по этому адресу.

Аналогичным образом получаем значение в переменную val1, складываем обе переменных и также с помощью косвенной адресации сохраняем результат в ячайку памяти, чей индекс хранится по индексу 2:

mem[mem[2]] = sum 

Опять же получается двухэтапный прочесс:

mem[2] -> 7
sum -> mem[7]

Указатели

При работе с памятью могут применяться указатели, которые упрощают косвенную адресацию. Указатели - это значения, которые хранят адреса ячеек памяти:

mem = [5,6,7,0,0,3,5,0]         # Условная память
pointer0 = mem[0]               # Указатель pointer0 указывает на ячейку памяти с адресом 0x0005
pointer1 = mem[1]               # Указатель pointer1 указывает на ячейку памяти с адресом 0x0006
pointer2 = mem[2]               # Указатель pointer2 указывает на ячейку памяти с адресом 0x0007
val0 = mem[pointer0]            # Получаем значение по указателю pointer0
val1 = mem[pointer1]            # Получаем значение по указателю pointer1
sum = val0 + val1               # Выполняем сложение
mem[pointer2] = sum             # Сохраняем результат в ячейку по указателю pointer2
print("Memory =", mem)          # Memory = [5, 6, 7, 0, 0, 3, 5, 8]

Здесь переменная pointer0 получает значение из mem[0] (ячейку памяти с условным адресом 0x0000). В этой ячейке хранится число 5. Но это не просто число. Это значение мы будем интерпретировать как адрес другой ячейки (фактически mem[5]). Аналогично переменная pointer1 получает в качестве значения число mem[1] - число 6, то есть ячейку с условным адресом 0x0006 (фактически mem[6]). То есть по факту указатели выступают в качестве индексов относительно начала памяти.

Далее, применяя указатель, мы можем получить по нему значение:

val0 = mem[pointer0]        # Получаем значение по указателю pointer0; val0 = 3
val1 = mem[pointer1]        # Получаем значение по указателю pointer1; val1 = 5

Выполнив сложение, сохраняем сумму по адресу на которую указывает указатель pointer2:

sum = val0 + val1               # Выполняем сложение
mem[pointer2] = sum             # Сохраняем результат в ячейку по указателю pointer2
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850