Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Problem sa argumentima funkcije

[es] :: Pascal / Delphi / Kylix :: Problem sa argumentima funkcije

Strane: 1 2

[ Pregleda: 6774 | Odgovora: 33 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

PeraKojotSuperGenije
Sasa Popovic
Beograd

Član broj: 44507
Poruke: 126
*.71.eunet.yu.



Profil

icon Re: Problem sa argumentima funkcije11.02.2005. u 00:33 - pre 233 meseci
Kod ima oko 1500 linija, pa mi stvarno nije zgodno da eliminisem metodu po metodu...

Kao sto vec rekoh, dodavanje neke od gore navedenih direktiva mi resava stvar! Sta je bilo uzrok pocetnog problema i dalje ne znam. Ako je neko zainteresovan da dobije kod, da se sa njim "poigra" ne bi li nasao uzrok problema neka mi pise na mail.


Sendvic uvek pada na namazanu stranu!
 
Odgovor na temu

neor
Nenad Orlovic

Član broj: 26828
Poruke: 74
*.metrohive.net.



Profil

icon Re: Problem sa argumentima funkcije11.02.2005. u 07:01 - pre 233 meseci
Citat:
PeraKojotSuperGenije:
Kao sto vec rekoh, dodavanje neke od gore navedenih direktiva mi resava stvar! Sta je bilo uzrok pocetnog problema i dalje ne znam.


To je opasno resenje.
Promena konvencije u ispravnom programu koji ne poziva spoljne funkcije ne sme da pravi razliku. Problem mora biti u necem drugom i samo ceka da se ponovo pojavi na drugom mestu.
Posto je to koliko vidim rekurzija, da nisi mozda ostao bez steka? Da ga povecas malo?
 
Odgovor na temu

PeraKojotSuperGenije
Sasa Popovic
Beograd

Član broj: 44507
Poruke: 126
*.22.eunet.yu.



Profil

icon Re: Problem sa argumentima funkcije11.02.2005. u 13:43 - pre 233 meseci
Citat:
Posto je to koliko vidim rekurzija, da nisi mozda ostao bez steka?

Zar u ovom slucaju ne bi "pukao" program sa porukom "Stack overflow error..."(ili tako nesto)?
Sendvic uvek pada na namazanu stranu!
 
Odgovor na temu

neor
Nenad Orlovic

Član broj: 26828
Poruke: 74
*.metrohive.net.



Profil

icon Re: Problem sa argumentima funkcije11.02.2005. u 15:02 - pre 233 meseci
Trebalo bi ali mozda negde imas try...except koji uhvati taj exception i ne obradi ga
 
Odgovor na temu

PeraKojotSuperGenije
Sasa Popovic
Beograd

Član broj: 44507
Poruke: 126
*.242.EUnet.yu.



Profil

icon Re: Problem sa argumentima funkcije11.02.2005. u 17:02 - pre 233 meseci
Neor mislim da me nisi razumeo. Meni se u toku izvrsavanja programa nikad ne javlja "Stack overflow error...", a na tvoje pitanje
Citat:
Posto je to koliko vidim rekurzija, da nisi mozda ostao bez steka?
, ja pitam: " Da li se u situaciji kada program ostaje bez steka uvek javlja "Stack overflow error"? Ja mislim da da.
Sendvic uvek pada na namazanu stranu!
 
Odgovor na temu

morlic
Milos Orlic
Beograd

Član broj: 6081
Poruke: 735
*.3.eunet.yu.



+1 Profil

icon Re: Problem sa argumentima funkcije12.02.2005. u 00:57 - pre 233 meseci
Posto vidim da nema rezultata nasih saveta ne preostaje nista drugo nego da
upotrebimo tesku artiljeriju, u ovom slucaju CPU prozor koji omogucava da
se vidi sta se tacno desava u memoriji i u registrima procesora. Napravio sam
primer koji se sastoji od jedne forme i dugmenceta na njoj, na koji kada se
klikne poziva se procedura YourTurn koja dalje poziva sledecu proceduru i tako
dalje. Cilj je da pokazem nacin na koji se prosledjuju argumenti do procedure
i kako mozemo proveriti ispravnost prenetih podataka. Postoje jos nekoliko metoda
kako se sve ovo moze uraditi, ali sam izabrao ovaj jer je malo zanimljiviji.

Potrebno znanje:

Stek, postavljanje prekida (breakpoint) i jos po nesto :)

