Пам'ять: завантаження та збереження

Пам'ять: завантаження та збереження

Пам'ять — це великий ряд пронумерованих комірок зберігання, і кожна комірка містить один байт (8 бітів). Номер комірки — це її адреса. Регістри — це невеликий набір швидких комірок процесора. Пам'ять набагато більша, але повільніша, і зберігає все, що не вміщується в регістрах, наприклад масиви та рядки. Щоб працювати зі значенням у пам'яті, ви завантажуєте його в регістр, змінюєте та зберігаєте назад.

Регістрів мало, а пам'ять велика. (load word) копіює слово з пам'яті в регістр, а (store word) копіює його назад. Адреса записується як offset(register).

Пам'ять RISC-V адресується побайтово, тому кожен байт має власну адресу в послідовності. Слово — це 32 біти, або 4 байти, тому ви просуваєте вказівник пам'яті на 4, щоб досягти наступного слова. Саме тому зсуви масиву дорівнюють 0, 4, 8 і так далі. На реальному обладнанні завантаження слова з адреси, що не є кратною 4, може бути повільним або спричинити пастку. Цей симулятор це дозволяє, але вам слід виробити звичку вирівнювати слова за 4 байтами.

Форма завантаження / збереження
lw t0, 0(a1) # t0 = пам'ять за адресою a1
sw t0, 4(a1) # пам'ять за адресою a1+4 = t0

У offset(register) до адреси, що зберігається в регістрі, додається невелике число зсуву. 0(a1) — це адреса в самому a1, а 4(a1) — на 4 байти далі. Це дозволяє досягати сусідніх значень без зміни базового регістра.

Збереження в пам'ять
CPU
li t0, 0x11111111
li t1, 0x22222222
li a0, 0x1000
sw t0, 0(a0)
sw t1, 8(a0)
Registers
t00x00000000
t10x00000000
a00x00000000
Random Access Memory (RAM)
AddressValue
0x100C0x00000000
0x10080x00000000
0x10040x00000000
0x1000
0x00000000
0x0FFC0x00000000

Регістри та пам'ять починаються з нуля.

В анімації базовий регістр a0 залишається незмінним. Збільшується лише літеральний зсув, записаний в інструкції, переміщуючись до наступної цільової адреси пам'яті. Щоб створити пам'ять, що відповідає цьому шаблону, зарезервуйте іменовану пам'ять у секції даних за допомогою .word (одне або кілька 32-бітних значень) або .space N (N порожніх байтів). Кожне слово займає 4 байти, тому послідовні елементи розташовані за зсувами 0, 4, 8, які збігаються з числами, використаними у ваших інструкціях збереження.

Використовуйте .word (одне або кілька 32-бітних значень) або .space N (N порожніх байтів), щоб зарезервувати іменовану пам'ять у секції даних. Кожне слово займає 4 байти, тому послідовні елементи знаходяться за зсувами 0, 4, 8 і так далі.

Сума масиву в пам'яті
.data
nums: .word 10, 20, 30, 40 # чотири слова
.text
la t1, nums # t1 = адреса масиву
li t2, 4 # кількість
li t0, 0 # поточна сума
loop:
beq t2, zero, done
lw t3, 0(t1) # завантажити поточний елемент
add t0, t0, t3 # додати до суми
addi t1, t1, 4 # перейти до наступного слова (4 байти)
addi t2, t2, -1 # на одне менше залишилося
j loop
done:
mv a0, t0 # вивести підсумок (100)
li a7, 1
ecall
li a7, 10
ecall

поміщає адресу масиву в t1, t2 підраховує 4 елементи, що залишилися, а t0 зберігає поточну суму. На кожному проході зупиняє цикл, коли не залишається елементів. завантажує елемент, на який вказує t1, додає його до суми, просуває вказівник на одне слово, а зменшує лічильник. Після всіх чотирьох елементів (10 + 20 + 30 + 40) done виводить 100.

💡
Використовуйте перемикач HEX/DEC на панелі інструментів симулятора, щоб змінити відображення адрес і значень. Виберіть ту систему числення, яка полегшує відстеження поточного кроку.