Jeg har lavet følgende fibonacci funktion. Da den ikke virkede, sagde min instruktor at jeg skulle pushe edx på stakken før de rekursive kald, og poppe den tilsidst. Hvorfor skal jeg gøre det? Min kode er
.section .text .globl _start _start: #int main()
pushl $5 #jeg skubber 5 paa stakken som parameter til fib call fib #fib(5), call = saetter old eip addl $4, %esp movl %eax,%ebx movl $1, %eax #exit int $0x80
.type fib, @function fib: # fib(long n) # { pushl %ebp # jeg saetter min old basepointer movl %esp, %ebp # laver min nye basepointer
cmpl $2,8(%ebp) #sammenligner n med 2 jnl if #
movl 8(%ebp),%eax #er den skarp mindre end saa skub den i eax
jmp end_if #og gaa til end_if
if: #if(n => 2)
pushl %edx movl 8(%ebp),%eax #skubber min fib parameter paa subl $1,%eax #traekker en fra pushl %eax #skubber eax paa stakken call fib #kalder rekursiv addl $4,%esp #overskriver movl %eax,%edx #flytter n-1 over i edx movl 8(%ebp),%eax #skubber parametren i eax subl $2,%eax #traekker to fra pushl %eax #Skubber eax paa stakken call fib #kalder rekursiv addl $4, %esp #overskriver
addl %edx, %eax #(n-1) + (n-2) (eax = resultat)
popl %edx
end_if: # return fibonacci tal for n movl %ebp,%esp #jeg bryder stakken ned popl %ebp # ---------||--------- ret # }
Jeg undskylder for at jeg poster den i C/C++, men det var det jeg fandt var tættest på dette niveau jeg programmere til.
Nu ved jeg ikke hvilket miljø du arbejder med, men det du effektivt gør, er jo at du bevarer edx værdien henover funktionskaldet. Hvis miljøet du arbejder i er afhængig af edx værdien; ville det netop være det sådan en pop/push operation man ville bruge for at bevare den.
jeg arbejder i et Linux miljø. Hmm ja jeg bevarer. Men bliver min edx brugt i andre sammenhæng? Det gør den vel nok. ALtså jeg bruger den selv, men hvordan kan jeg bevare den ved at smide den på stakken og aldrig smide den ind i edx igen.
Du bevarer den jo netop ved at du popper den tilbage i edx til sidst;
popl %edx
Jeg kender intet til Linux; men det er ikke usandsynligt at systemet forventer nogle eller alle registre er uændret efter programkørsel. Ydermere, hvis du kalder din funktion fra C eller C++, skal du overholde de calling conventions, der gælder.
Ah ok. popl betyder altså at jeg popper det der er øverst på stakken tilbage i, her, edx registeret. Jeg kalder den ikke min funktion fra C eller C++. Men det er vel bare sådan det skal være.
Jeg forstod det ikke på daværende tidspunkt, men når jeg læser dit svar igennem igen driis, så kan jeg godt forstå det :) Så smid et svar driis og du får point :)
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.