U opcijama projekta na stranici compiler treba postaviti:

Optimization=iskljuceno
Stack frames=iskljuceno
Range checking=iskljuceno
Overflow checking=iskljuceno

Debug information=ukljuceno

i uraditi Build projekta.

Kod primera:

Code:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    procedure RootSearchAB(alpha, beta: integer; const depth: byte; var n,
      x, y: byte);
    procedure YourTurn;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
procedure TForm1.RootSearchAB(alpha, beta: integer; const depth: byte; var n, x, y: byte);
begin
  n:= depth;
end;

procedure TForm1.YourTurn;
Var
  n, x, y, depth: byte;
begin
   depth:= $63; // Decimalno 99
   n:= $11;     // Decimalno 17
   x:= $22;     // Decimalno 34
   y:= $33;     // Decimalno 51
   RootSearchAB(-maxint-1, maxint, depth, n, x, y);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  YourTurn;
end;

end.



Postavljamo breakpoint na liniju:

depth:= $63;

i pokrenemo program. Kliknemo na button1 i program prekida izvrsavanje
i prikazuje se Delphi editor sa obelezenom linijom prekida.

Sada pritiskamo ctrl+alt+c i dobijamo CPU window kao na slici 1 koju
sam poslao. Od crvene tacke na dole mozemo videti kako promenjive
depth, n, x i y dobijaju vrednosti:

Code:

mov byte ptr [ebp-$08], $63


Ovo nije nista drugo do naredba da se vrednost $63 (decimalno 99) stavi na
lokaciju u memoriji na adresi [ebp-$08] (u pitanju je stek memorija u
kojoj se nalaze izmedju ostalog i lokalne promenjive. Ovo pravilo ne vazi
uvek ali da sada ne ulazim u detalje). Isto se desava i sa
ostalim promenjivama.

Slika1:



Od linije Unit1.pas.43 u CPU prozoru pocinju da se desavaju zanimljive
stvari. Krece pakovanje podataka za poziv procedure
RootSearchAB(). Prevodilac (compiler) pakuje argumente za
poziv procedure tako sto prva dva argumenta (alpha i beta)
stavlja u registre, dok ostale parametre pakuje na stek sa
leva na desno. Prvo pakuje na stek:

Code:

mov al,[ebp-$08]   // Vrednost promenjive depth se kopira u
                   // registar procesora al (1 byte register)
push eax           // Vrednost registra eax se smesta na stek
                   // al registar je deo eax registra


ovo je zbog toga sto je depth prosledjen kao const i procedura
koju pozivamo zapravo dobija kopiju vrednosti depth promenjive
i na taj nacin nece moci da izmeni originalnu depth promenjivu
koja se nalazi na lokaciji [ebp-$08].

Treba sa F7 ici kroz naredbe dok se ne stigne do linije

Code:

push eax


(kao na slici 2) koja je pomenuta gore.

Slika2:



Ako pogledamo u gornjem desnom delu
CPU prozora vrednosti registra procesora u tom trenutku videcemo da je u
eax registru vrednost $008C1E63. Posto je depth smesten u al
registar treba gledati samo zadnje dve cifre a to iznosi $63 sto i jeste
vrednost promenjive depth. Za sada je sve kako treba.

Ostale promenjive se prosledjuju kao var sto znaci da treba
omoguciti proceduri koju pozivamo da promeni njihove vrednosti.
Kompajler ovo radi tako sto prosledjuje adrese promenjivih u
memoriji proceduri koju zovemo kako bi ona eventualno mogla da
trajno upise nove vrednosti:

