[ Pobierz całość w formacie PDF ]
.Za pomoc¹ s¹siedniej opcji (FPU)mo¿na tak¿e zobaczyæ zawartoœæ rejestrów, stosu i znaczników jednostkizmiennoprzecinkowej.Mo¿na tak¿e uzyskaæ czyteln¹ postaæ przek³adu w bardziej trwa³ej postaci.Nale¿y mianowicie dodaæ znacznik –B w sekcji CFLAG1 pliku g³Ã³wnego projektu(dostêpnego za poœrednictwem opcji Project|Edit Option Source) i zaznaczyæ nakarcie Tasm opcji projektu pozycje Generate wydruk i Expanded wydruk – wefekcie dla ka¿dego z plików *.cpp, wchodz¹cych w sk³ad projektu, wygenerowanyzostanie równowa¿ny plik *.asm, odzwierciedlaj¹cy przek³ad dokonany przezkompilator.Ten sam efekt osi¹gn¹æ mo¿na, uruchamiaj¹c kompilator C++Buildera zwiersza poleceñ w nastêpuj¹cy sposób:BCC32 –S modu³.cppgdzie modu³ jest nazw¹ modu³u Ÿród³owego; mo¿e okazaæ siê konieczne u¿ycieopcji –I, wskazuj¹cej œcie¿kê dostêpu do do³¹czanych plików.Wygenerowany plik.asm zawiera³ bêdzie (oprócz wygenerowanego kodu) „wykomentowane” œrednikamiinstrukcje kodu Ÿród³owego.W³¹czanie (do treœci funkcji) kodu w jêzyku asemblera odbywa siê za pomoc¹s³owa kluczowego asm, po którym nastêpuje blok instrukcji asemblerowych; pozainstrukcj¹ asm mo¿liwy jest tak¿e dostêp do rejestrów procesora – ich symbolenale¿y poprzedziæ podkreœleniem; ma to jednak sens jedynie w bezpoœrednims¹siedztwie instrukcji asm.Wydruk 4.19 prezentuje napisan¹ w asemblerzefunkcjê obliczaj¹c¹ wartoœæ silni argumentu typu int:Wydruk 4.19.Obliczanie funkcji „silnia”int Factorial(int Value){_EDX = Value;asm {push ebpmov ebp,esppush ecxpush edxmov [ebp-0x04],edxmov eax,0x00000001cmp dword ptr [ebp-0x04],0x02jl endtop:imul dword ptr [ebp-0x04]dec dword ptr [ebp-0x04]cmp dword ptr [ebp-0x04],0x02jnl topend:pop edxpop ecxpop ebp}return(_EAX);}Uwaga od t³umacza:Tê funkcjê mo¿na by³o napisaæ cokolwiek efektywniej – wersja prezentowanaponi¿ej obywa siê bez zmiennych pomocniczych w pamiêci, wykorzystuj¹c jedynierejestry EAX, ECX i EDX.Ponadto w przeciwieñstwie do prezentowanego wy¿ejpierwowzoru poni¿sza wersja obs³uguje poprawnie sytuacje wyj¹tkowe – dlaargumentu ujemnego albo zbyt du¿ego, by jego silnia zmieœci³a siê w zakresietypu int, wynikiem funkcji jest zero.O poprawnoœci jej dzia³ania mo¿na siêprzekonaæ, uruchamiaj¹c projekt AsmFactorial.bpr z za³¹czonej p³yty CD-ROM.int factorial(int val)// (C) 2001 A.Gra¿yñski{_ECX = val;asm{xor eax,eaxinc eax// w EAX znajduje siê domyœlna wartoœæ 1 dla argumentu 0test ecx,ecxjl @@invalid // b³¹d, gdy argument ujemnyjz @@done // gotowe, gdy argument zerowy@@again:mul ecx // mno¿enie EAX*ECX, wynik w EDX:EAXjc @@ovfl// je¿eli wynik mno¿enia nie mieœci siê w EDX:EAX,// ustawiany jest znacznik CFloop @@again// je¿eli wynik nie mieœci siê w ca³oœci w EAX,// to oznacza, ¿e argument jest zbyt du¿ytest edx,edxjnz @@ovfl// je¿eli EAX jest ujemne, to jest to wynik nadmiaru// (argument jest za du¿y)test eax,eaxjns @@done@@ovfl:// Tutaj sterowanie trafia, gdy wartoœæ argumentu jest zbyt du¿a,// by jego silnia zmieœci³a siê w zakresie typu int.// Niniejsza funkcja sygnalizuje ten fakt, zwracaj¹c wartoœæ zero.// U¿ytkownik mo¿e zaprogramowaæ w tym miejscu swoj¹ w³asn¹ obs³ugê.@@invalid:xor eax,eax@@done:}return(_EAX);}Je¿eli opatrzymy tê funkcjê klauzul¹ __fastcall, bêdzie ona oczekiwa³aargumentu w rejestrze EAX i w tym¿e rejestrze oczekiwany bêdzie wynik przezfunkcjê wywo³uj¹c¹.Dotychczasowe instrukcje poza blokiem asm nie bêd¹ wiêcpotrzebne (dla przejrzystoœci usun¹³em komentarze):int __fastcall factorial(int val)// (C) 2001 A.Gra¿yñski{asm{push ecxmov ecx,eaxxor eax,eaxinc eaxtest ecx,ecxjl @@invalidjz @@done@@again:mul ecxjc @@ovflloop @@againtest edx,edxjnz @@ovfltest eax,eaxjns @@done@@ovfl:// Tutaj sterowanie trafia, gdy wartoœæ argumentu jest zbyt du¿a,// by jego silnia zmieœci³a siê w zakresie typu int.// Niniejsza funkcja sygnalizuje ten fakt, zwracaj¹c wartoœæ zero.// U¿ytkownik mo¿e zaprogramowaæ w tym miejscu swoj¹ w³asn¹ obs³ugê.@@invalid:xor eax,eax@@done:pop ecx}}Zdecydowa³em siê wtr¹ciæ swoje trzy grosze, bo wygl¹da na to, ¿e autororygina³u da³ plamê: widocznie nie bêd¹c bieg³ym w programowaniu asemblerowympodgl¹dn¹³ przek³ad generowany przez kompilator i po prostu go zer¿n¹³.Aprzecie¿ jest tu mowa o rozumnej optymalizacji (przez programistê).Jako starysystemowiec nie mog³em na to patrzeæ i napisa³em tê funkcjê tak, jak nale¿a³oj¹ napisaæ.Oczywiœcie móg³bym pomin¹æ milczeniem orygina³ i zamieœciæ swoj¹ wersjê bezkomentarza; to ¿e post¹pi³em inaczej, podyktowane by³o raczej nie moimitendencjami do chwalenia siê, ale pewnymi racjami HELIONa – jeden z wpisów wKsiêdze Goœci zapytywa³ „dlaczego nasze ksi¹¿ki s¹ takie drogie, skoro my jetylko t³umaczymy?” Takie przypadki jak ten to jedna z wielu tysiêcy okazji dozademonstrowania, czym ró¿ni siê t³umaczenie od opracowania polskiej wersji [ Pobierz caÅ‚ość w formacie PDF ]

  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • listy-do-eda.opx.pl