RISC-V assembler programmering
Het enthousiasme voor RISC-V wijst erop dat de architectuur een kracht is om rekening mee te houden. Dit maakt de architectuur in veel gevallen een goede investering. Met de RISC-V assembler kunt u direct geoptimaliseerde functies ontwikkelen.
Een groot aantal hedendaagse elektronicaprojecten maakt gebruik van microprocessorchips vanwege de flexibiliteit die softwarebesturing biedt. Maar welke microprocessor kies je? Welke programmeertalen gebruiken we? Dit zijn belangrijke vragen voor elke projectontwerper. RISC-V microprocessoren bieden extra hardware flexibiliteit. De fabricagekosten zijn lager omdat ze niet onderworpen zijn aan IP-licenties en beperkingen. Zonder deze beperkingen kunnen fabrikanten aangepaste functies aan hun CPU toevoegen, wat gespecialiseerde projectvoordelen biedt. De goed ontworpen RISC-V-specificatie is georganiseerd in categorieën van eigenschappen (extensies genoemd). Hierdoor kan de fabrikant ervoor kiezen alleen die functies te implementeren die de toepassing vereist. Vermindering van het aantal transistors op een chip leidt tot minder stroomverbruik en lagere kosten.
Zowel hobbyisten als fabrikanten profiteren van de beschikbaarheid van de gratis Gnu C/C++ compiler toolchain. Wat soms over het hoofd wordt gezien is dat een assembler in de toolchain aanwezig is. Voor het grootste deel zal C/C++ de productiefste programmeertaal blijven. Toch blijft er soms behoefte bestaan aan sterk geoptimaliseerde functies die alleen in assembler kunnen worden geprogrammeerd. Een belangrijk gebied hiervoor is de ontwikkeling van korte interrupt-service-routines.
Het enthousiasme van leveranciers, waaronder Intel, voor RISC-V wijst erop dat de architectuur een kracht is waarmee rekening moet worden gehouden. Dit maakt de architectuur tot een goede investering. Als je met de RISC-V assembler begint, kun je direct geoptimaliseerde functies ontwikkelen. Of je kunt C/C++ builds op instructieniveau controleren om te zien wat de optimaliserende compiler voor je heeft geproduceerd. Soms resulteert de high-level optimalisatie van een compiler in foutieve code. Daarom bespaart het opsporen van dit soort problemen tijd.
De ESP32-C3 werd gekozen vanwege zijn lage kosten voor zowel de hobbyist als de student. Toch is dit device zeer functioneel, inclusief USB, Wi-Fi, SPI, I2C en meer. De ESP32-C3 is een uitstekend platform om kennis te maken met de RISC-V RV32 ISA (32-bit instructieset architectuur). Het ESP-IDF ontwikkelingssysteem van Espressif wordt gebruikt voor de ESP32-C3. Men is niet afhankelijk van Arduino software.
Met de QEMU-emulator kan de lezer zijn desktopcomputer gebruiken om Fedora Linux te draaien in de RISC-V RV64 ISA (64-bit architectuur). Bovendien biedt deze omgeving hem de mogelijkheid om te oefenen met de RISC-V floating-point extensies.
Table 1: RISC-V Basic Registers.
Met zo'n groot aantal registers kan een goed geconstrueerde functie het aanspreken van het geheugen volledig vermijden, wat leidt tot een snellere uitvoering. De registers bieden onmiddellijke toegang tot data, terwijl voor toegang tot het geheugen extra klokcycli nodig zijn. Alle RISC-V CPU's bieden deze 32 registers, met één uitzondering. Uitbreiding E voor RISC-V is ontwikkeld om fabrikanten in staat te stellen een CPU te maken met slechts 16 registers. Deze zijn gericht op zeer goedkope microcontrollers.
Alle registers hebben dezelfde mogelijkheden, met uitzondering van x0 dat een speciale gave heeft. Wanneer x0 als bron wordt opgegeven, levert het de gehele waarde nul. Als het als bestemming voor een resultaat wordt opgegeven, wordt dit resultaat geëlimineerd. Hoewel de overige registers alle dezelfde functie hebben, reserveert de Gnu-calling-conventie groepen registers voor specifieke doeleinden. Voorbeelden zijn a0 tot a7, die worden gebruikt om argumenten op te slaan, t0 tot t6 om tijdelijke getallen te onthouden en register ra (x1) om een return adres te ontvangen.
Naast deze registers voegen de RISC-V-uitbreidingen F, D of Q de volgende floating-point-registers toe, zoals aangegeven in tabel 2.
Table 2: Floating-point registers en hun ABI-namen.
De breedte van deze registers hangt af van de ondersteunde extensies. Extensie F ondersteunt het float type van C, terwijl extensie D het double type ondersteunt. Extensie Q tenslotte ondersteunt het quad floating-point formaat.
De oplettende lezer heeft misschien gemerkt dat er iets ontbreekt. Er zijn geen status flag bits, zoals Carry, Overflow, Negative, etc., en dus ook geen statusregister. De ontwerpers van de RISC-V architectuur besloten dat het het beste was om deze weg te laten. Dit vermindert de overhead van de interrupt-service-routine omdat de status flags niet meer hoeven te worden opgeslagen en hersteld. RISC-V voorziet in die behoefte op andere manieren, die in het boek worden beschreven.
Zowel hobbyisten als fabrikanten profiteren van de beschikbaarheid van de gratis Gnu C/C++ compiler toolchain. Wat soms over het hoofd wordt gezien is dat een assembler in de toolchain aanwezig is. Voor het grootste deel zal C/C++ de productiefste programmeertaal blijven. Toch blijft er soms behoefte bestaan aan sterk geoptimaliseerde functies die alleen in assembler kunnen worden geprogrammeerd. Een belangrijk gebied hiervoor is de ontwikkeling van korte interrupt-service-routines.
Waarom RISC-V kiezen voor je project?
Veel bestaande instructie-architecturen moeten tientallen jaren worden uitgebreid zodat bestaande software compatibel blijft. Dit duwt de softwareontwikkelaar op een steile leercurve om de architectuur onder de knie te krijgen. Dit is vervelend en kan leiden tot langer debuggen en gemiste deadlines. De RISC-V-specificatie veegt de lei schoon en presenteert een nieuwe instructieset.Het enthousiasme van leveranciers, waaronder Intel, voor RISC-V wijst erop dat de architectuur een kracht is waarmee rekening moet worden gehouden. Dit maakt de architectuur tot een goede investering. Als je met de RISC-V assembler begint, kun je direct geoptimaliseerde functies ontwikkelen. Of je kunt C/C++ builds op instructieniveau controleren om te zien wat de optimaliserende compiler voor je heeft geproduceerd. Soms resulteert de high-level optimalisatie van een compiler in foutieve code. Daarom bespaart het opsporen van dit soort problemen tijd.
Waar gaat dit boek over?
Het boek, RISC-V Assembly Language Programming using ESP32-C3 and QEMU, is een handleiding om je op weg te helpen. Het is ontworpen als een eenvoudig leerboek. Elk hoofdstuk introduceert een paar minimale concepten, zodat je niet te veel in één keer hoeft te leren. Latere hoofdstukken bouwen dan voort op wat je al geleerd hebt. Elk project begint met een hoofdprogramma in C dat één of meer onder programma’s in assembler oproept. Dit demonstreert het nut van het gebruik van de C/C++ taal waar het zinvol is en het tegelijkertijd benutten van assembler.De ESP32-C3 werd gekozen vanwege zijn lage kosten voor zowel de hobbyist als de student. Toch is dit device zeer functioneel, inclusief USB, Wi-Fi, SPI, I2C en meer. De ESP32-C3 is een uitstekend platform om kennis te maken met de RISC-V RV32 ISA (32-bit instructieset architectuur). Het ESP-IDF ontwikkelingssysteem van Espressif wordt gebruikt voor de ESP32-C3. Men is niet afhankelijk van Arduino software.
Met de QEMU-emulator kan de lezer zijn desktopcomputer gebruiken om Fedora Linux te draaien in de RISC-V RV64 ISA (64-bit architectuur). Bovendien biedt deze omgeving hem de mogelijkheid om te oefenen met de RISC-V floating-point extensies.
Wat krijg je met een RISC-V CPU?
Tabel 1 geeft een overzicht van de 32 integer basisregisters die de CPU de programmeur biedt. Deze kunnen worden aangeduid met x0 t/m x31 of met de vriendelijkere ABI-namen (application binary interface), zoals a0 voor argument nul. Voor RV32-platforms zoals de ESP32-C3 zijn dit 32-bits registers. Bij RV64-platforms zijn de registers 64 bits breed.Table 1: RISC-V Basic Registers.
Register | ABI Naam | Beschrijving |
x0 | zero | Hardwired to return zero |
x1 | ra | Return Address |
x2 | sp | Stack pointer |
x3 | gp | Global pointer |
x4 | tp | Thread pointer |
x5-x7 | t0-t2 | Temporary registers |
x8 | s0/fp | Saved register / frame pointer |
x9 | s1 | Saved register |
x10-x11 | a0-a1 | Function arguments / return value |
x12-x17 | a2-a7 | Function arguments (continued) |
x18-x27 | s2-s11 | Saved registers |
x28-x31 | t3-t6 | Temporary registers |
Met zo'n groot aantal registers kan een goed geconstrueerde functie het aanspreken van het geheugen volledig vermijden, wat leidt tot een snellere uitvoering. De registers bieden onmiddellijke toegang tot data, terwijl voor toegang tot het geheugen extra klokcycli nodig zijn. Alle RISC-V CPU's bieden deze 32 registers, met één uitzondering. Uitbreiding E voor RISC-V is ontwikkeld om fabrikanten in staat te stellen een CPU te maken met slechts 16 registers. Deze zijn gericht op zeer goedkope microcontrollers.
Alle registers hebben dezelfde mogelijkheden, met uitzondering van x0 dat een speciale gave heeft. Wanneer x0 als bron wordt opgegeven, levert het de gehele waarde nul. Als het als bestemming voor een resultaat wordt opgegeven, wordt dit resultaat geëlimineerd. Hoewel de overige registers alle dezelfde functie hebben, reserveert de Gnu-calling-conventie groepen registers voor specifieke doeleinden. Voorbeelden zijn a0 tot a7, die worden gebruikt om argumenten op te slaan, t0 tot t6 om tijdelijke getallen te onthouden en register ra (x1) om een return adres te ontvangen.
Naast deze registers voegen de RISC-V-uitbreidingen F, D of Q de volgende floating-point-registers toe, zoals aangegeven in tabel 2.
Table 2: Floating-point registers en hun ABI-namen.
Register | ABI Naam | Beschrijving |
f0-f7 | ft0-ft7 | Floating-point temporaries |
f8-f9 | fs0-fs1 | Floating-point saved registers |
f10-f11 | fa0-fa1 | Floating-point arguments/return values |
f12-f17 | fa2-fa7 | Floating-point arguments |
f18-f27 | fs2-fs11 | Floating-point saved registers |
f28-f31 | ft8-ft11 | Floating-point temporaries |
De breedte van deze registers hangt af van de ondersteunde extensies. Extensie F ondersteunt het float type van C, terwijl extensie D het double type ondersteunt. Extensie Q tenslotte ondersteunt het quad floating-point formaat.
De oplettende lezer heeft misschien gemerkt dat er iets ontbreekt. Er zijn geen status flag bits, zoals Carry, Overflow, Negative, etc., en dus ook geen statusregister. De ontwerpers van de RISC-V architectuur besloten dat het het beste was om deze weg te laten. Dit vermindert de overhead van de interrupt-service-routine omdat de status flags niet meer hoeven te worden opgeslagen en hersteld. RISC-V voorziet in die behoefte op andere manieren, die in het boek worden beschreven.