johanna83 behöver inte mer hjälp
johanna83 31
Postad: 2 maj 17:51 Redigerad: 2 maj 20:18

Handassemblering

Hej! En till fråga. 

Översätt instruktionerna nedan till maskinkod. Processor NIOS 11, tror jag. 

and r6, r7, r8

Svaret är: A B C OPX = 0x0E 0 OP 0x3A, 00111 01000 00110 001110 00000 111010

Varför är A = r7? 

Är det där resultatet ska sparas som ska vara först? Men det sparas väl i r8? Hur får man fram nummer på OPX?


Tråd flyttad från Matematik > Universitet till Programmering > Övriga programmeringsspråk. /Smutstvätt, moderator 

sictransit 1072 – Livehjälpare
Postad: 2 maj 19:16 Redigerad: 2 maj 20:21

Jag har aldrig jobbat med den här arkitekturen. OPX gissar jag står för eXtended OPcode, alltså processorns instruktioner. De är numrerade, så du ropar i princip på en funktion (exempelvis AND) med ett nummer. Det här beskrivs i manualen för CPU:n. Gissningsvis har du fått ett exemplar.

Efter lite googlande fann jag den här, men använd den du förhoppningsvis fått. På sida 8-8 hittar jag följande. Klistrar in ett litet utdrag ur den och hävdar "fair use". 

Det är där jag ser att hela OPX-familjen är 0x3a och i den är instruktionen AND 0x0e.

Här står det: rCrA&rB, så resultatet av A AND B skall till C.

I ditt fall blir det: r6r7&r8

Då tror jag du har svaret på dina frågor, eller hur?

De första 2x5 bitarna (A och B, alltså från vänster räknat) är indata. Nästa 5 bitar är utdata (C).


Varför denna ordning? Ja, det kan bara de som designat CPU:n svara på. Min gissning är att CPU:n avkodar instruktionen så här.

Den läser bitarna från höger till vänster (LSB till MSB), hittar olika delar och agerar beroende på dem.

  • 0x3a: Aha! En OPX.
    • Skippa fem bitar, för att se vilken.
  • 0x0e: Aha! Vi skall räkna AND. 
    • Nästa fem bitar talar om vart vi skall skicka resultatet.
  • 0x06: Rajt! Resultatet skall till R6, så vi nollar det registret nu.
    • Nästa fem talar om vad vi skall lägga där först.
  • 0x08: OK. Ta innehållet i R8 och stoppa i R6.
    • Nästa fem bitar skall AND:as.
  • 0x07: OK. Det vi precis stoppat i R6 skall AND:as med innehåller i R7.

Klart!


Hoppas det hjälper! Kul att du kodar maskinnära. Det är svårt, men väldigt roligt och dessutom förstår man hur datorer verkligen fungerar långt därinne.

johanna83 31
Postad: 3 maj 12:36

Tack! Men, låt mig se här... A och B ska läggas ihop. Alltså 01000 AND 00110 och då blir det 01110? och då ska 01110 ligga i C? Eller C är redan bestämt eftersom det är r6, alltså 00110?

johanna83 31
Postad: 3 maj 12:48

Och vilka är det alltid som har 6 platser? A, B, C har alltid 5 platser... men jag är osäker på de andra. Har OP alltid 6 platser?

sictransit 1072 – Livehjälpare
Postad: 3 maj 13:54 Redigerad: 3 maj 14:50
johanna83 skrev:

Tack! Men, låt mig se här... A och B ska läggas ihop. Alltså 01000 AND 00110 och då blir det 01110? och då ska 01110 ligga i C? Eller C är redan bestämt eftersom det är r6, alltså 00110?

Är du med på vad register är och vad den här instruktionen gör?

Ett register är som en låda, en area i minnet, där du kan stoppa ett värde. Typiskt finns det en uppsättning register i CPU:n. Vissa har specifika användningsområden, medan andra kan användas till vad som helst. Ungefär som en variabel när du programmerar.

Den här instruktionen tar värdena i två register, gör "bitwise logical and" på dem och stoppar resultatet i ett tredje register.

I det här fallet har vi "and r6, r7, r8". Det betyder att resultatet av en AND-operation mellan r7 och r8 skall läggas i r6.

Låt oss säga att vi har följande i registren:

  • r7=4711_dec=0001 0010 0110 0111
  • r8=1723_dec=0000 0110 1011 1011

Efter instruktionen är körd kommer r6 att innehålla:

  • r7 AND r8 = 0000 0010 0010 0011

Vi kan provköra instruktionen i en emulator.

Jag fyller r7 och r8 med de hexadecimala representationerna av 4711 respektive 1723.

Sedan kör vi instruktionen.

Efter det innehåller r6 mycket riktigt 0x223, vilket är bitvis AND av 0x1267 och 0x6bb.

Som bonus ger oss assemblern även en opcode: 3a0c703a. 

Binärt blir den: 00111010000011000111000000111010

Grupperar vi bitarna på rätt sätt får vi:

00111 (07) 01000 (08) 00110 (06)  001110 (0e) 00000 (00) 111010 (3a)

johanna83 31
Postad: 3 maj 14:18

Tack! Jag tror att jag fattar nu... Jag har gjort mov r8, r9 och call set-leds och bne r6,r7, write_char på egen hand mha av handboken nu... Så jag tror att jag kan. Snart kommer lite svårare saker. Då återkommer jag antagligen. 

Nu handlar det här ju om "handassemblering", men generellt rekommenderar jag en assembler. Då ser du vilka opcodes den genererar. Precis ingen handassemblerar längre, men klart det är en nyttig läxa för att förstå så här i början.

Sedan får du hitta en CPU att köra din kod på, eller en emulator som i mitt fall.

Laguna 30471
Postad: 3 maj 16:50

OP är förmodligen alltid lika många bitar, för det är den processorn tittar på först för att se vad resten betyder, och det går snabbast om man tar ett förutbestämt antal.

Antalet register är fixt, t.ex. 32 eller 64, så man använder alltid fem respektive sex bitar för att ange dem.

johanna83 31
Postad: 3 maj 16:52

Ja, nästa uppgift går ut på att experimentera med en assembler.... Rekommenderar du någon där jag kan öva på just detta?

Nope! Aldrig jobbat med den. Tog första bästa när du frågade. 

https://cpulator.01xz.net/

johanna83 31
Postad: 3 maj 17:00

Tack! Då ska jag sitta med den nästa helg :)

Laguna 30471
Postad: 3 maj 17:21

Vad säger kursbeskrivningen att ni ska lära er?

johanna83 31
Postad: 3 maj 17:29

"förstå hur processorn tolkar maskininstruktioner samt själv kunna skriva mindre maskinnära program" och en massa annat, men kring just detta är det det som står. 

johanna83 31
Postad: 3 maj 17:30

På laborationen ska vi sitta med assembler och på tentan ska vi skriva lite addi r6, r8 etc... 

Svara
Close