Rekursiv Fibonacci skriven i ARM Assembly Kod
Jag har i uppgift att skriva en rekursiv fibonacci kod med hjälp av ARM Assembly och kan inte riktigt få det till att fungera. Koden ser ut såhär.
PUBLIC main
SECTION .text : CODE(2)
THUMB
GRT
SUB R0, #1
BL FIB
SUB R0, #2
BL FIB
POP {LR}
BX LR
LET
ADD R1, R1, R0
CMP R0, #1
ITE EQ
ADDEQ R0, R0, #1
ADDNE R0, R0, #2
POP {LR}
BX LR
FIB
PUSH {LR}
CMP R0, #1
IT GT
BLGT GRT
CMP R0, #2
IT LT
BLLT LET
main
MOV R0, #5
MOV R1, #0
BL FIB
STOP B STOP
END
Problemet med koden är att "Link Registret" inte riktigt fungerar som det ska, tror jag inte gör riktigt rätt när jag poppar och pushar LR. Om någon bara hade kunnat glo igenom och ge tips så hade det uppskattats riktigt mycket.
För varje PUSH {LR} ska du inte göra POP {LR} utan POP {PC} (vilket jag som gammal assemblerprogrammerare tycker är ologiskt)
https://forums.raspberrypi.com/viewtopic.php?t=229793
Tack för hjälpen, även fast jag bytte Push{LR} till Push{PC} så fungerar koden inte, tror inte jag har gjort helt rätt och undra ba om du kunde kika igenom koden o ge ngn kommentar på vad jag gör fel, fattar verkligen inte hur man ska skriva detta i ARM Assembly. Hade uppskattats riktigt mycket!
Har du läst länken jag bifogade?
Ofta är det bra om man definierar sin uppgift i pseudokod innan man skriver det i språket ifråga.
Typ så här:
function Fibonacci(n)
{
if n < 2
return n
return Fibonacci(n-1) + Fibonacci(n-2)
}
Jo men så började jag, problemet är att skriva över det till assembly kod. Man måste ju skriva koden rekursivt vilket jag inte tycker är det lättaste att göra med hjälp av assembly kod.
Jag håller inte med om att rådet i inlägg #5 är användbart. När man har programmerat i assembly, som är ett lågnivåspråk, lär man sig snabbt att man inte kan förvänta sig samma enkla hantering av rekursion som i högre nivåspråk. Eftersom man måste manuellt hantera funktionsanrop, returvärden och minneshantering i assembly, blir rekursion mer komplicerat och svårare att implementera. Det kan också leda till problem med prestanda och minnesanvändning. Därför bör man vara medveten om de utmaningar och begränsningar som finns när man arbetar med lågnivåspråk som assembly, snarare än att försöka tillämpa rekursion på samma sätt som i högre nivåspråk.
Istället för att ge dig svaret till varför din implementation inte fungerar, så rekommenderar jag att du debuggar. Kolla på värdet av dina register för varje steg, när får du ett oväntat resultat? Det är så här man gör i praktiken för att hitta och lösa buggar och liknande.
Om du fastnar
Vad gör du med resultaten av dina funktionsanrop?
Jag förstår vad du säger och så. Men grejen är den att man måste använda rekursion för att lösa uppgiften. Och hur man använder rekursion i Assembly förstår jag mig inte riktigt på. Antar att man måste använda Link Registret och pusha och poppa men vet inte hur man ska använda det effektivt. Får nog skriva om hela koden och börja från början.
Dracaena skrev:Jag håller inte med om att rådet i inlägg #5 är användbart. När man har programmerat i assembly, som är ett lågnivåspråk, lär man sig snabbt att man inte kan förvänta sig samma enkla hantering av rekursion som i högre nivåspråk.
Självklart inte. När man programmerar i assembler så vet man att det är skillnad mot ett högnivåspråk. Att börja en programmeringsuppgift med att skriva pseudokod kan vara effektivt i vissa fall. Den programmeringsteknik man använder är högst individuell och Vikke kan göra som han vill med mina råd.
Jag håller absolut med om att felsöka med en debugger. Det är så man lär sig programmering på djupet oberoende av språk.
Vikke skrev:Jag förstår vad du säger och så. Men grejen är den att man måste använda rekursion för att lösa uppgiften. Och hur man använder rekursion i Assembly förstår jag mig inte riktigt på. Antar att man måste använda Link Registret och pusha och poppa men vet inte hur man ska använda det effektivt. Får nog skriva om hela koden och börja från början.
Vad använder du för programmeringsmiljö? Finns den online?
Jag använder mig av IAR Embedded Workbench IDE, den är gratis och du kan hitta den online.
Vikke skrev:Jag använder mig av IAR Embedded Workbench IDE, den är gratis och du kan hitta den online.
Installerar. Kan du skicka din Workspace-fil (*.eww)?
Då vet jag att jag använder samma parametrar som du gör.
Har du lyckats med något assemblerprogram alls? Ta en liten bit i taget, t.ex. först kolla att fib(0) och fib(1) funkar.
Peter_ skrev:Vikke skrev:Jag använder mig av IAR Embedded Workbench IDE, den är gratis och du kan hitta den online.
Installerar. Kan du skicka din Workspace-fil (*.eww)?
Då vet jag att jag använder samma parametrar som du gör.
Absolut men hur skickar man en fil? Ser bara infoga bild och länk, ingen fil knapp.
Laguna skrev:Har du lyckats med något assemblerprogram alls? Ta en liten bit i taget, t.ex. först kolla att fib(0) och fib(1) funkar.
Ja jag har haft andra assemblyprogram som har fungerat men vet bara inte hur jag ska lösa denna assemblyuppgiften.
Vikke skrev: Absolut men hur skickar man en fil?
Du kan använda https://filesharesite.com/
Peter_ skrev:Vikke skrev: Absolut men hur skickar man en fil?
Du kan använda https://filesharesite.com/
Aha okej, tack. https://www.filesharesite.com/files/202305/1683210447E310713C0BC84E66AB168C8F22D11A1A.html
Den borde fungera
Det fungerade men ditt projekt är väldigt enkelt. Ändå så har du delat upp din workspace på tre projektfiler.
<?xml version="1.0" encoding="UTF-8"?>
<workspace>
<project>
<path>$WS_DIR$\Lab2_1.ewp</path>
</project>
<project>
<path>$WS_DIR$\..\Test\Lab2_1.ewp</path>
</project>
<project>
<path>$WS_DIR$\..\Lab2_3\Lab2_3.ewp</path>
</project>
<batchBuild />
</workspace>
Jag vill gärna hjälpa till. Kan du skicka över dina tre .ewp också?
Har du löst din uppgift nu?