Code:

lea eax,[ebp-$05]   // Izracunaj efektivnu adresu promenjive n
                    // i izracunatu adresu stavi u eax registar
push eax            // stavi vrednost eax registra na stek


i isto tako i za x i y promenjive.


Sada dolazimo i do alpha i beta argumenata. Kompajler ce
staviti ove vrednosti da se prenose do procedure RootSearchAB() u
registrima ecx i edx kako i treba po konvenciji register.
Sledeci interesantan korak je i pozivanje procedure RootSearchAB().
Potrebno je pritiskati F7 (korak po korak) dok ne dodjemo do tacke kao na
slici 3:

Slika3:



To je trenutak kada se u promenjivu n stavlja vrednost promenjive
depth. Linija:

Code:

mov dl,[ebp+$14]


prebacuje vrednost promenjive depth u registar dl koji je deo edx
registra. To je trenutak kada mozemo u gornjem desnom uglu CPU prozora pogledati
edx registar i videti da sadrzi vrednost $63 (zadnje dve cifre) sto znaci da
promenjiva ima ispravnu vrednost. I tako dalje.

Ovaj koliko toliko prost primer pokazuje kako funkcionisu pozivi procedura i kako
se prosledju parametri. Ako stavimo da procedura RootSearchAB() koristi
stdcall prosledjivanje onda bi i alpha, beta promenjive isle preko steka
a ne preko registara. Imali bi smo umesto:

Code:

mov ecx,$7fffffff
mov edx,$80000000


sledeci kod:

Code:

push $7fffffff
push $80000000


sto na oko i nije neka velika razlika dokle god se ne koriste dll-ovi. Sa njima ova
razlika postaje velika jer ako procedura u dll-u ocekuje sve argumente na steku a dobije
prva dva u registrima onda imamo veliki problem, koji se najcesce rezultuje korupcijom steka.

Sada bi PeraKojotSuperGenije trebao da primeni ovu tehniku na svom programu uz neke sitne izmene
(kao sto je n:=depth na pocetku procedure kako bi vec tu mogao lakse iz CPU prozora da proveri
vrednost koja je prosledjena).

Eto materijala za pocetak pa da vidimo, posalji slike CPU prozora u ove tru faze koje sam
pomenuo :) pa da analiziramo.

Izvinjavam se ako sam nesto izostavio, ali materija je obimna a ja sam probao da sve to sabijem
u par recenica, tako da je mnogo toga ostalo bez objasnjenja.

Ako ima pitanja u vezi sa ovim postom, slobodno...
Prikačeni fajlovi
 
Odgovor na temu

sasas
Saša Slavnić
radim za neke švabe

Član broj: 35478
Poruke: 617
195.246.3.*



Profil

icon Re: Problem sa argumentima funkcije12.02.2005. u 07:33 - pre 233 meseci
off-topic:
morlicu, svaka cast na ovako detaljnom objasnjenju. samo bih ti predlozio da svoj post prebacis u novu temu i da je topujes, jer je univerzalna i bogami vrlo korisna.

on-topic:
imam utisak da svi razmisljate u pogresnom smeru. delphi garantovano 100% dobro generise kood. to nije kompajler koji je u nekoj alpha/beta fazi, pa da se nekom analizom generisanog kooda uoce bugovi u kompajleru.

Citat:
neor: Probaj da izbacis iz tog koda sve sta mozes (narocito pozivi finkcija koje nisi ovde dao) a da se problem i dalje javlja i stavi onda ovde neki kod koji moze da se kompajlira pa da moze da se proba.


ovo je najkorisniji savet u celoj diskusiji. Znam da je tesko i dosadno, ali moras svesti program na razumnu velicinu (a da i dalje imas bug), pa tek onda traziti pomoc. u stvari, kad to uradis, siguran sam da ti saveti nece ni trebati, jer ces sam videti eventualne greske u algoritmu.

