assembler, pamat - otazky
zacal som sa pohravat s assemblerom, ale zopar veci mi zial nie je jasnych.
Preto som sa obratil na Vas :-)
Totizto, ked som dobre pochopil, tak program ked sa spusti, tak on si o sebe mysli, ze ma k dispozicii 4GB pamate(v 32bitovych systemoch) - od 0x0000000 po 0xfffffff . A samozrejme vsetky adresy, na ktore instrukcie odkazuju su odkazy na VIRTUALNE ADRESY. Potom vsak nechapem, ze ako moze vzniknut SEGFAULT , cize ze napriklad sa to EIPcka narve adresa, ku ktorej program nema prava vstupit... Ved ma prava vstupit vsade, nie? Ma to nejaky suvis s nejakym sandboxingom?
Taktiez nemam potmo jasne v tom koncepte - preco potom program nepouziva adresy uplne od 0x0000000 ? Co smo si disassembloval kratulilinke programiky, tak instrukcie zacinali na 0x8nieco a potom na 0xbfnieco. Preco prave tu niekde nezavisle na spustenom programe?
Dalej by sa zaujimalo, ze ako vnima program zdielanu pamat? (mam na mysli napr. shared libraries) - na jeho adresovaciom priestore je to nejak naadresovane(s tym, ze potom uz kernel zariadi to, aby to odkazovalo na fyzicke umiestnenie zdielanych objektov)?
Zaujima ma taktiez, ze kolko priestoru v tom adresovacom priestore je vyhradenych pre stack a haldu? cely zvysok, alebo je to nejak uz premyslene a hodene tam nejake implicitne cislo?
A na zaver by ma este zaujimala otazka z trosku ineho sudka:
totiz som si pozeral nejake navody na tvorbu vlastneho OS a tu nechapem jednu vec: predsa napriklad veci skompilovanom vo Visual Ccku nepojdu na linuxe a vice versa - gcc-ckovske veci defaultne nejdu na windose - lebo su tie kompilatory nejak tak spravene, ze su uz prisposobene tomu danemu operacnemu systemu a vyuzivaju jeho architekturu a neviemco este.
Ako je potom mozne, ze v tych navodoch su kroky, ako teraz si zdrojak nasho operacneho systemu prekompilujeme cez gcc-cko? Ako mozem kompilovat uplne novy OS(uplne novy platformu) na kompilatori, ktory kompiluje programy len na jednu platformu?
Skuste mi prosim odpovedat na to, na co viete, lebo mam v tom mys-maz. Vdaka :-)
Pre pridávanie komentárov sa musíte prihlásiť.
to nie je pravda . Teoreticky ich moze mat ale len niektore moze pouzit...
> A samozrejme vsetky adresy, na ktore instrukcie odkazuju su odkazy na VIRTUALNE ADRESY. Potom vsak nechapem, ze ako moze vzniknut >SEGFAULT , cize ze napriklad sa to EIPcka narve adresa, ku ktorej program nema prava vstupit... Ved ma prava vstupit vsade, nie? Ma to nejaky suvis >s nejakym sandboxingom?
Pravo ma pristupovat len k tyk adresam, ktore mu prideli OS(ak je ten OS spravne napsiany)
>Taktiez nemam potmo jasne v tom koncepte - preco potom program nepouziva adresy uplne od 0x0000000 ? Co smo si disassembloval kratulilinke >programiky, tak instrukcie zacinali na 0x8nieco a potom na 0xbfnieco. Preco prave tu niekde nezavisle na spustenom programe?
na zacitok si dava nejake veci OS a je tam aj stack
>Dalej by sa zaujimalo, ze ako vnima program zdielanu pamat? (mam na mysli napr. shared libraries) - na jeho adresovaciom priestore je to nejak >naadresovane(s tym, ze potom uz kernel zariadi to, aby to odkazovalo na fyzicke umiestnenie zdielanych objektov)?
Presne tak, jednoducho adresy zdielanej pamate sa prifdaju k datovemu segmentu a kod kniznic as primauje na konec texroveho (ktory sa vDOSE ana X86 nazykva kodovy) segmentu
>Zaujima ma taktiez, ze kolko priestoru v tom adresovacom priestore je vyhradenych pre stack a haldu? cely zvysok, alebo je to nejak uz premyslene a >hodene tam nejake implicitne cislo?
stack je na zaciatku a halda je na konci dateveho segmentu
>totiz som si pozeral nejake navody na tvorbu vlastneho OS a tu nechapem jednu vec: predsa napriklad veci skompilovanom vo Visual Ccku nepojdu
>na linuxe a vice versa - gcc-ckovske veci defaultne nejdu na windose - lebo su tie kompilatory nejak tak spravene, ze su uz prisposobene tomu
>danemu operacnemu systemu a vyuzivaju jeho architekturu a neviemco este.
ak kompilujes v C-cku tak sa program skompiluje s tym, ze potrebuje na svoj beh zdielanu kniznicu daneho kompilatora. Je to preto, ze okrem Portland kompilatora nema ziadny iny kompilor 100% podporu ISO/ANSI C a nic navyse... MS C nema kniynicu pre Linux ale gcc ma kniynicu pre Windows
>Ako je potom mozne, ze v tych navodoch su kroky, ako teraz si zdrojak nasho operacneho systemu prekompilujeme cez gcc-cko? Ako mozem
>kompilovat uplne novy OS(uplne novy platformu) na kompilatori, ktory kompiluje programy len na jednu platformu?
Cross compile su sobr kniznic toho kompilatora pre rozne platformy a tie sa pritom prilinkuju staticky k u kodu ak sa robi cross compile...
Majme jednoduchy program:
#include <stdio.h>
int main()
{
printf("Hello world!\n");
sleep(1000);
return 0;
}
a teraz si pozrime jeho virtualny adresny priestor:
// tu je namapovana cast suboru a.out, ktora obsahuje vykonatelny kod
08048000-08049000 r-xp 00000000 03:01 2474008 /home/dusan/projects/hello/a.out
// tu je namapovana cast suboru a.out, ktora obsahuje udaje, ktore si program uz
// nosi zo sebou, v tomto pripade to bude retazec "Hello world!\n"
08049000-0804a000 rw-p 00000000 03:01 2474008 /home/dusan/projects/hello/a.out
b7dd4000-b7dd5000 rw-p 00000000 00:00 0
// namapovana kniznica libc
b7dd5000-b7f2a000 r-xp 00000000 03:01 984384 /lib/i686/cmov/libc-2.7.so
b7f2a000-b7f2b000 r--p 00155000 03:01 984384 /lib/i686/cmov/libc-2.7.so
b7f2b000-b7f2d000 rw-p 00156000 03:01 984384 /lib/i686/cmov/libc-2.7.so
b7f2d000-b7f30000 rw-p 00000000 00:00 0
b7f4b000-b7f4e000 rw-p 00000000 00:00 0
// hack v jadre 2.6 ktory "zefektivnuje" pouzivanie systemovych volani jadra
b7f4e000-b7f4f000 r-xp 00000000 00:00 0 [vdso]
// dynamicky linker
b7f4f000-b7f69000 r-xp 00000000 03:01 974850 /lib/ld-2.7.so
b7f69000-b7f6b000 rw-p 0001a000 03:01 974850 /lib/ld-2.7.so
// zasobnik
// Jadro adresu zasobnika pri kazdom spusteni randomizuje v rozsahu par MB
// aby sa tak zabranilo utoku buffer overflow
bfd11000-bfd26000 rw-p 00000000 00:00 0 [stack]
na to potrebuje druhy priklad:
#include <stdlib.h>
int main()
{
free(malloc(1024));
return 0;
}
virtualny adresny priestor:
08048000-08049000 r-xp 00000000 03:01 2474008 /home/dusan/projects/hello/a.out
08049000-0804a000 rw-p 00000000 03:01 2474008 /home/dusan/projects/hello/a.out
// tu je halda:
09864000-09885000 rw-p 00000000 00:00 0 [heap]
b7eef000-b7ef0000 rw-p 00000000 00:00 0
b7ef0000-b8045000 r-xp 00000000 03:01 984384 /lib/i686/cmov/libc-2.7.so
b8045000-b8046000 r--p 00155000 03:01 984384 /lib/i686/cmov/libc-2.7.so
b8046000-b8048000 rw-p 00156000 03:01 984384 /lib/i686/cmov/libc-2.7.so
b8048000-b804b000 rw-p 00000000 00:00 0
b8067000-b8069000 rw-p 00000000 00:00 0
b8069000-b806a000 r-xp 00000000 00:00 0 [vdso]
b806a000-b8084000 r-xp 00000000 03:01 974850 /lib/ld-2.7.so
b8084000-b8086000 rw-p 0001a000 03:01 974850 /lib/ld-2.7.so
// vsimnite si, ze stack je trochu na indej adrese ako v minulom pripade ;)
bf916000-bf92b000 rw-p 00000000 00:00 0 [stack]
Na 32 bitovych CPU ma 4GB virtualny adresovy priestor (z toho moze aj tak maximlane teoreticky vyzuzit iba 3GB), nie 4 GB pamate
Vtip je v tom, ze nie kazda pamatova stranka virtualneho adresoveho priestora je namapovana na fyzky adresovy ramec pamate.
SIGSEGV nastava ked proces chce pristupit na stranku ktora vobec nie je namapovana, alebo zapisuje na starnku, ktora je namapovana len pre citanie alebo pristupuje na stranku, ktora mu nepateri (tie od 3GB vyssie)
>Taktiez nemam potmo jasne v tom koncepte - preco potom program nepouziva adresy uplne od 0x0000000 ? Co smo si disassembloval kratulilinke programiky, tak instrukcie zacinali na 0x8nieco a potom na 0xbfnieco.
To presne neviem ani ja, myslim si vsak, ze je to z historickych dovodov. Od adresy 0x0 byt namapovane nic nemoze, lebo potom by adresa NULL "niekam ukazovala"
>Dalej by sa zaujimalo, ze ako vnima program zdielanu pamat? (mam na mysli napr. shared libraries) - na jeho adresovaciom priestore je to nejak naadresovane(s tym, ze potom uz kernel zariadi to, aby to odkazovalo na fyzicke umiestnenie zdielanych objektov)?
Zdelanu knizicu proces vnima ako privatne namapovany subor.
Uvediem priklad na kniznici libc:
b7d6d000-b7ec2000 r-xp 00000000 03:01 984384 /lib/i686/cmov/libc-2.7.so
tu sa namapoval vykonatelny kod, ktory sa moze spustat a nemoze sa prepisovat
b7ec2000-b7ec3000 r--p 00155000 03:01 984384 /lib/i686/cmov/libc-2.7.so
tu je su namapovane nejake readonly data pre knizicu
b7ec3000-b7ec5000 rw-p 00156000 03:01 984384 /lib/i686/cmov/libc-2.7.so
a tu su namapovane data pre knizicu, ktore sa mozu aj citat aj prepisovat
>totiz som si pozeral nejake navody na tvorbu vlastneho OS a tu nechapem jednu vec: predsa napriklad veci skompilovanom vo Visual Ccku nepojdu na linuxe a vice versa - gcc-ckovske veci defaultne nejdu na windose - lebo su tie kompilatory nejak tak spravene, ze su uz prisposobene tomu danemu operacnemu systemu a vyuzivaju jeho architekturu a neviemco este.
To ze "program skompilovany pod Visual Ccku nepojde pod Linuxom" je skor tym, ze program pouziva windowsacke knizice, program je linkovany do formatu PE EXE.
BTW existuje verzia gcc pre Windows :)
V najvseubecnejsom slova zmysle kompilator dokaze kompilovat kod v C nezavysle od OS.
myslim, ze by celkom bodol clanok na tuto temu v portali(na googli som ani v anglictine nic napomocne nenasiel :( )
ps aux
vyhliadni si nejaky proces a zapametaj si jeho PID (druhe cislo z lava)
potom uz iba napis:
cat /proc/PID_daneho_procesu/maps
a mas vypis pamate
ak mas napriklad:
root 26948 0.0 0.1 3468 1736 pts/3 S 20:06 0:00 bash
pid procesu bash je 26948
a potom napis cat /proc/26948/maps