2026-01-23

Se även Lecture 02 på Canvas som är väldigt bra!

Administrativt

Deadline att gå med i en grupp på söndag, se Canvas.

ISA

En ISA specificerar en processors beteende i termer av instruktionsuppsättning, register och minnesmodell, samt hur dessa komponenter samverkar.

Att göra en egen ISA är mycket dyrt eftersom det är extremt mycket mjukvara som behöver utvecklas för att stödja den:

Viktiga ISA

RISC-V

RISC-V (Reduced Instruction Set Computer 5) är en ISA (Instruction Set Architecture) som är öppet för alla att använda och används främst i embedded och mikrokontrollers.

Varianter och extentensions

RISC-V är modulärt och har tre varianter och ett flertal extensions

Varianter

Både RV32I och RV64I har 47 maskinkodsinstruktioner.

Extensions

Och fler som vi inte behöver veta.

MD307 Utvecklingskort

Det vi kommer använda i kursen. Det är av RV32I varianten, och har extensions F, C och A.

ABI

Står för Application Binary Interface.

Dokument som bestämmer konventioner för hur maskinkod på en viss ISA skall skrivas. Bestämmer bland annat t.ex:

Register

RISC-V har 32 st 32-bitars register. ABI har bestämda namn och syften. x0-31 är standardbenämningen på register, men när man skriver assemblerkod använder man istället ABI-namnen.

Pasted image 20260123134014.png

Instruktioner

RISC-V har bara 47 maskinkodsinstruktioner. MEN den har många fler assemblerkodsinstruktioner. Till exempel mv t0, t1 som kopierar värdet från t1 till t0 finns inte som en maskinkodsinstruktion. Istället återanvänder man add t0, t1, zero som mv eftersom det gör samma sak.

Assemblerinstruktioner som översätts till andra maskinkodsinstruktioner (som mv) kallas pseudoinstruktioner.

Load/Store Arkitektur

RISC-V har en Load/Store arkitektur. Det innebär att enbart Load och Store instruktioner får kommunicera med minnesbussen.

Istället för add register_0, M(register_1) som läser från minnet och adderar talen så måste man först ladda från minnet till ett register och sedan addera de register.

Varför? Det är enklare att bygga optimiserare när man vet att bara vissa instruktioner rör minnet.

Quickguide

Finns på Canvas: https://www.cse.chalmers.se/edu/resources/mop/lecture_notes/quickguide.html

Referens som innehåller register, instruktioner, periferi och allt man kan behöva man behöver. Kommer få den som en PDF några veckor innan tentan, vi kommer även få den som del av tentatesen.

Tip

I Visual Studio Code kan man köra kommandot Simple Browser: Show och öppna Quickguide i ett browserfönster.

Exempelprogram

Vi vill ha ett program som gör följande:

Pasted image 20260123141301.png

Med RISC-V assemblerkod skrivs det som:

Pasted image 20260123141310.png

Detta kompileras i sin tur till maskinkod:

Pasted image 20260123141748.png

Se Lecture 02 på Canvas för förklaring

Stora immediates

Instruktionerna är alltid 32-bitar så stora immediates som är t.ex. 32-bitar långa måste laddas in i flera instruktioner

Minnerymd

Vi har:

Pasted image 20260123142423.png

För våra första labbar är mikrokontrollern färdigkonfigurerad att skriva vårt program till början av SRAM. Senare i kursen kommer vi även specificera addresser utanför SRAM.

Sign extension

I följande exempel har a och b samma värde i minnet 0xFB.

Pasted image 20260123144052.png

Men när vi läser dessa från minnet med lb (load byte) kommer de läsas in som signed bytes, vilket innebär att de båda blir -5 i 32-bitar 0xFFFFFFFB och summan blir -10. Detta kallas sign-extension och för att fixa det i det här exemplet använder vi lbu instruktionen istället vilket läser en unsigned byte vilket fyller de övre bitsen med 0 istället för 1.

Memory Alignment

Läser ett word (4-bytes/32-bitar), detta funkar utan problem eftersom vi kan aktivera rätt 32-bitars register och läsa alla bytes från det.

Pasted image 20260123144903.png

Men om vi läser från en address som inte är delbar med 4 hamnar vi mellan två register. Detta är långsammare och skulle behöva utföras i flera klockcyklar, därför är detta helt förbjudet i många ISA som RISC-V.

Pasted image 20260123145027.png

Regel

En variabel som tar upp 4 bytes måste ligga på en address som är jämnt delbar med fyra

En variabel som tar upp 2 bytes måste ligga på en address som är jämnt delbar med två

Exempel

Säg att vi ska definiera följande variabler:

a: .byte
b: .hword
c: .hword
d: .word

Ett naivt sätt att göra det är att lägga in fler variabler för att aligna variablerna:

a: .byte
d: .byte # Dummy byte
b: .hword
c: .hword
e: .hword # Dummy hword
d: .word

Men om man skulle lägga till en byte innan måste man manuellt lägga in fler bytes vilket bara blir jobbigt. align direktivet (skrivs som .align x) säger att nästa address måste vara delbart med 2^x.

a: .byte
.align 1
b: .hword
c: .hword
.align 2
d: .word