just my 0.02$

ss.

When something is hard to do, then it's not worth doing.
 
Odgovor na temu

morlic
Milos Orlic
Beograd

Član broj: 6081
Poruke: 735
*.117.EUnet.yu.



+1 Profil

icon Re: Problem sa argumentima funkcije15.02.2005. u 16:53 - pre 233 meseci
Dzabe ja pisem kad PKSG nema nameru da proba ovo, a mi se trudimo da resimo...
 
Odgovor na temu

PeraKojotSuperGenije
Sasa Popovic
Beograd

Član broj: 44507
Poruke: 126
*.9.eunet.yu.



Profil

icon Re: Problem sa argumentima funkcije15.02.2005. u 17:19 - pre 233 meseci
Stvarno se izvinjavam. Imam nameru, ali trenutno nemam vremena. Cim odradim javicu se.
Sendvic uvek pada na namazanu stranu!
 
Odgovor na temu

morlic
Milos Orlic
Beograd

Član broj: 6081
Poruke: 735
*.58.eunet.yu.



+1 Profil

icon Re: Problem sa argumentima funkcije15.02.2005. u 21:15 - pre 233 meseci
Ok :) strpljivi smo, nije da nismo... :)
 
Odgovor na temu

PeraKojotSuperGenije
Sasa Popovic
Beograd

Član broj: 44507
Poruke: 126
*.70.eunet.yu.



Profil

icon Re: Problem sa argumentima funkcije20.02.2005. u 15:22 - pre 233 meseci
Napravio sam screenshotove u kriticnim momentima(u spajalici su). Na mojih 15 incha je bilo malo guzva pa ne znam da li se svi potrebni delovi cpu i source prozora vide.

1) Vidi se kako depth (depth je polje klase) dobija vrednost.
2) Neposredno pre poziva RootSearchAB.
3) Neposredno po ulasku u RootSearchAB.
4) Neposredno pre ulaska u NegaMaxAB.
5) Neposredno po ulsaku u NegaMax.

Sada se nenormalne vrednosti (za depth) javljaju tek u NegaMax Funkciji!?!
Sendvic uvek pada na namazanu stranu!
Prikačeni fajlovi
 
Odgovor na temu

PeraKojotSuperGenije
Sasa Popovic
Beograd

Član broj: 44507
Poruke: 126
*.70.eunet.yu.



Profil

icon Re: Problem sa argumentima funkcije20.02.2005. u 15:26 - pre 233 meseci
Ovde su preostale 3 slike. Morao sam ovako zbog ogranicenja od 200k!
Sendvic uvek pada na namazanu stranu!
Prikačeni fajlovi
 
Odgovor na temu

morlic
Milos Orlic
Beograd

Član broj: 6081
Poruke: 735
*.78.EUnet.yu.



+1 Profil

icon Re: Problem sa argumentima funkcije21.02.2005. u 00:17 - pre 233 meseci
Kako se sada menjaju vrednosti? :)

Na pogresnim si mestima "slikao" ekran:

Slika 1) Pritisni jos dva puta F7 dok si na CPU prozoru, pa tek onda slikaj kako bi u prozoru za pregled registara videli vrednost al registra koji drzi vrednost depth.

Slika 3) jednom F7 pa slikaj

Slika 4) jednom F7 pa slikaj

Slika 5) jednom F7 pa slikaj

Ajde prvo probaj sliku br1 da vidimo da li je ok, pa ces onda i ostale.
 
Odgovor na temu

morlic
Milos Orlic
Beograd

Član broj: 6081
Poruke: 735
*.141.eunet.yu.



+1 Profil

icon Re: Problem sa argumentima funkcije02.03.2005. u 21:36 - pre 232 meseci
Ajde kada stignes posalji barem sliku br1!
 
Odgovor na temu

[es] :: Pascal / Delphi / Kylix :: Problem sa argumentima funkcije

Strane: 1 2

[ Pregleda: 6774 | Odgovora: 33 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.