no par dotazov
1. nezaskodilo by par obrazokv (aspon jeden hocijaky na lepsiu predstavu)
2. myslim ze clanok bude citat viac ne-assemblistov takze nejaky uvod do assembly by mohol byt ;o) , prehlad registrov, ako funguje adresovanie pamate cez ne, ako je to linuxe podrobnejsie ako to funguje proste taky guide step by step assembleru v linuxe a asembly jazyku celkovo pre zaciatocnikov hlavne tie obrazky!!! :o))
3. dobry clanok pacil sa mi, ale hlavne tie obrazky na lepsiu predstavu pre ne-assemblistov lebo s to tazko cita a este tazsie rozumie :o)
K prvnimu prispevku, dekuji za pripominku s obrazky, do dalsich dilu serialu je pridam, dobry napad, zejmena k debuggingu.
Ad dalsi ;), uvod do assembleru se netyka primo linuxu a ja mel dohodnuty serial o programovani v Assembleru v linuxu, tzn. v jeho odlisnostech, ale neni problem napsat teoreticky uvod...
1) K cemu NASM pro PPC, kdyz tam existuje GAS?
2) Na PPC samozrejme jedine GAS :-)
AT&T syntaxe pouzita v GASu sice na prvni pohled vypada jinak nez Inteli, kterou predpokladam pouziva NASM. Ale to rozhodne neznamena, ze by byla mene logicka, hur pouzitelna, nebo tak neco. Na unixech je to proste standard a vyplati se ji umet uz treba proto, kdyz chcete psat inline assembler v C-ckovych programech (uprimne receno - psat _cely_ program v asm je velmi neobvykle).
V GASu mate dve moznosti:
1) pouzit standardni preprocesor cpp - staci kdyz zdrojak ulozite jako "neco.S" namisto "neco.s" a muzete makrovat az do aleluja ;-)
2) pouzit GAS direktivy .macro/.endm ktere take umi makra, pochopitelne i s parametry a podobnymi samozrejmostmi.
Takze v tomhle myslim GAS neni nijak horsi nez NASM, nebo NASM umi jeste neco dalsiho?
... ale neodpustim si:
1. assembler nie je programovaci jazyk, je to proste... assembler ;-)
2. assembler je vseobecny pojem, cize pisat to s velkym A je to iste ako pisat Programovaci Jazyk C ;)
ale inak sa mi clanok pacil, som zvedavy na pokracovania, asm pod linom je dost nepokryta oblast. Co sa tyka tych dotazov na pictures, popis asm... ludia, na nete je toho spusty, naco opakovat stale dokola tie iste infos, teraz mame/mate moznost sa dozvediet nieco, co zase az tak bezne nie je.
No, kdyz uz si nechcete odpoustet, tak vezte, ze "assembler" je program, ktery prevadi zapis jazyka symbolickych adres (srozumitelne mnemonicke popisy instrukci) do strojoveho kodu ciloveho procesoru (cili vznesene receno je to prekladac). Ze se oznaceni "assembler" ustalilo pro onen vlastni JSI je vec jina...
Obrazky mi nechybi (stejne je mam vypnuty :-), natoz pak rozebirani zakladu strojoveho kodu x86 (zkuste http://docs.linux.cz/asm_gasparovic/zaklad.htm . Nebo http://www.zezula.net/cz/teach/assembler_01.html ... coze, obrazky? http://www.maturita.cz/pocitace/mikroprocesory.htm , nebo google :-).
Clanek zuper, obcas me zajimalo, jak to ten linux resi, a tohle vypada presne jako odpoved ;-).
Ohledne slovicka programovaci jazyk - http://www.vood.mysteria.cz/programovani/C1.htm - vyhledat LLL. (Pro me) assembler je jazyk programovaci, plne v nizke urovni procesoru.
Opravdu je v paměti vždy jen jedna stránka programu? Co když je smyčka na hranici stránek, tak se pořád střídavě nahrávají z disku ty dvě stránky, které ji obsahují? To snad ne... Proč je program tedy zaváděn do 128MB, když je v paměti vždy jen jedna stránka (4kB). Nemyslí se tím stránkováním spíš něco jiného?
Proč je k adrese 0xBFFFFFFF připsáno "hranice 4 GB", když 4GB=0xffffffff?
Nemá v tom autor trochu hokej?
1) autor v tom evidentne drobatko hokej ma.
2) stranek programu je v pameti tolik kolik je treba a kolik se vejde. Pokud uz nektere nejsou treba nebo je nutne uvolnit misto, tak jsou dve moznosti: a) kdyz se jedna o kod, tak se zahodi, protoze se v pripade potreby muze opet dohrat z binarky na disku. b) pokud se jedna o data, odlozi se do swapu.
3) horni hranici adresniho prostoru zabira kernel. Neni sice pristupny pro cteni z userspace, ale je tam a zabira misto.
4) co se tyka adresy 0xBFFF... tak tam obvykle zacina stack, neboli zasobnik.
1) Nerekl bych drobatko. Na druhou stranu neni jediny.
2) Stranky programu se nahravaji, kdyz jsou potreba (je tedy pravda ze nemusi byt nahrane vsechny). Kdyz globalne dojde pamet, coz se casto nestane po mnoho behu programu, tak se nejaka stranka nejakeho programu odmapuje a odswapuje nebo zahodi. (Podrobny algoritmus je dost slozity).
3) Spravne. Presneji, kernel zabira misto od 0xC0000000 do 0xFFFFFFFF ve standartni konfiguraci kernelu.
4) Zasobnik sice zacina na 0xBFFFFFFF, ale jak je na Intelu zvykem roste DOLU. Takze treba pokud pouzivas 12KB zasobniku, je zasobnik od 0xBFFFFFFF do 0xBFFFD000.
5) Kde vzal autor 128MB netusim.
Na zacatku sa z programu nahra do pameti jenom jedna stranka. Kdyz jsou potreba dalsi stranky, dohrajou sa (eventualne se neco z pameti vyhodi aby se udelalo misto). Cili na zacatku tesne pred spustenim programu je v pamati opravdu jenom jedna stranka z celeho programu (ostatni se prihrajou pozdeji).
Jeste k tomu kernelu: kernel v adresnim prostoru procesu muze zabirat az 2 GB (zalezi na konfiguraci jadra) ale u x86 (teoreticky) jadro nemusi zabirat nic (nevim vsak presne, jak je to resene, patrne pri teto konfiguraci volani jadra zpusobi prepnuti procesu na nejakej "kernel process", ktery pozadavek obslouzi) nebo jenom par MB (kod + datasegment jadra jsou v adresnim prostoru procesu, ostatni datove struktury uz ne).
Troufnu si tvrdit, ze GCC to umi lip nez to zvladnete rucne ;-) Nebo budete pocitat i s takovymi detaily, jestli je vyhodnejsi udelat "push %eax" nebo radeji "mov %eax, (%esp); sub %esp, 4"? GCC tohle vsechno vi a umi zohlednit.
Ale nechci se vas dotknout, mozna to skutecne GCC trumfnete :-)
Gcc generuje ne uplne dobry kod. Typicky pripad, ktery gcc nezvladne zoptimalizovat je, kdyz mate ve funkci rychlou casto pouzivanou cestu, ktere staci k vykonani registry, ktere neni treba ukladat (eax, ecx, edx) a druhou pomalou malo pouzivanou cestu, ktera potrebuje spoustu mista na zasobniku a vsechny registry. Gcc da alokaci mista zasobniku a ukladani registru na zacatek funkce pred obe cesty, ne jen do te pomale, jak by to bylo lepsi.
Quake se zrychlil pry 2x, kdyz se prepsaly nejdulezitejsi funkce v assembleru.
Rucne schedulovat instrukce neni problem --- pro Pentium a Pentium 2 jsou ta pravidla jednoducha. Pro Pentium 4 trochu slozitejsi (a ne tak ucinna), ale ne o moc.
Ja jsem zase psal smycku co prepocitava alfa kanaly pri generovani pismenek v Linksu.
Delilo se tam obrovske mnozstvi cisel (cele pole) 255. A protoze vstupni hodnota mohla byt max. 255*255=65025, tak se mi podarilo kod deleni vymyslet o takt rychleji, nez to dokaze GCC. GCC predpoklada, ze vstupni hodnota je az 65535, a tak generuje o takt pomalejsi kod, nez by mohlo.
Vzhledem k tomu, ze v jazyce C se neda nijak nadeklarovat short a rict, ze jeho maximalni hodnota bude 65025, nemuze GCC z principu generovat optimalni kod.
Detaily pouziti MMX a SSE se celkem dost lisi procesor od procesoru, pokud vas tahle problematika zajima, stahnete si ze stranek Intelu a AMD dokumenty popisujici optimalizaci pro jejich procesory - aspon AMD tam ma spoustu prikladu, jak efektivne pocitat napr. 3d transformace, porovnani jak funguji ruzne implementace memcpy - rep movsb pocinaje a mmx+prefetch konce atd.
Jsem asi hnidopich, ale na zacatku melo byt tucnym pismem uvedeno, ze se jedna o Linux na x86. Mozna je to profesionalni deformace, jelikoz pracuji i s jinymi architekturami. Kazdopadne formulace "Pro systémová volání se v Linuxu používá přerušení int 0x80." je bez uvedeni architektury nesmysl.
Dal:
> Když program zapíše na nealokované místo, bude
> proces ukončen (SIGKILL kernelu).
Tesne vedle - kernel ho sejme signalem SIGSEGV
> Linux však podporuje mnoho formátů spustitelných
> souborů, my se zaměříme třeba na formát ELF -
> executable and linkable format.
Jsem rad, ze padla volba "třeba na formát ELF" - on je totiz nejdulezitejsi a prakticky na Linuxu nejvic pouzivany :-)
> Adresa 0x08048000 [... sem se zavede program]
Kde se tohle cislo vzalo? Muze byt jine?
- Ano muze byt jine a je urceno linkerem pri sestavovani programu. A kde se ho kernel dozvi? V hlavicce ELFu.
> Program obvykle bývá nahrán do 128 MB adresového
> prostoru.
Zase vedle - ten vas konkretni program bude zacinat na adrese 0x08048000, cili tesne _nad_ 128 MB
No nic, necham prudeni a jdu na obed :-))
Nechtel byste neco zajimaveho zase napsat vy sam ? Nepresne extrakty man & HOWTO a jeste monokulturni x86-linux centrismus :-) mi nijak zajimavy neprijde... Myslim ze hodnotne informace hodne publikovani jsou ty s vysokou (autorovou) pridanou hodnotou z praxe a multiplatformnim nadhledem (nebo jeste lepe i mimo linux-only kernel).
> > Když program zapíše na nealokované místo, bude
> > proces ukončen (SIGKILL kernelu).
> Tesne vedle - kernel ho sejme signalem SIGSEGV
Tesne vedle ;) kernel posle procesu signal SIGSEGV, tj. zavola se handler tohoto signalu. To ze default handler proces zabije je jina vec :) Muzete si napsat handler svuj a osetrit to jak chcete, muzete dokonce zpusobit dalsi SIGSEGV v samotnem handleru a volat ho tak rekurzivne treba 1000x ;)
Co je zajimavejsi, v linuxu muzete uvnitr handleru SIGSEGV zjistit adresu na ktere doslo k chybe, zavolat na ni mmap, vratit se a pokracovat v behu programu ... otazkou je k cemu je to dobre, protoze obvykle pokud program spacha SIGSEGV, je to zpusobeno chybou kterou zevnitr tezko opravite.
Vyjimkou je User-Mode Linux a podobne aplikace, ktere diky teto vlastosti mohou provadet vlastni strankovani.
Tady nejde o navratovou adresu, tj adresu chybne instrukce (mimochodem, myslim ze by to bylo tezke, protoze se jedna o zasobnik KERNELU). Tady jde o adresu mista v pameti, jehoz cteni/zapis vyvolalo chybu. Tj. pokud sigsegv nastalo diky radku c=a[i], zjistite adresu a+i a muzete na tuto adresu primapovat pamet, takze radek c=a[i] muze probehnout bez chyby.
delate, jako by to byla vysada linuxu :-) snad kazdy operacni system umoznuje nejakym zpusobem reseni vyjimek. at uz je to SEH a VEH pod nt nebo signal handlery pod *nixama a je snad logicke, ze u nekterych vyjimek muzeme (treba po zmene atributu stranky a pripadne alokaci pameti - takto jsou treba reseny samoexpandujici stacky - guard pages) pokracovat v cinnosti
Ty guard pages --- to mi pripomina, jak jsem portoval gcc na OS/2. Guard pages jsou strasna prasarna, ktera komplikuje kompilaci kodu --- pokud funkce obsahuje lokalni promenne delsi nez jedna stranka, tak hrozi, ze sahne o dve stranky pod posledne namapovanou stranku zasobniku a cely program spadne. Proto se do ramu musi na kazdou stranku napsat. Totez plati pro alloca --- je treba se dotknout tech alokovanych mist v sestupnem poradi.
Na Linuxu to potreba neni, ten vzdycky alokuje a namapuje pamet pri page faultu nad esp.
>Ty guard pages --- to mi pripomina, jak jsem portoval gcc na OS/2.
>Guard pages jsou strasna prasarna, ktera komplikuje kompilaci kodu
>--- pokud funkce obsahuje lokalni promenne delsi nez jedna stranka,
>tak hrozi, ze sahne o dve stranky pod posledne namapovanou stranku
>zasobniku a cely program spadne. Proto se do ramu musi na kazdou
>stranku napsat. Totez plati pro alloca --- je treba se dotknout
>tech alokovanych mist v sestupnem poradi.
ano. kazdopadne toto je zalezitost prekladace a vetsinou se resi nejakymi
pomocnymi fcemi v prologu (treba check_esp), ktere manuelne donuti
stack expandovat. nerikam, ze je to koser, nicmene -
mit vice jak 4 kila na zasobniku, to uz o necem svedci. nevim, mozna jsem
prilis ovlivnena kernel modem, ale tam je stack maximalne 12 kilo velky a
kdyz jste nekde hluboko v i/o stacku, nemuzete si se zasobnikem dovolit
moc. ale od toho tu je preci bss sekce (pridat static).
mit tolika mista lokalne ve fci spise (IMHO) ukazuje, ze by mela byt
rozdelena na vice podfci, kde onen problem odpada ...
>Na Linuxu to potreba neni, ten vzdycky alokuje a namapuje pamet pri
>page faultu nad esp.
pamet prideli kdekoliv, nebo pouze v rozsahu zasobniku? rozsah zasobniku
je nekde zapsan? treba v pe filu je polozka commit/reserve co se tyce
zasobniku.
Jisteze neni zrovna kulturni alokovat na zasobniku pole o velikosti 4k --- jenomze userspace programy museji fungovat vzdy, kdyz splnuji specifikaci, ne jen tehdy, kdyz jsou napsany kulturne. Proto je treba pri pouziti guard pages po kazdem volani alloca zjistit velikost a prohrabnout alokovane pole smerem dolu. Stejne tak to kompilator musi pri alokaci lokalnich promennych zjistovat, zda nepresahnou 4k a pripadne se zasobniku dotknout jeste drive nez je zacne pouzivat.
K tomu > 4k na zasobniku - kernel je v tomto pripade trosku extrem, pomerne kompaktni "program", u ktereho lze uhlidat, ze se cely kod k zasobniku bude chovat slusne a lze tedy rict, ze celkova velikost stacku bude 8k (nebo 12k, nevim, jestli se to posledni dobou nezmenilo).
Nicmene user-programy obsahuji tuny knihoven, o kterych nikdo nic nevi, a proto je by default omezena velikost stacku na 2MB (aspon v pthread-programech na starsich kernelech). Tedy neni duvod, proc si nevytvorit na stacku neco ala char path[MAX_PATH], na coz se zrovna v linux-kernelu pouziva dynamicka alokace get_page...
Samozrejme nejake slusne pravidla jsou vhodne (psat takhle rekursivni funkce atd.), nicmene povazovat to predem za prasarnu mi prijde prehnane.
No jo no jo, dyt ja vim ;-)
V sighandlerech se vubec daji delat zajimave veci. Namatkou:
1) Backtrace - jakmile mi program nekde zhuci, tak v handleru segfaultu muzu vypsat backtrace, abych se dozvedel, kde k tomu doslo. Bohuzel s nastupem novych formatu ladicich informaci to prestava byt trivialni zalezitost.
2) Osetrovani chyb - napr. mam pointer a nevim jestli je platny (inu stane se :-). Pomoci setjmp(3) si ulozim aktualni stav procesu, zkusim sahnout na adresu v tom pointeru a kdyz to nahodou nevyjde a ocitnu se v sighalndleru, muzu se pomoci longjmp(3) vratit a podruhy uz to nezkouset.
tento clanek je dosti mystifikacni a nicnerikajici blabol.
jenom malickost
pokud chcete pouzivat intervalove oznaceni tak je to takto:
env[x] x = <0; n-1> ne x = (0; n). zacinate od 0 vcetne. tedy alespon pokud pod linuxem nejni jina konvence env[].
pane ludwiku, jelikoz je autor viditelne nekompetentni, rada bych se zeptala Vas, pokud dovolite :-)
jak vypada adresovy prostor pod linuxem? kolik pameti je vyhrazeno jadru, kolik zustava programu? napriklad ve srovnani s NTckama:
dve minus neco giga pro program (pokud /3GB tak 3 minus neco), zbytek je jadro. dve (nebo tri) giga zacinaji od nuly, cili 0 - 0x80000000 patri procesu. (pripadne vic pro /3GB). dale se tam nachazi peb, kde jsou informace o nahranych modulech a podobne. take kazdy thread ma v process address space teb, kam se treba ukladaji per thread promenne. je tam jeste jedna stranka mapovana do jadra (pouze pro cteni) obsahujici treba aktualni timestamp - aby ku prikladu kvuli cteni casu nebylo potreba volat jadro (existuje neco takoveho na linuxu?). navic je treba mit minimalne ntdll.dll v adresovem prostoru (pro nativni programy) takze to bude o neco mene nez dve ci tri giga. mohl byste mi, prosim, osvetlit, jak to vypada na linuxu?
dekuji
ip
No prima - vy se me na neco chcete zeptat a pritom neuveritelnym zpusobem zkomolite moje jmeno, i kdyz se na teto strance vyskytuje minimalne 8x spravne :-((
Jmenuju se Michal Ludvig, ne Ludwik !!!
Nemam ted cas hledat presne udaje, ale pro x86 je to zhruba takhle (vezmu to od nejnizsich adres):
1) od cca 0x08000000 nahoru je mapovan vlastni kod programu
2) pak nasleduji globalni promenne
3) potom misto pro alokace skrz malloc & spol.
4) od 0x40000000 nahoru jsou mapovany sdilene knihovny
5) od 0xBFFFFFFF dolu je alokovan zasobnik (stack)
6) nejvyssich 512 MB (?) okupuje kernel
Celkem to mame 4 GB virtualniho prostoru.
Zde je to rozkresleno trochu nazorneji:
http://linuxassembly.org/articles/startup.html
(mimochodem napadna podobnost s castmi dnesniho clankem je jiste ciste nahodna :-)
" tento clanek je dosti mystifikacni a nicnerikajici blabol. ","pane ludwiku, jelikoz je autor viditelne nekompetentni, rada bych se zeptala Vas, pokud dovolite :-) "
----------
Ne ze bych se chtel autora nejak zastavat, ale on napsal alespon neco - narozdil od Vas (teda pokud neberu v potaz hordu dotazu, urazek a nepresnosti, kterych jste se ve sve kratke odpovedi dopustila). A zbytek informaci, resp. jejich opravy - jak vidno - se da vyzjistit v diskuzi na jejimz zaklade se da clanek poopravit, aby do budoucna nikoho nematl. A ackoliv je mozna pan Ludvig kompetentnejsi nez autor clanku, jeho znalosti a zkusenosti by nam byly uplne naprd, protoze bez zde pritomneho clanku by se o sve informace pravdepodobne s nikym nepodelil.
---
Takze:
-- autorovi preji hodne kuraze do dalsiho pokracovani
-- Ivone Prenosilove studenou sprchu
Je dobře, že lidé tady doplňují a opravují autora, ale
nešlo by to bez těch urážek? Jestli jste někdy psali technicky článek, víte sami, jak je těžké to napsat tak, aby se žádný odborník neozval a nenapadl nějakou jeho část, neobvinil vás z nepřesnosti, špatného názvosloví apod.
Assembler je pro fajnšmekry, je to skutečně vysoká škola programování. A je těžké o tom psát vyčerpávajícím způsobem na malém prostoru zde vyhrazeném.
assembler ze je vysoka skola programovani??????? jezismarja! to je stejna pitomost jako kdyz se lide "trumfuji" v piti piva, plivani do dalky apod.
assembler je relikt minulosti a prestoze se dodnes na nektere veci pouziva (a nekteri lide v tom i vidi smysl) tak neni nic vic. a co se tyce programovani v nem tak to dokaze kazde pako... zkuste se na programovani zeptat napr. nekoho ze sceny kolem funkcionalniho progromovani - system typu, ruzne morfismy, kalkuly atd. tomu rikam "vysoka skola progamovani" a ne blbemu prepisovani pameti (coz assembler v podstate je, protoze vic abstrakce tam proste neni)
No, kdyby kazdy dnesni programator zacinal na Assembleru (jako napr. ja :-), tak by dnesni systemy trhaly dlazbu svou rychlosti. Bohuzel tomu tak neni a vetsina dnesnich programatoru pojmy 'rychlost', "setreni mistem", 'elegantnost reseni', atd. ve svem slovniku nemaji. Pro dukaz si spustte $ top. :-)
Co se tyka GCC optimalizace (jiny thread). GCC je na poli x86 kompilatoru docela dost lama, vetsina komercnich ho tezce prevalcuje. A pokud vam nekdo tvrdi, ze clovek nezvladne napsat lepsi kod nez kompilator, neverte mu. Dvoj a vicenasobna rychlost neni vyjimkou. A desetinasobna uspora mista uz vubec ne.
Jde o pohled na vec, vy zastavate nazor, ze program musi byt "umelecke dilo" a jini (treba ja), ze musi byt maximalne efektivni a "setrny" k HW. Dodnes pisu v Assembleru hodne (i kdyz s rozmyslem), protoze je podstatny rozdil, jestli operace bezi 20 hodin, nebo 11, ci jestli aplikace bezici 24/7 ma zatez 80%, nebo 20%. S tim, ze programovani v asmu je "blbe prepisovani pameti" samozrejme nesouhlasim, blbe je v pripade, ze je blby programator, nebo prekladac.
Jedno Vám povím:
možná se Vám assembler nelíbí, ale mně se třeba nelíbí Java a všechny ty C-křížky a interpretovaný hovadiny. Jsem nucen pracovat na databázi, která má napsaný engine v Javě a přál bych Vám na tom pracovat! Jepice se svym jednodenním životem a nulovou inteligencí by ty dotazy zvládla daleko rychleji.
Teď se neuražte, ale programátor v Javě, C#, VB, VB-sketch, JavaSketch a tomu podobný --- to neni programátor, ale lama, která se naučila klikat v programech se zkratkou IDE (např. Borland*, VisualStudio, ...). Klikat umí bába v kanclu! Tak se vzpamatujte! Já si programátorů píšících v asm velice cením, protože o tom počítači aspoň něco vědí!
PS.: Doufám, že jsem nikoho moc neurazil a pokud ano, tak přijměte mou omluvu.
Jeste lepsi je strojovy kod.
Napr. na Z80 se dala udelat instrukce "nastav n-ty bit bajtu na jednicku", i kdyz procesor umel jen instrukce typu "nastav 4. bit bajtu na jednicku".
Protoze cislo bitu bylo jako bitove pole v opkodu instrukce, clovek si ho spocital, pouknul na adresu do kodu (SamoModifikujiciSe Kod (TM) ) a nechal probehnout. A vyhnul se tak zdlouhave a pokazde jinak trvajici smycce.
Kdyz clovek pouziva asm a abstrahuje od strojoveho zapisu instrukci, nevsimne si takoveto vyhodne vlastnosti strojoveho kodu.
Strojovy kod ma take tu vyhodu, ze se vyvojar nemusi rozmyslet, zda pouzije GAS nebo NASM. Zapis je zde jen jeden - ten uvedeny v datasheetu od procesoru :)
Kdybys ten samomodifikujici kod udelal na pentiu 4, trpel bys delayem v radu stovek cyklu, nez se vyprazdni pool mikroinstrukci a nez se data prelijou z datove do instrukcni cache.
Quake to pouziva, ale je to trba delat jen tehdy, kdyz se to vyplati --- tnz. usetri se tim vic nez stovka ztracenych cyklu.
>Ne ze bych se chtel autora nejak zastavat, ale on >napsal alespon neco - narozdil od Vas
:-) vzdycky kdyz se rozhoduji, jestli napsat hromadu nesmyslu nebo radeji nenapsat nic ...
>(teda pokud neberu v potaz hordu
>dotazu
dotazy byly spise pro ty, kteri se o linux zajimaji. ja radeji zustanu u winnt, preci jenom se mi tento system libi daleko vice ;-)
>urazek
spise bych rekla realistickych zhodnoceni
>nepresnosti
>kterych jste se ve sve kratke
>odpovedi dopustila)
jakych nepresnosti jsem se dopustila?
add pan ludvig > omlouvam se za zkomoleni Vaseho jmena a dekuji za informace
add neologism > s timto si jdi otravovat na blackhole. coze? ze uz te tam nikdo nechce poslouchat? achich ouvej :-)
:-) vzdycky kdyz se rozhoduji, jestli napsat hromadu nesmyslu nebo radeji nenapsat nic ...
-------------------------------
---> implikaci tohoto vyroku dochazim k nazoru, ze s nejvetsi pravdepodobnosti pisete vzdy hromady nesmyslu, tudiz je dalsi debata irelevantni.
( Abychom si rozumeli: neurazim, pouze se snazim 'realisticky' interpretovat co jste prave napsala. Jestlize jsem od Vas zadne clanky na rootu necetl [ctu roota pravidelne a navic jsem se take snazil hledat], znamena to ze bud jste se nepokusila zadny napsat - pak plati ma predchozi odpoved a Vase kritika neni v zadnem pripade na miste. Jestlize jste se pokusila neco napsat a <nebylo to zverejneno>/<rozhodla jste se to nezverejnit>, pak plati to co jste odpovedela => Vasimi slovy: byla to hromada nesmyslu). Nicmene - jestli jsem se dopustil chybne interpretace Vaseho vyroku, milerad si to necham vysvetlit.
ano, samozrejme, ze pisi hromady nesmyslu - proto nikdy neuvidite muj clanek na rootu. nicmene ve foru pod clanky se to mezi ostatnimi prispevky ( treba i Vasemi) s prehledem ztrati :-)
>Jestlize jsem od Vas zadne clanky na rootu necetl[ctu roota pravidelne a navic jsem se take snazil hledat], znamena to ze bud jste se nepokusila zadny napsat - pak plati ma predchozi odpoved a Vase >kritika neni v zadnem pripade na miste.
jestli berete clanek na rootu jako bernou minci schopnosti kritizovat, tak to se nad sebou zamyslete :-)
jak tak nad tim premyslim, dosti to souvisi s mymi predeslymi nekompetentnimi blaboly do fora pod clanky. pokud chce byt root profesionalni a odborny, nemuze strpet clanky jako je tento, ktery viditelne psal nejaky zacatecnik. a mrzi me to jeste z toho duvodu, ze takto spatne napsany clanek uz tu dlouho nevysel ...
btw jeste jste neodpovedel, kde jsem se dopustila onech "nepresnosti".
jestli berete clanek na rootu jako bernou minci schopnosti kritizovat, tak to se nad sebou zamyslete :-)
----->
Ale samozrejme ze ne, nic takoveho jsem - pokud je mi znamo - nenapsal. Ja pouze poukazuji na to, ze ackoliv mate zrejme nizsi znalosti o tematu nez autor clanku (= jinak byste se neptala, ale opravila autora), dovolite si ze sve pozice vynaset soudy o jeho kompetentnosti (nejste jedina).
---------------
muze strpet clanky jako je tento, ktery viditelne psal nejaky zacatecnik.
----->
no, samozrejme. ale kazdy nejak zacina. V serioznich vedeckych casopisech se to obvykle dela tak, ze se clanek da posoudit nekomu kompetentnimu (dava posoudit redakce) a na zaklade takoveho posudku je zverejnen pripadne vracen. Takze poukazovat na autorovo zacatecnictvi je ponekud ubohe, protoze chyba je spise na strane redakce, ktera si neoverila kvalitu prispevku. (to redakce: no flame, ja neremcam, od toho jsou tady jini)
------>
ad nepresnosti:
nicnerikajici blabol --> nepravda, generalizace problemu nekompetentnim hodnotitelem
pane ludwiku --> no comment
viditelne nekompetentni --> nepravda, usudek nekompetentni osoby nad kompetentnosti nekoho jineho nelze povazovat za spravny, neomlouva Vas ani ten smajlik
add pan ludvig --> co comment.
-------------------------
Jeste posledni vec:
pokud chce byt root profesionalni a odborny, nemuze strpet clanky jako je tento, ktery viditelne psal nejaky zacatecnik --> vy tady nekoho hanite, ale v podstate si ani sama po sobe neprectete co jste napsala. Ma-li byt kritika z Vasi strany konstruktivni, je nutne se vyvarovat osocovani a pracovat jaksi 'na urovni'.
----------------
Jelikoz se mi opravdu dalsi debata na toto tema zda licha, nehodlam v ni pokracovat.
--------------------------
--------------------------
Jeste jedna poznamka: jestlize budete vzdy lyncovat autory, kdyz se neco nepovede, tak za chvili zadny root nebude, protoze autori nebudou mit chut psat.
Pravda je, že některé nepřesnosti v článku obsažené jsou do nebe volající a ukazují na autorovy elementární neznalosti. Neztotožňuju se s Vaším názorem, že napsat článek s četnými a zásadními chybami a spolehnout, že ho někdo opraví, je legitimní způsob odborného publikování.
Souhlasím s tím, že Ivona Přenosilová by si mohla nalézt duchaplnější způsob, jak si obhájit svoje místečko na slunci; možná by jí v hledání mohla pomoci i ta studená sprcha.
Autorovi taktéž přeju kuráž, dále aby mu vydrželo jeho nesporné nadšení pro assembler, a také aby našel odvahu a skromnost požádat někoho o přečtení a korekci článku ještě před jeho uveřejněním.
Je to jak Ludvig popsal, ale ten kernel má 900MB (ty jsou lineárně pomocí velkých stránek namapovány na prvních 900MB paměti), nikoli 512MB. Zbytek se používá v kernelu na virtuální alokaci (alokace více nesouvislých stránek mapována do souvislého adresního prostoru) a cache mapování, když jádro potřebuje přistupovat k vyšším adresám.
Stránku s timestampem Linux nemá, při zjištění času se vždy volá kernel. Novější jádra namapují procesu stránku, na které se nachází vstup a výstup ze syscallu (tzn. to o int 0x80 z článku taky moc neplatí) --- tam se podle typu procesoru zapíše intrukce sysenter (Intel) nebo int 0x80, pokud je procesor starý, že to neumí (AMD syscall to asi neumí, ale nevim --- každopádně by tam šel jednoduše dopsat).
Thready jsou implementovány tak, že pro každý thread je jeden deskriptor v LDT a na něj ukazuje GS. Pomocí čtení paměti přes GS je možno zjistit, který thread se právě vykonává nebo přistupovat na thread-specific datové položky (dělají se tak, že se před deklaraci globální proměnné napíše __thread).
nt na novejsich procesorech pouzivaji sysenter/sysleave tez misto int 2eh. mapovana stranka nejni jen pro timestamp, ale jsem moc lina divat se pro co jeste ...
per thread zalezitosti se pod winnt resi pomoci selectoru v gdt (fs registr). pri context swapu se meni na adresu TEBu noveho threadu. pokud se pro kazdy thread pouziva polozka v LDT neomezuje to maximalni pocet threadu?
to same co pisete pro gs registr plati na nt pro fs registr - je tam datova struktura obsahujici TLS
NT maji odlisne FS na kazdem procesoru a z neho urci o jaky thread se jedna?
LDT mnozstvi threadu v procesu na Linuxu omezuje. Mozna kdysi ve starych libc se thread urcoval pomoci ESP. To GS kazdopadne uz zmenit nejde --- je to zakompilovane do vsech programu, co pouzivaji thread-local promenne.
>NT maji odlisne FS na kazdem procesoru a z neho urci o jaky thread se jedna?
ano, ale je to trochu slozitejsi. nejprve je dulezite rozlisit kernel a user mode.
fs je rozdilne na kazdem procesoru i v kazdem user mode threadu. ted prichazeji
v potaz dva gdt selectory:
selector 0x30 - ten ukazuje na PCR (PCRB), process control region, ktery je samozrejme
na kazdem procesoru jiny, ale nemeni se.
selector 0x3b - ten ukazuje na UTEB (user mode thread environment block). ten
se meni (base) pri kazdem context switchi.
DPL=3, Base=0x7FFDE00 (1st thread), Lim=0x00000FFF
pro kernel mode thready je base = 0
jak vidite, tento selektor ukazuje do address space procesu, do
ktereho nalezi.
kdyz se zavola syscall, v syscall handler prologu se nastavi fs == 0x30 - cili
ukazuje na PCR daneho procesoru, na kterem zrovna bezi. tam je ulozen odkaz treba
na aktualni thread object, etc. kdyz se zase prepina zpet z kernel modu do user
modu, nastavi se zpet fs registr na 0x3b. jelikoz tento selector ma pro kazdy
user mode thread jinou bazi (a ukazuje na jinou datovou strukturu), umoznuje
pouzivat thread local variables.
>LDT mnozstvi threadu v procesu na Linuxu omezuje. Mozna kdysi ve starych
>libc se thread urcoval pomoci ESP. To GS kazdopadne uz zmenit nejde ---
>je to zakompilovane do vsech programu, co pouzivaji thread-local promenne.
fs take menit nejde. kvuli optimalizaci se pouziva inline kod.
Mno, kdysi ve starych libc - ja bych tak neprehanel - rekl bych, ze takhle zmena (thread-identifikace via %gs) je az od kernelu 2.5.x. Navic tu zustavaji architektury, ktere specialni registr pro thready nemaji, tam se to stale provadi via %esp (tzn. se zaokrouhli na 2MB nahoru, kde je struktura __pthread_desc, ci neco takoveho, tam jsou vsechny thread-local veci, ala pointer na lokalni promenne, thread errno, id, atd.).
maximalni velikost ldt (i gdt) je sice 64 kilo, nicmene deskriptor ma 8 bajtu, ne 4. cili neni to 16k threadu, ale 8k threadu. je to velke cislo i tak. neprela jsem se, jestli je mozne to naplnit (ano je), nebo ze je to realne. navic pod linuxem, kde je to s threadama trochu slozitejsi (podporuje linux vubec prave kernel mode thready? shedulable entita je proces, nebo thread pod linuxem?), takze se spise pouziji procesy. byla to jen otazka, nic ofenzivniho :-)
> Novější jádra namapují procesu stránku, na které se nachází vstup a výstup ze syscallu.
Jenže KAM ji mapují? Hledal jsem v hlavičkách pro glibc a nic jsem nenašel. Je to pevná virtuální adresa, která nezávisí na verzi kernelu? Jaká?
Jak se taková stránka volá, když i386 neumí pro "call" a "jmp" jiný operand než pc-relativní? To každé místo, kde v kódu volám kernel generuje relokaci? Pro programy to sice nevadí, ale co volání kernelu z -f PIC kódu? To tam bude navíc další jump instrukce s indirekcí přes GOT? Každý nepřímý skok na AMD i Intelu flushuje pipelie. Nebylo by lepší mít vsyscall stránku namapovanou na začátku každé knihovny?
Moment ... ano, zvoral jsem to. Predevsim jsem spatne precetl co tvrdi clanek a pote jsem se venoval main misto _start ... takze clanek ma pravdu, s tim ze obvykle za polem pointeru na env (posledni v clanku uvedena polozka) nasleduje jeste vlastni OBSAH argv a env. To by ovsem nikoho nemelo zajimat.