Zine.net online

Witaj na Zine.net online Zaloguj się | Rejestracja | Pomoc
w Szukaj

mgrzeg.net - Admin on Rails :)

Fibonacci a WinDbg

Mało kto o tym wie, ale WinDbg oferuje całkiem rozbudowane środowisko skryptowe pozwalające na automatyzację niektórych zadań podczas analizy. Dzisiaj krótki przykład wyliczania n-tego elementu ciągu Fibonacciego, wykorzystując do tego celu WinDbg.

Wersja rekurencyjna

Chyba najciekawsza ze względu na to, jak realizowana jest rekurencja :)
Tworzymy plik fibo_recur.wds o zawartości:

$$ fibo_recur.wds - oblicz n-ty element ciagu Fibonacciego
.block
{
 .if (${$arg1} > 1)
 {
  $$>a<fibo_recur.wds ${$arg1}-1
  r $t2 = @$t1
  r $t1 = @$t1 + @$t0
  r $t0 = @$t2
 }
 .else
 {
  r $t0 = 0
  r $t1 = 1
 }
 .printf "Fibonacci(%p) = %p\n", ${$arg1}, @$t1
}

po czym wykonujemy go z poziomu WinDbg:

0:000> $$>a<fibo_recur.wds 6

W rezultacie otrzymamy

Fibonacci(0000000000000001) = 0000000000000001
Fibonacci(0000000000000002) = 0000000000000001
Fibonacci(0000000000000003) = 0000000000000002
Fibonacci(0000000000000004) = 0000000000000003
Fibonacci(0000000000000005) = 0000000000000005
Fibonacci(0000000000000006) = 0000000000000008

Kilka uwag:
1. Gdybyśmy mieli więcej argumentów, to w skrypcie wpisujemy kolejne $argn (np. $arg2), do których odwołujemy się poprzez ${$argn} ($arg1 to alias, którego wartość uzyskujemy dzięki interpreterowi aliasów (${}).
2. Kolejne argumenty przekazane do skryptu oddzielane są spacjami

0:000> $$>a<skrypt.wds 6 8

3. Przy uruchamianiu bez parametrów

0:000> $$><skrypt_bez_param.wds

4. .block, .else, .printf (podobnie jak wiele innych poleceń) bez trudu można odnaleźć w helpie do WinDbg.
5. $t0, $t1, etc. to 'pseudorejestry' - 'zmienne skryptu'. Przy odwoływaniu się do wartości pseudorejestrów dodajemy "@", np.: @$t1
6. $$ wprowadza komentarz

Wersje iteracyjne

a. Wersja z .for

$$ fibo_iter_for.wds - oblicz n-ty element ciagu Fibonacciego
.block
{
 .if (${$arg1} > 1)
 {
  r $t0 = 0
  r $t1 = 1
  .for (r $t3 = 2;
        @$t3 <= ${$arg1};
  r $t3 = @$t3 + 1)
   {
    r $t2 = @$t1
    r $t1 = @$t1 + @$t0
    r $t0 = @$t2
   }
 }
 .printf "Fibonacci(%p) = %p\n", ${$arg1}, @$t1
}

b. Wersja z .while

$$ fibo_iter_while.wds - oblicz n-ty element ciagu Fibonacciego
.block
{
 .if (${$arg1} > 1)
 {
  r $t0 = 0
  r $t1 = 1
  r $t3 = ${$arg1}
  .while (@$t3-1)
   {
    r $t2 = @$t1
    r $t1 = @$t1 + @$t0
    r $t0 = @$t2
    r $t3 = @$t3 - 1
   }
 }
 .printf "Fibonacci(%p) = %p\n", ${$arg1}, @$t1
}

Oba skrypty wykonujemy tak, jak miało to miejsce w przypadku wersji rekurencyjnej, np. (wersja z .while):

0:000> $$>a<fibo_iter_while.wds 6

Tym razem jednak, w rezultacie otrzymamy

Fibonacci(0000000000000006) = 0000000000000008

Dobrej zabawy! :)

Opublikowane 6 czerwca 2012 19:30 przez mgrzeg
Filed under: ,

Powiadamianie o komentarzach

Jeżeli chciałbyś otrzymywać email gdy ta wypowiedź zostanie zaktualizowana, to zarejestruj się tutaj

Subskrybuj komentarze za pomocą RSS

Komentarze:

Brak komentarzy

Co o tym myślisz?

(wymagane) 
(opcjonalne)
(wymagane) 

  
Wprowadź kod: (wymagane)
Wyślij

Subskrypcje

W oparciu o Community Server (Personal Edition), Telligent Systems