Dicas - C e Assembly para arquitetura x86-64 ©
Versão 0.33.9 2014-2017 por Frederico Lamberti Pissarra 3 de fevereiro de 2017
Título: C !ssemb"# para ar$%itet%ra &'(-(4 Autor: Frederico Lamberti Pissarra Ano de publicação: 201(
)ste materia" * prote+ido pe"a "ice,a F/L 1.3: C & Assembly para arquitetura x86-64 Copyright (C) 2014-2016 by Freeri!o "amberti #issarra
A permissão de cópia, distribuição e/ou modificação deste documento é garantida sob os termos da licença “GNU Free Documentation icense, !ersion "#$% ou &ersão mais recente publicada pela Free 'oft(are Foundation# ) te*to integral da licença pode ser lido no lin+ ttps-//(((#gnu#org/licenses/fdl#tml#
importa,te ,o e,ta,to advertir ao "eitor $%e este materia" e,co,tra-se em processo de prod%ão. rata-se e,tão de %m rasc%,o e ,ão ref"ete o materia" fi,a"iado. Fi+%ra da capa: DIE da arquitetura Intel Ivy Bridge
Índice Introdução
C e
5r+a,iaão "ivro do 6istemas5peracio,ais:Li,%&vsi,do8s C6obre 6obre "i,+%a+em a !ssemb"# me"or; ! roti,a poss
1
2 2 2 3 4
7
Capítulo1I:ntroduçãoaoprocessador
> ( 7 9
Aodos operaão de $%e 5si+,ifica proteão;B $%e 5si+,ifica pa+i,aão;B Proteãoese+me,tos,omodoprote+idoem32bits 5,de fica tabe"a a de descritoresB 6e"etoresedescritoresdese+me,tos,omodo&'(-(4 /escritores ,o modo &'(-(4 Cace descritores de Proteão modo ,o &'(-(4
9 10 10 10 13 13 14 1> 1>
Capítulo2:Interrompemosnossaprogramação...
%ma $%e 5 *i,terr%pãoB !s ?,terr%pesespeciais:)&ceesFa"tase!bortos )&istemdoistiposdei,terr%pesdeard8aredifere,tes ?,terr%pessãosempree&ec%tadas,oDer,e"spaceE Fa"tasimporta,tesparaperforma,ce 6i,ais: ?,terr%pes,o %ser space me&emp"ode%sodesi,ais,oLi,%& @ão %se si+,a"GH %se si+actio,GH )&istemaissobresi,aisdo$%edis%avãfi"osofia... Capítulo 3: esol!endo d"!idas #re$uentes sobre a %inguagem C
IeaderseA=d%"os:ma$%estãodeor+a,iaão Camadasdef%,esco,tidas,omesmom=d%"o ama,o de i,teiros po,teiros e @ão*pr%de,teco,fiar,ostama,osdostiposdefa%"t )&istedifere,ae,tredec"arar;edefi,ir;%ms
17
17
17 1' 1' 19 19
21 21 22 23
23 24 2> 2> 2( 27 27 2' 29 31 32 34 34 3>
27
Aais po,teiros arra#s e /ec"ara,doei,icia"ia,doarra#sestr%t%rase%,io,s Po,teiros f%,es pi"a ae ),te,de,doa"+%masdec"araesma"%cas;%sa,dopo,teiros ti"idadedepo,teirosparaf%,es bib"ioteca ! padrão: "ibc !"ibcfa%mmo,tedecoisasporbai&odospa,os; C%idados ao %sar f%,es da "ibc /ispara,do processos fi"os
3( 3( 3' 39 40 41 43 44 44
Capítulo&:esol!endod"!idassobrealinguagemAssembl'
processador 5 pode ter b%+s; !mesmai,str%ãopode+astarmaistempodo$%edeveria @emtodasasi,str%es+astam;tempo red o,e; api"a e! Prefi&os
&7
47
4' 49
49 >0
Capítulo () : isturando C A e ssembl'
Co,ve,es de camada G&'(-(4H Co,ve,es de camada Gi3'(H F%,escom,MmerodeparKmetrosvarive",o&'(-(4 Pi"a ,os modos i3'( &'(-(4 e mdeta"esobreo%sodere+istradoresde32e(4bits )&emp"odef%,ãoemassemb"# %sa,do aco,ve,ãodecamada !visosobreretor,odef%,escomtiposcomp"e&os pi"ada %so 5 Variveis "ocais pi"a ae 5compi"ador,ão%satodasasi,str%es /eta"esi,teressa,tessobreai,str%ão@5Peoprefi&oN)P L55P e L55P@O são difere,tes mas N)P@O e N)P são a mesma coisaE !ssemb"# i,"i,e 5peradordei,direãoGpo,teirosHemassemb"# sa,doasi,ta&e?,te",oassemb"#i,"i,edoCC Prob"emascomoassemb"eri,"i,edoCC sa,do @!6A
(3
>3 >4 >( >( >7 >7 >' (0 (1 (2 (3 (> (> (' (9 (9 70
Capítu +*le:orramentas
73
@ Li,Der G"dH 5bte,do i,formaes com obd%mp /eb%++er @ Co,fi+%ra,do /Q o /%asma,eirasde"istarc=di+oassemb"#,o+db
73
Lista,do re+istradores )&ami,a,do mem=ria a com /Q o 5bte,do"ista+e,semassemb"#%sa,dooCC 6obre os e,dereos em "ista+e,s em assemb"# obtidas com obd%mp o% CC
7'
7> 7> 7( 7( 77 7' '1 '2
Usando o make: Fazendo um bolo, usando receitas Capítul7o) : edindp oer#ormance
Cic"os de m$%i,a cic"os e de c"ocD Co,tarcic"osdem$%i,a,ão fci" * medirB Como
,7
'7 '7 ''
!%me,ta,do precisão a da medida Aas o +cc poss%i f%,es i,tr<,secas; para e&ec%tar CP?/ e N/6CE Ae"ora,doamediãodeperforma,ce 5 c"c%"o do +a,o de performa,ce R%a,do %m +a,o va"e pe,a;B S sa,doperf;paramedirperforma,ce
'9 91 92 92 93 94
Capítulo,: timiaç/es0automticas
9(
@
9> 9> 9(
Aove,do c=di+o i,varia,te de de,tro de "oops GLoop ?,varia,t Code Aotio,H )"imi,aãodec=di+omortoG/eadCode)"imi,atio,H )"imi,aão de armae,ame,to morto G/ead 6tore )"imi,atio, ) Previsãodesa"tosGQra,cPredictio,H 6imp"ificaes "=+icas 6imp"ificaãodef%,esrec%rsivas !%to vetoriaão G66)H 5timiaes atrav*sde profi"i,+
97
97 97 99 100 101 101
CapC ít9u a:cloes
estr%t%ra ! dos caces /etermi,a,dootama,ode%ma"i,a di"ema 5 do a"i,ame,to /icapara%sarme"oroscaces... !%daciosame,tei,doo,de%mb#teamaisesteve... F%,esi,"i,eeasat%raãodocace
143
103 104 10> 10( 107 107
Capítul1o4) : em5ri6 airtual
Virt%a"iaão de mem=ria )spaos de e,dereame,to Pa+i,aão Pa+i,aão s8appi,+ e abe"asdepa+i,aão,omodo&'(-(4 !s e,tradas da Pa+e ab"e e&te,ses !s P6) P!) e ra,s"atio, LooDaside Q%ffers !importK,ciadeco,eceroes$%emadepa+i,aão abe"asdep+i,as%sadaspe"o%serspace !"oca,domem=ria: ma""oc mmap e me&emp"odei,eãodec=di+o%sa,dop+i,as R%a,tamem=riaf
149
109 109 109 110 111 112 112 113 113 114 11> 11( 11'
Capítu1Tl1o: reads
A%"titarefapreemptivaecooperativa AM"tip"os processadores Como sced%"er o camadoB * Fi,a"me,te %ma e&p"icaão de por$%e 66 ,ão * ero ,o modo &'(-(4E @a prtica $%e o %ma * tread;B Cria,dos%apr=priatread%sa,doptreads Cria,do treads ,o i,do8s Parar%matread,amarra;$%asesempre,ão*%maboaideia
9(
121
121 122 123 123 123 124 12> 127
@emtodasastreadspodemsermortas; reads ,Mc"eos caces e raba"arcomtreads,ão*tãosimp"es$%a,toparece )vita,do race co,ditio,s; reads bib"iotecas e reads Q"o$%eios e $%e 5si+,ifica isso t%doB e,ta,doevitarocaveame,todeco,te&tosdetarefas sa,do 5pe,AP o 5pe,AP m+ico ,ão * Compi"a,do %sa,do e 5pe,AP
127 12' 12' 129 130 131 131 131 132 133 133
5pe,CL ,Vidia e C/!
134
Capítul1o28:ont#olutuante
Precisão vers%s )&atidão $%e 5 po,to * f"%t%a,te;B )str%t%ra %m f"oat de !,a"o+iacom,otaãocie,t
13(
13> 13> 13> 13( 137 13' 13' 139 140 141 142 142 143 144 144 14> 14( 14(
Capítulo 13I:nstruç/e s stendidas
66) F%,es i,tri,secas; para 66). )&emp"o do prod%to esca"ar maotimiaão;$%efa"o%Toprod%tovetoria" maotimiaãobems%cedida:A%"tip"icaãodematries $%a,do !VUB )ao 5%trase&te,sesMteis:QA? FA! e
1&9
149 1>0 1>1 1>2 1>4 1>> 1>>
Capítul1o&:icm aesacetes
Va"oresboo"ea,os:!"+%masdicasi,teressa,tesemC R%a,to mais as coisas m%dam... /)C ?@C são e"erdasE issoEEE faa @ão !ritm*ticai,teiradem%"tip"aprecisão VocJ ,ão est ca,sado dissoB 5timiaãodepree,cime,todearra#s e,ta,dootimiaroNFC1071cecDs%m.)fa"a,do... Previsãodesa"tose%marra#deva"oresa"eat=rios
1(9
1>9 1(0 1(0 1(0 1(1 1(2 1(4 1(( 1('
sarrai$%adradavia66)pareceestra,o... era,do ,Mmeros a"eat=rios Capítul1o() : isturand;oa!C ea
170 171 173
173
Porque no ! uma boa ideia misturar " com ambientes #gerenciados$
arba+e Co""ectio, ,o ava Aist%ra,docom%me&emp"osimp"es... sa,do stri,+s sa,do arra#s %,idime,sio,ais sa,do obetos Cama,dom*todosdopr=prioobeto
174 17> 17' 1'0 1'1 1'2
!cessa,domembrosdedadosdopr=prioobeto /evo"taaosarra#s:sa,domaisde%madime,são
1'4 1'4
Capítulo 1*:
1,7
Co,ta+em referJ,cias de ?,sta,cia,do p#to, o Carre+a,do %m m=d%"o )&ec%ta,do %m m=d%"o simp"es Ap=ndiA > ce': stecm alls
Co,sideraessobreo%sodai,str%ão6W6C!LL 5,deobtera"istades#sca""sdoLi,%&B sars#sca""s,oi,do8s,ão*%maboaid*iaE
1'7 1'7 1'' 1'9 191
191 192 193
Ap=ndice?:esen!ol!endopara@indosusandoBCC
sa,do Ai, o ,o Li,%& sa,do Ai, o ,o i,do8s !sbib"iotecasmi,+8m10.d""emsvcrt.d"" Limitaes Ai, do !ssemb"# com Ai, o @!6A e i,do8s %sa codificaão de caracteres de 1( bits i,ter,ame,te Va"e a pe,a dese,vo"ver ap"icaes i,teiras em assemb"# para i,do8sB ?mporta,do /LLs ,o Ai,-8(4
19(
19> 19> 19( 19( 19( 19( 197 19'
Ap=ndicCe?:uiltindB so CC
241
Ap=ndic e) : 5dulodsD o ernel
24(
!,atomia de %m m=d%"o simp"es
20>
Introdução )m 1994 p%b"i$%ei %ma s*rie de 2( cap
9!3 e o P? '2>34 o% os mais moder,os com o ?X5 !P?C '2093! >H bem como "ista+e,s dos mapeame,tos de portas de ?X5 (. )sse materia" * esse,cia" para o e,te,dime,to da ar$%itet%ra dos PCs especia"me,te ,o $%e co,cer,e o mapeame,to da mem=ria. para a "i,+%a+em C e&istem a"*m de t%toriais o,"i,e bo,s "ivros trad%idos para o port%+%Js bem como as especificaes ?65 da "i,+%a+em G$%e recome,do forteme,te $%e vocJ se fami"iarieEH. 1 2 3 4 > (
?!-32 ?,te" (4 6oft8are /eve"opme,t Aa,%a"s;: ttp:XX+oo.+"XbssF. !A/(4 !rcitect%re Pro+rammerYs Aa,%a"s;: ttp:XX+oo.+"Xo?Q,V/. Pro+rammab"e ?,terr%pt Co,tro""er '2>9! /ataseet: ttps:XX+oo.+"XC%2s#. Pro+rammab"e ?,terva" imer '2>3 /ataseet: ttp:XX+oo.+"X9svF. !dva,ced ?X5 Pro+rammab"e ?,terr%pt Co,tro""er '2093! /ataseet: ttp:XX+oo.+"X44,t/7. )is %ma "ista+em em formato te&to: ttp:XX+oo.+"XcF'2!V.
1
Organização do livro 5s cap e P#to, ,o cap
Sistemas Operacionais: Linux vs Windows @a maioria do tempo fa"arei sobre Li,%& a$%i. ?sso ,ão si+,ifica $%e dicas e macetes ,ão possam ser ap"ciadas a o%tros sistemas como i,do8s e 56XU. !co,tece $%e o M,ico sistema operacio,a" o,de podemos co"ocar as mãos em s%as e,tra,as e rea"iar %ma ava"iaão $%ase $%e cirMr+ica * o Li,%&7. ! ,ão ser $%e vocJ te,a o c=di+o fo,te do i,do8s mais rece,te o% do 56XU G$%e * baseado ,o FreeQ6/ por fa"ar ,issoH certos rec%rsos ,ão podem ser co,ecidos diretame,te. R%ais$%er e&p"icaes e,vo"ve,do rec%rsos i,ter,os do i,do8s por e&emp"o seria merame,te espec%"ativa. ! doc%me,taão e&iste,te sobre a !P? * boa Gdispo,
Sobre C e C++ /e acordo com o t
2
5D vocJ tamb*m pode faer isso com as variaes free; do Q6/E !cess
a"+%m po,to. !s M,icas e&cees são os cap
Eame )angling T 5s ,omes de f%,es em C cost%mam ser codificados de %ma
ma,eira difere,te do $%e * feito em C. )m C %ma f%,ão do tipo: i,t fGi,tH\; tem o ,ome de f; ,%ma "ista+em do c=di+o e$%iva"e,te em assemb"#. )m C o ,ome * %ma coisa ma"%ca como ]O1fi; o% a"+o $%e o va"a G,ão vo% me ater S co,ve,ão de ,ome,c"at%ra de f%,es em C a$%i... isso m%da de compi"ador para compi"adorH. 5 verbo o ma,+"e; em i,+"Js pode ser "itera"me,te trad%ido para m%ti"ar;. 5 $%e di m%ito sobre C\ •
+unç/es membro de classes T !s f%,es membro ,ão estticas de %ma c"asse recebem
%m po,teiro adicio,a" esco,dido camado YtisY. )ste po,teiro apo,ta para a i,stK,cia; do obeto da c"asse e * passado esco,dido para todas as f%,es Gde ,ovo: ,ão estticasH. •
+unç/es membro !irtuais T oda camada a %ma f%,ão membro virt%a" * feita com d%p"a
i,direão. ?sto * %ma referJ,cia a %m obeto * %m po,teiro $%e apo,ta para %ma tabe"a co,te,do po,teiros para as f%,es. )&p"icarei isso breveme,te ,o cap
Sobre a linguagem Assembl R%a,to a "i,+%a+em assemb"# e&istem m%itos sabores; $%e o "eitor pode esco"er . Cada tipo de processador se%.a$%i )stecom te&toas"ida ape,as com os modos i3'(dae &'(-(4 dos processadores fam<"ia ?,te".tem @ãoo "ido p"ataformas ?!-(4 Gtamb*,m ?,te"H o% !NA e !NA-(4dapor e&emp"o Go M"timo est em vo+a; oe em dia +raas aos dispositivos m=veis e devices como o as&berry PI e smartpo,esH. ?sso * importa,te por$%e ,essas o%tras ar$%itet%ras temos a"*m da "i,+%a+em assemb"# difere,te re+ras de otimiaes e or+a,iaão de ard8are tamb*m comp"etame,te difere,tes. !ssemb"# a$%i tamb*m não * %sada como "i,+%a+em pri,cipa" de dese,vo"vime,to e recome,do #ortemente $%e vocJ ,ão te,te %s-"a como ta". Ioe em dia aco %ma verdadeira "o%c%ra 3
dese,vo"ver ap"icaes i,teiras ,essa "i,+%a+em. !t* os sistemas operacio,ais são comp"e&os o s%ficie,te para ,ão permitirem %ma aborda+em prod%tiva ,esse se,tido e a"*m do mais os compi"adores de ,
A !mel"or# rotina poss$vel !"+%,s "eitores me per+%,tam de tempos em tempos $%a" * o me"or; eito de faer a"+%ma coisa. ),te,do $%e por me"or; $%erem dier o mais ve"o; ,o se,tido de $%e e&etem o mais rpido poss
5 compi"ador do Vis%a" 6t%dio teve +ra, de parte de s%as op es de otimi aão retiradas da "i,a de coma,do. @esse se,tido e"e não +era o me"or c=di+o poss
4
3. Aedião. Por e&periJ,cia; $%ero dier a fami"iaridade do dese,vo"vedor com a "i,+%a+em e com o ambie,te. 6ome,te essa co,vivJ,cia poder te dier $%a" eito; $%e criar roti,as mais rpidas o% mais "e,tas... ! e&perime,taão; * esse,cia" at* mesmo para o s%cesso do primeiro item. medião; * sempre %m passo ,ecessrio. sar %ma t*c,ica $%e sempre de% certo ,o passado ,ão * +ara,tia de $%e e"a dar certo oe. ,ecessrio medir a performa,ce de vrios casos para determi,ar $%a" * o mais rpido. Aais adia,te ,este "ivro aprese,tarei %ma roti,a simp"es para medir a $%a,tidade de cic"os de c"ocD; +astos por %ma roti,a. esse,cia" $%e essas medies seam feitas em c=di+os cr
C%digos&'onte deste livro odo c=di+o-fo,te comp"eto $%e vocJ "er ,este te&to comea com %ma "i,a de come,trio die,do o ,ome do ar$%ivo $%e %sei. Com isso vocJ pode copi-"o e compi"-"o. )ssa co,ve,ão * partic%"arme,te importa,te $%a,do temos c=di+os $%e poss%em diversos m=d%"os o% ar$%ivos. 6e preferir a"+%,s dos c=di+os mais importa,tes estão dispo,tab)9 as listagens, neste livro, esse caractere no est? l?9 1o co&iar e colar voc; obter? erros ao c/amar o
(obre as listagens em " e 1ssembly: editor de te4tos usado &ara con.eccionar esse livro substitui as as&as &or dois caracteres es&eciais999 1 as&a de abertura ! di.erente da as&a de .ec/amento9 bserve: #$9 1o co&iar o c@digo e tentar com&il?5lo, obter? erros, com toda certeza999 0entei acertar esse &roblema nos c@digos e acredito que consegui9 'as, esteAa avisado desse &ossvel &roblemaC
@ão %so ?/)s para dese,vo"ver mi,as ap"icaes ape,as o bom e ve"o vim os compi"adores e m%ito materia" de referJ,cia Gma,%ais "ivros man&ages etcH. )ste * %m dos motivos por$%e vocJ ,ão ver scree,sots de a,e"as receitas de co,fi+%raão de me% ambie,te de dese,vo"vime,to; favorito etc. )ste "ivro * sobre dese,vo"vime,to em C %sa,do !ssemb"# para o modo &'(-(4 do processador ?,te" com %ma pitada de i,formaes sobre ard8are e sobre a"+%mas e,tra,as do processador o% do PC. )"e não F %m "ivro sobre ?/)s. $%e ,ãopor %somotivos ?/)s ede e"as me dão a"er+ia Gassim como i,do8sEH ,as "ista+e,s vrios m=d%"os brevidade i,dicarei o i,
!ssim vocJ saber o,de termi,a %m ar$%ivo e comea o%tro. 5 e&emp"o abai&o mostra %m m=d%"o em C camado e""o.c; %m make.ile Gcamado de AaDefi"e;H e a "i,a de coma,do %sada para compi"ar o proeto: >
/* hello.c */ #include int main(int argc, char *argv[]) !rint"($ello, orld&'n) return -----%<----- corte aqui -----%<----# +ae"ile hello hello.o () -o 0 1 hello.o hello.c () -23 -c -o 0 < -----%<----corte aqui -----%<---- make cc -23 -c -o hello.o hello.c cc -o hello hello.o ./hello $ello, orld&
@o caso de "i,as de coma,do os coma,dos di+itveis; aparecerão em ,e+rito. ) $%e me% foco * Li,%& o prompt; * sempre %m Y`Y o% Y[Y Gse o ,
e,to tamb*m ma,ter os c=di+os fo,te co,tidos ,%ma M,ica p+i,a o% separado e,tre p+i,as de %ma ma,eira me,os fra+me,tada poss
Ar(uiteturas de processadores )ntel 5 termo ar$%itet%ra; * %sado de forma basta,te amp"a ,este "ivro. )&istem dois co,ceitos f%,dame,tais: R%a,do os termos i3'( 12 Go% ?!-32H e &'(-(4 Go% ?,te" (4;H são %sados refiro -me aos processadores derivados da fam<"ia '0&'( $%e s%portam e operam ,os modos de 32 e (4 bits respectivame,te. 5 o%tro co,ceito est atre"ado S tec,o"o+ia %sada ,o processador. )&istem vrias e e"as tJm ,omes e,+raados: @ea"em @etQ%rst 6a,d# Qrid+e ?v# Qrid+e Ias8e"" etc para citar ape,as os da ?,te".
12 sarei i3'( ao i,v*s de ?!-32 a$%i mesmo $%e i3'( sea espec
(
Figura : 1rquiteturas dos &rocessadores Intel
6aber sobre essas ar$%itet%ras * Mti" por e&emp"o por$%e foi ape,as ,a etBurst $%e a ?,te" i,trod%i% o modo de (4 bits. )m essJ,cia este "ivro ap"ica-se a todas as tec,o"o+ias desde o i3'( at* a mais rece,te GQroad8e"" ,a *poca em $%e escrevo issoH mas me% foco est mais ,as ar$%itet%ras vi,das depois da etBurst especia"me,te ,a 8asell. Ae%s ambie,tes de teste at%ais são baseados ,essa M"tima ar$%itet%ra. @ão * estra,o $%e %m "ivro $%e se prope a fa"ar sobre ar$%itet%ra de (4 bits recorra a tec,o"o+ias de 32B !co,tece $%e o modo &'(-(4 * ,a rea"idade o mesmo modo i3'( com e&te,ses de (4 bits e com a"+%,s rec%rsos e&tirpados. R%ase t%do o $%e va"e para 32 bits va"e para (4. 5 co,trrio * $%e ,ão se ap"ica... !ssim $%a,do fa"o da ar$%itet%ra i3'( esto% fa"a,do de todas os processadores ?,te" depois do i3'( i,c"%sive. R%a,do fa"o de &'(-(4 todos os processadores depois da ar$%itet%ra @etQ%rst i,c"%sive são o obeto de est%do.
*ão con'unda ar(uitetura com modo de operação @este "ivro o termo i3'( ap"ica-se ta,to a ar$%itet%ra $%a,to a %m modo de operaão dos processadores da fam<"ia &'(. R%a,do "er modo i3'(; isso si+,ifica $%e o processador estar traba"a,do em modo prote+ido; de 32 bits. 5 o%tro modo de operaã o citado ,a doc%me,ta ão da ?,te" * ?!-32e;. )ste * o modo de operaão de (4 bits o% de ma,eira mais precisa o modo de 32 bits com e&te,ses Gda< o YeYH para (4 bits. @este "ivro camo esse modo de &'(-(4; aproveita,do a ,ome,c"at%ra da !A/. !co &'(-(4; mais se4y do $%e ?!-32e;9 5 modo &'(-(4 * tamb*m camado de amd(4; este M"timo * %sado ,a ,omeaão de pacotes do Li,%&. @o te&to vocJ poder ver %ma mist%ra de ,ome,c"at%ras ,esse se,tido... ?!-32e amd(4 e &'(-(4 são %sados de forma i,tercambive" para si+,ificar a mesma coisa: o modo de (4 bits. Pode ser $%e vocJ e,co,tre ?!-32 e i3'( tamb*m $%e $%erem dier a mesma coisa. Avisos 'inais sobre o livro odo esse "ivro fa"a some,te sobre a %,idade ce,tra" de processame,to GCPH o% processador; para os <,timos. Aostrarei m%ito po%co Gse mostrarEH o% ape,as %m res%mo sobre Ps G7ra&/ical Processing UnitH cipsets e o%tros dispositivos co,tidos ,o se% comp%tador. VocJ tamb*m vai reparar $%e %so o termo p"ataforma ?,te"; ,o te&to mesmo sabe,do $%e a !A/ * %m +ra,de competidor a ?,te" firmo%-se como padrão de .acto com re"aão a esse tipo de processador... ?sso ,ão si+,ifica $%e a !A/ fi$%e atrs. !"is recome,do $%e vocJ est%de tambFm 7
os ma,%ais de dese,vo"vime,to de soft8are da !A/ G$%e são mais masti+veis;H. 6= mais %ma coisa $%e vo c ẽ vai reparar_ so a ,otaão ^iQ AiQ iQ iQ e PiQ para $%i"o; me+a; +i+a; tera; e peta; b#tes ao i,v*s das tradicio,ais DQ; AQ; etc. 5 motivo * simp"es: 5s prefi&os D; A; ; ; e P; são potJ,cias de 10 e,$%a,to os padres ?65X?)C '0000-13 e ?))) 1>41-2002 padro,iam os prefi&os Dibi; mebi; +ibi; tebi; e pebi; como se,do m%"tip"icadores ,a base 2 respectivame,te 2 2 2 2 e 2 . ⁰
⁰
⁰ ⁴ ⁰
⁵⁰
!i,da o Q; maiMsc%"o i,dica b#te; e o mi,Msc%"o b; i,dicar bit; como em 1> AibXs G1> mebibits por se+%,doH. !o i,v*s de Dibi; co,ti,%arei cama,do de $%i"o; s= para ,ão ca%sar maior estra,ea o% +oaão G* de comer;BH.
'
Capítulo ! Introdução ao processador R%em prete,de dese,v o"ver soft8are para a p"ataforma ?,te" ,ão deveria estar i,teressado em %m mode"o de processador espec i3 Core2 /%o Pe,ti%m 4'( 3'( etcH mas ,os po,tos com%,s e,tre e"es. @o e,ta,to $%a,to mais vocJ mer+%"ar em deta"es ver $%e ,ão e&iste ta" coisa de ar$%itet%ra com%m;. ! cada par de a,os a ?,te" aprese,ta %ma ,ova ar$%itet%ra ,omeada a partir de a"+%m "%+ar o% cidade ,orte-america,a G6a,d# Qrid+e ?v# Qrid+e Ias8e"" etcH $%e poss%i %ma s*rie de ,ovos ar$%itet%ra por e&emp"o poss%i sem $%aseco,tar o dobro dea"+%mas poder de processame,to $%e rec%rsos. s%a irmã!mais ,ova a8asell ar$%itet%ra (andy Bridge com ,ovidades. 6em "evar em co,ta a ar$%itet%ra o $%e prete,do mostrar ,este cap
odos de operação Processadores da fam<"ia ?,te" '0&'( a partir do '02'( podem traba"ar em diversos modos. 6= estamos i,teressados ,os processadores $%e s%portem o modo &'(-(4. )ste * o modo prote+ido pa+i,ado de 32 bits com eGtens/es para *& bits . importa,te perceber $%e ,ão e&iste %m modo de (4 bits; mas %ma e&te,são ao modo de 32. @ote tamb*m os termos prote+ido; e pa+i,ado;. ma breve e&p"icaão sobre proteão e pa+i,aão * dada ,os t=picos se+%i,tes. )&istem o%tros de e&p"orarei operaão do processador $%e são i,teressa,tes e %sados emGdepois casos m%ito espec
"o,+; e porta,to ,ão fa"arei do modo compatib"e; a$%i. 5 modo "o,+; * o $%e camo a$%i de modo &'(-(4.
O (ue signi'ica !proteção#, @%m ambie,te o,de vrios processos podem estar se,do e&ec%tados de forma co,corre,te * importa,te $%e %m ,ão possa i,terferir ,o o%tro. Por i,terferJ,cia; podemos e,te,der $%e %m processo ,ão pode ter acesso aos dados e c=di+o de o%tro. Pe"o me,os ,ão diretame,te. Proteão ,este se,tido * a i,fraestr%t%ra oferecida pe"o processador para iso"armos processos. !trav*s da proteão podemos por e&emp"o ter c=di+os e dados do Der,e" comp"etame,te iso"ados de e dadosrec%rsos de %m pro+rama do %s%riom em e&ec%ão ai,da %m pro+rama do %s%rio temc=di+os como acessar de o%tro pro+rama. ,ão sabe;e$%e o o%tro e&iste. !ssim cada ,ão processo tem o se% pr=prio espao; de mem=ria prote+ido. Veremos $%e ape,as o Der,e" o% o sistema operacio,a" tJm como acessar todo e $%a"$%er rec%rso de processos mesmo $%e ,ão seam os se%s pr=prios. Aas o co,trrio ,ão va"e.
O (ue signi'ica !paginação#, !o i,v*s do processador traba"ar ape,as com a mem=ria f
-roteção e segmentos. no modo protegido em /0 bits 6e vocJ est%do% assemb"# para a fam<"ia '0&'( vi% $%e e&istem seis re+istradores se"etores de se+me,tos; GC6 /6 )6 66 F6 e 6H. @o modo rea"; de 1( bits o co,teMdo desses re+istradores for,ece %m e,dereo base de 20 bits $%e apo,ta para %m se+me,to; de (4 ^iQ de tama,o. ?sso * feito des"oca,do o co,teMdo de %m desses re+istradores para a es$%erda em 4 bits 13 @a verdade são 3: 5 espao L=+ico o Virt%a" e o F
10
$%e * a mesma coisa $%e m%"tip"icar o va"or por 1( efetivame,te adicio,a,do esses bits e&tras GeradosH S direita do va"or co,tido ,esses re+istradores. /e posse desse e,dereo base adicio,amos %m des"ocame,to e obtemos %m endereço l5gico de 20 bits: @o modo prote+ido a coisa * %m po%co mais comp"icada. )sses re+istradores não co,t*m o e,dereo base de %m se+me,to. )"es co,t*m %m <,dice $%e seleciona %ma e,trada em %ma tabela de descritores.
Figura H: Estrutura de um selector de segmentos9
5 dia+rama acima mostra a estr%t%ra de %m se"etor. emos 13 bits de <,dice 1 bit $%e ,os di o tipo; de se"etor G$%e ,ão importa a+oraH e dois bits $%e ,os diem o privi"*+io; do se"etor G$%e e&p"ico mais adia,teH. Com 13 bits %m se"etor pode se"ecio,ar %ma das '192 e,tradas da tabe"a de descritores. ! tabela de descritores co,t*m e,tradas $%e descre!em Gda< o ,omeEH se+me,tos de mem=ria $%e podem ser se"ecio,ado s pe"o seletor Gde ,ovo da< o ,omeEH. Cada e,trada ,essa tabe"a * camada de descritor e tJm mais o% me,os a se+%i,te estr%t%ra simp"ificada 14:
Figura 2: Forma resumida de um descritor9
@o modo i3'(pode sem ter %sarmos o rec%rso de pa+i,aão %m b"oco Gse+me,toH deemem=ria descritoem ,%m descritor at* 4 iQ Gdepe,de do campo tama,o; do descritorH estar "oca"iado $%a"$%er "%+ar da mem=ria f
mome,to e * ma,tido ,o se"etor de se+me,to de c=di+o Gre+istrador C6H. 5 CPL tamb*m * ma,tido como c=pia ,o re+istrador 66 G (tack (electorH por$%e o processo e&i+e o %so da pi"a em i,str%es como C!LL e N)66 bem como tratame,to de i,terr%pes_ /i+odoc=pia campo de privi"*+io do se"etor * de fato,o NPL mas precisa ter o mesmo ,
14 ! estr%t%ra ,ão * assim. )ste * %m es$ %ema para faci"itar a compree,são.
11
6%po,amos $%e o CPL sea 3 G5 se"etor de c=di+o C6 apo,ta para a"+%m "%+ar do users&ace) e s%po,a tamb*m $%e o NPL do se"etor /6 sea tamb*m 3. )ste NPL Gde /6H ser cecado co,tra o /PL ,a e,trada da tabe"a de descritores correspo,de,te ao <,dice co,tido ,o se"etor e co,tra o CPL. @o caso se o /PL tamb*m for 3 e,tão o processador poder e&ec%tar a i,str%ão caso co,trrio e"e ca%sar %m segmentation .ault o% %m general &rotection error. @este caso todos os trJs ,
Figura 6: 1n!is de &rivil!gio9
5%tra ,ome,c"at%ra $%e vocJ pode acar para c=di+os e dados $%e esteam prese,tes ,a re+ião de mem=ria descrita com ,
12
Onde 'ica a tabela de descritores, 5 processador ,ão poss%i %ma re+ião de mem=ria i,ter,a $%e ma,t*m a tabe"a de descritores. )ssa tabe"a tem $%e ser co"ocada ,a mem=ria f. 5
processador %sa esse e,dereo como base para "oca"iar as e,tradas ,a tabe"a de descritores de acordo com o <,dice co,tido ,%m se"etor. ! primeira e,trada da tabe"a * sempre erada e co,siderada i,v"ida. )sse * %m descritor @L5 1(. m <,dice ero ,%m se"etor apo,tar para esse descritor e $%a"$%er acesso S mem=ria %sa,do esse se"etor ca%sar %m segmentation .ault o% PF G7eneral Protection FaultH. !s demais e,tradas da tabe"a descrevem re+ies da mem=ria "i,ear para %so espec
Seletores e descritores de segmentos no modo x12&23 5 modo &'(-(4 * %m modo meio es$%isito em a"+%,s aspectos. !t* e,tão ta,to ,o modo rea" $%a,to ,o modo i3'( os se"etores faem e&atame,te o $%e e"es foram feitos para faer: 6e"ecio,am %m se+me,to de mem=ria... @o modo &'(-(4 e"es $%ase ,ão servem para ,adaE 5s re+istradores C6 /6 )6 F6 6 e 66 co,ti,%am e&isti,do mas o M,ico $%e rea"me,te tem a"+%ma %ti"idade * o C6 por$%e +%arda em se% i,terior o CPL e %m bit die,do em $%e moda"idade do modo &'(-(4 o c=di+o ser e&ec%tado_ )&istem dois: 5 long mode e o com&ability mode. @o modo com&atvel o processo comporta-se do mesmo eito $%e o modo i3'( e&ceto pe"o fato de $%e temos acesso aos re+istradores e&te,didos de (4 bits. 5s demais se"etores estão desabi"itados ,o modo &'(-(4 p%ro. 6e e"es estiverem todos erados Ge porta,to i,v"idos;H o% com $%a"$%er o%tro va"or serão simp"esme,te i+,orados: /* readsel.c */ #include #de"ine C4DEF4G4D2H(s) ' EEasmEE EEvolatileEE ( mov %% #s ,%%a@ a ((s)) ) unsigned short cs, ds, es, "s, gs, ss
1> )&iste %ma o%tra tabe"a de descritores camada *ocal Descri&tor 0able. Por motivos de simp"icidade vo% i+,orar a e&istJ,cia dessa tabe"a ,a e&p"icaão $%e se+%e... 1( )ssa * %ma e&i+J,cia da ar$%itet%ra ?,te" para o modo prote+ido e ,ão tem @!/! aver com po,teiros @LL.
13
void main(void) C4DEF4G4D2H(cs) C4DEF4G4D2H(ds) C4DEF4G4D2H(es) C4DEF4G4D2H("s) C4DEF4G4D2H(gs) C4DEF4G4D2H(ss) !rint"(F@%AI, JF@%AI, 4F@%AI, KF@%AI, CF@%AI, FF@%AI'n, cs, ds, es, "s, gs, ss) -----%<----- corte aqui -----%<---- gcc -o readsel readsel.c ./readsel F@33, JF@, 4F@, KF@, CF@, FF@LM
@o e&emp"o acima ,ote $%e /6 )6 F6 e 6 estão erados. Aesmo assim o pro+rama foi capa de "erXescrever ,a mem=ria atrav*s do se"etor /6E 5 re+istrador C6 co,t*m %m va"or e de acordo com o dia+rama da estr%t%ra de %m se"etor $%e mostrei a,tes e"e apo,ta para o <,dice ( da tabe"a de descritores globais G?0H e re$%isita o privi"*+io ,o users&ace GNPL3H. 5 se"etor 66 parece desafiar o $%e foi dito a,tes. )"e co,t*m %m va"or v"ido G<,dice 12 e NPL3H mas isso est ai ape,as para co,tro"e i,ter,o do sistema operacio,a" e ,ão tem o m<,imo si+,ificado para os ,ossos pro+ramas. R%er dier: ,ão * %sado pe"o processador. 6e vocJ e&ec%tar o pro+rami,a acima ,o modo i3'( obter va"ores v"idos para todos os se"etores e a"ter-"os poder "evar ao erro de segmentation .ault. @o modo &'(-(4 p%ro podemos a"terar sem medo /6 e )6. 5s re+istradores F6 e 6 são especiais ,o se,tido de $%e podem %sar %m descritor como offset para %m e,dereo "i,ear depe,de,do da co,fi+%raão do processador. ?sso ,ão * %sado ,o users&ace e ,ão ,os i,teressa ,o mome,to. @este po,to vocJ pode estar se per+%,ta,to o,de diabos foi parar a proteão o% sea os privi"*+ios ,o modo &'(-(4B 6e os se"etores ,ão tem %so ,esse modo i,c"%i,do o NPL como o processador sabe $%aisse,do re+ies pode o% ,ão acessarem se C6 ,ão mas comparaão comdas o /PLB modo osão CPL co,ti,%a ma,tido i,ter,ame,te os privi"*+ios re+ies@este de mem=ria ma,tidas ,os descritores de &?ginasE 5 modo de pa+i,aão * obrigat5rio ,o modo &'(-(4 por esse motivo...
4escritores no modo x12&23 /os descritores %sados por se"etores ape,as os descritores de se+me,tos de c=di+o são ,ecessrios ,o modo &'(-(4 e ape,as o se"etor C6 * co,siderado os demais estão desabi"itados. !s e&cees são os se"etores F6 e 6 $%e podem ser %sados para apo,tar para e,dereos base ,os descritores para os $%ais apo,tam. 5 se"etor 6 * partic%"arme,te i,teressa,te por$%e ,o kernels&ace podemos %sar a i,str%ão 6!P6 $%e troca o e,dereo base pe"o co,teMdo da A6N17 ?!32]^)N@)L]6]Q!6) G0&C0000102H. ?sso permite ma,ter o e,dereo de estr%t%ras acess
17 A6Ns são re+istradores especiais ma,tidos pe"o processador. ! si+"a vJm de 'ac/ine (&eci.ic egister.
14
Cac"e de descritores 6empre $%e %m se"etor * carre+ado %m descritor * copiado para %ma parte i,vis
cac/ing de
-roteção no modo x12&23 /esco,sidera,do a pa+i,aão ,o modo &'(-(4 o processador ass%me $%e o e,dereo base sempre * ero e o tama,o do se+me,to correspo,de a todo o espao e,dereve" poss
rdi,["sr;@=ra@*L]
@este caso se F6 apo,ta para %m descritor de o,de a i,str%ão obter o e,dereo base e a somar ao co,teMdo de NQU e ao dobro de N!U co"oca,do o va"or ca"c%"ado em N/?. 6e te,tarmos %sar prefi&os de se"etores sem $%e seam F6 o% 6 em referJ, cias S mem=ria e"es são s%mar iame,te i+,orados ,o prefi&os pior caso %ma e&ce de instruJo Gunde.ined instruction H $%e o% a"+%,s ,ãoca%sarão estão defi,idos para ão o modo &'(-(4: inde.inida mov ra@,[csr;@]
Nsso nOo est8 dis!onPvel no assem;lQ @RS-SA e, causa uma e@ceTOo&
$%e se"etores ,ão são %sados as i,str%es L/6 L)6 L66 LF6 e L6 não eGistem ,o modo &'(-(4_ c"aro $%e ai,da podemos carre+ar os se"etores via i,str%ão A5V.
1' 5s bits e&cede,tes tJm $%e ser ,ecessariame,te %ma c=pia do bit >1 o% sea %m e,de reo ,o modo &'(-(4 tem si,a"E
1>
1(
Capítulo "! Interrompemos nossa pro#ramação$$$ Citei e4ceJKes e fa"tas ,o cap
O (ue 5 uma interrupção, 5 processador est co,sta,teme,te e&ec%ta,do c=di+o. a,to o c=di+o do pro+rama e&ec%tado ,o users&ace $%a,to o c=di+o co,tido ,o Der,e". @ão e&iste ta" coisa como processame,to parado; o% tempo ocioso; ,os processadores 19... ?sso * %ma abstraão %sada pe"o sistema operacio,a" o% ambie,tes +rficos. )m res%mo: 5 processador est e&ec%ta,do c=di+o o tempo todo sem parar... /%ra,te a e&ec%ão de %m pro+rama certos circ%itos Gpor e&emp"o o do tec"adoH podem pedir S CP $%e o processame,to ,orma" sea interrompido para e&ec%tar %ma rotina de tratamento de ser!iço G?6N Interru&t (ervice outine H. )ssa roti,a vai "idar com as ,ecessidades do dispositivo $%e re$%isito% a ate,ão e ao termi,ar faer com $%e o f"%&o de processame,to retor,e ao ,orma". 5 tec"ado fa isso m%da,do o estado de %m si,a" e"*trico ,o processador do , o,de ?NR2 %sada. 5 ,Mmero da1>re$%isião tamb*me est comdea reso"%ão de prioridade G?NR1,ão tem* mais prioridade do $%e ?NR7 por e&emp"o. @o e&emp"o do circ%ito do tec"ado e"e est co,ectado S ?NR1. R%a,do vocJ di+it a %ma tec"a o co,tro"ador do tec"ad o G^QC T MeyBoard "ontrollerH fa %m pedido de i,terr%pão ?NR1 ao controlador &rogram?vel de interru&JKes GP?CH. 5 P?C * pro+ramado de forma ta" $%e $%a,do o processador reco,ece o pedido Gvia pi,o ?@[ do processadorH e"e recebe %m ,Mmero correspo,de,te S e,trada da tabe"a de i,terr%pes $%e deve ser %sada para camar a roti,a de tratame,to de servio... /a< o processador pra t%do o $%e est fae,do sa"ta para a ?6N correspo,de,te e ,o fi,a" dessa roti,a i,dica ao P?C $%e trato% a i,terr%pão escreve,do %m coma,do )5? G End . Interru&tionH ,%m re+istrador especia" do co,tro"ador. Lo+o em se+%ida e&ec%ta %ma i,str%ão ?N) $%e far o processador retomar a e&ec%ão ,orma". !ssim como os descritores de se+me,tos e&iste %ma tabe"a $%e descreve cada %ma das 2>( e,tradas poss
As )nterrupç6es especiais: 7xceç6es. 8altas e Abortos 19 Qem... ,ão * bem assimE Aas co,ti,%e "e,do oDB
17
!"+%mas i,terr%pes são ca%sadas ,ão por %ma si,a"iaão feita por %m circ%ito e&ter,o mas pe"o pr=prio processador. o caso de fa"tas como 7eneral Protection Fault Page Fault o% (tack ver.lo Fault. 6e certas co,dies esperadas pe"o processador forem vio"adas e"e i,terrompe o processame,to ,orma" e desvia o f"%&o de processame,to para tratadores especiais $%e "idarão com essas fa"tas;. )&istem trJs tipos especiais de i,terr%pes de fa"as;: )&cees Fa"tas e !bortos... ! difere,a e,tre os trJs termos * $%e %m aborto; * a"+o mais drstico $%e %ma fa"ta; $%e * mais drstico $%e %ma e&ceão;. m erro de divisão por ero ca%sar %ma e&ceão;. m erro de va"idaão de privi"*+ios ca%sar %ma fa"ta;. Aas e&istem erros $%e co"ocam o processador em %m estado i,stve". )sses são os abortos; $%e +era"me,te ,ão podem ser tratados Ge "evam S Blue (creen . Deat/ o% a %m Menel PanicH. !bortos s= i,teressam ao sistema operacio,a". )stamos i,teressados ape,as em a"+%mas fa"tas e e&cees.
7xistem dois tipos de interrupç6es de "ardware di'erentes Vimos acima o $%e * %ma ?NR. )ssas i,terr%pes podem ser mascaradas; Go% desabi"itadasH faci"me,te. 5 f"a+ ?F ,o re+istrador NFL!6 toma co,ta disso do "ado do processador. 6e o f"a+ ?F estiver erado o processador ,ão aceitar ,e,%ma ?NR. Para mascarar ?NRs * s= %sar a i,str%ão CL? era,do o f"a+ ?F. Para abi"itar as ?NRs basta e&ec%tar a i,str%ão 6? fae,do ?F ser setado. )&iste tamb*m %ma i,terr%pão de ard8are $%e ,ão pode ser mascarada. )"a * camada @A? Gon 'askable Interru&tH e est associada a %m co,%,to de erros $%e o se% comp%tador pode e,fre,tar e são verificados por a"+%m circ%ito e&ter,o... era"me,te ,ão estamos m%ito i,teressados em @A?s. Atenção: R%a,do eramos o f"a+ ?F o processador ,ão aceitar as ?NRs mas isso ,ão si+,ifica $%e o P?C ,ão co,ti,%e recebe,do-as. )m certos casos o sistema operacio,a" pode precisar mascarar; i,terr%pes ,o pr=prio P?C a"*m de erar o f"a+ ?F. ! mesma coisa aco,tece com a @A?... 5 processador * sempre obri+ado a aceitar @A?s mas podemos desabi"itar o si,a" e"*trico em o%tro circ%ito do PC para i,ibi-"o Gestra,ame,te o cip co,tro"ador do tec"ado permite faer issoEH. )nterrupç6es são sempre executadas no 9ernelspace @ão * poss
20 66 tamb*m * empi"ado por motivos de compatibi"idade. Lembre-se e"e ,ão * %sado ,o modo &'(-(4.
1'
Figura N: Pil/a, antes e de&ois de uma interru&Jo ou e4ceJo com c@digo de erro9
R%a,do o tratador e,co,tra %ma i,str%ão ?N) e"e rec%pera os co,teMdos empi"ados ,a ordem em os foram empi"ados sa"ta,do para o C6:N?P co,tido ,a pi"a. ?sso * mais o% me,os como N)$%e f%,cio,a com a"+%,s re+istradores a mais. respo,sabi"idade das roti,as de tratame,to de i,terr%pes preservarem o co,teMdo dos re+istradores de %so +era" Ge&ceto N6PH e rec%per-"os a,tes de sair da i,terr%pão.
8altas importantes para per'ormance ! fa"ta mais importa,te do po,to de vista da performa,ce * a Page Fault. bom "embrar $%e %ma p+i,a; * %ma re+ião de 4 ^iQ ,a mem=ria mapeada ,%ma tabe"a $%e permite o %so de mem=ria virt%a";. )ssa fa"ta aco,tece de acordo com %ma das ci,co co,dies abai&o: • ! p+i,a ,ão est prese,te ,a mem=ria f
5 ,
•
e,tar escrever em %ma p+i,a read5only\
•
N?P apo,ta para %ma p+i,a marcada como ,ão e&ec%tve";\
•
5s bits reservados ,o mapa de p+i,as são difere,tes de ero.
Co,ecer essas re+ras * i,teressa,te mas o mais importa,te * saber $%e sempre $%e %m Page Fault o processador * i,terrompido e %m tratador e&ec%tado. ?sso afetar o%tras re+ies do processador como caces por e&emp"o. /os motivos para a fa"ta o primeiro * o mais importa,te. atrav*s de"e $%e o processo de &age sa&&ing * feito. !ssim $%a,to mais fa"tas de p+i,a provave"me,te o sistema operacio,a" estar mapea,do p+i,as T possive"me,te fae,do +ravaes e "eit%ras em disco tamb*m. @ão * de espa,tar $%e &age .aults possam ser o motivo de %ma +ra,de perda de performa,ce. emos $%e arr%mar %m eito de evit-"as...
Sinais: )nterrupç6es no user space 6e% c=di+o em Cde pode imp"eme,tar de isto tratame,to de si,ais. pra )sseso si,ais sãofae,do i,terr%pes; ,o f"%&o ,orma" operaão do se% roti,as processo * se% pro+rama $%e est para ate,der %m si,a" e $%a,do a roti,a de tratame,to * fi,a"iada e"e pode co,ti,%ar o $%e estava fae,do Go% em a"+%,s casos abortar o processoH. 6i,ais são %sados em ambie,tes P56?U. 5 i,do8s por e&emp"o não imp"eme,ta si,ais21... 21 Qem.... pe"o me,o s a imp"eme,taão ,ão * tão boa. 5 A6/@ i,dica $%e a f%,ão signal>) * imp"eme,tada para si,ais como 6??@ 6?!QN 6?FP) 6??LL 6?6)V e 6?)NA e * s=. Aesmo assim 6??@ ,ão * s%portado pe"o i,do8 s Gembora signal>) o permitaH. 5%tros si,ais importa,tes como 6?^?LL 6?CIL/ e
19
m si,a" * co,ecido por %m va"or i,teiro ape"idado por (I7444. !bai&o temos %ma "ista com a"+%,s dos si,ais mais %sados. @ote $%e todo si,a" se ,ão for tratado tem %m comportame,to padrão: >inal
escrição
6??@ 6?^?LL
5 %s%rio %so% Ctr"C ,o termi,a". *rmi,o do processo. Necebido $%a,do o processo * matado;. *rmi,o do processo.
6?6)V
ma referJ,cia i,v"ida S mem=ria foi *rmi,o do processo. feita. Pedido de t*rmi,o do processo. *rmi,o do processo. Pedido de s%spe,são GparadaH do 6%spe,são do processo. processo GCtr"O ,o termi,a"BH. 6i,ais defi,idos pe"o %s%rio. *rmi,o do processo. Processo fi"o GforDedH foi termi,ado. ?+,orado. 6i,a" do timer. gti" para criar timeo%ts; *rmi,o do processo. em processos. )sse si,a" * pro+ramado via s#sca"" alarm>).
6?)NA 6?65P 6?6N1 6?6N2 6?CIL/ 6?!LNA
Comportamentopadrão
0abela : 1lguns sinais mais con/ecidos
5s si,ais 6?^?LL e 6?65P ,ão podem ter tratadores o% sea o comportame,to padrão * fi&o para esses si,ais. 6?^?LL * partic%"arme,te drstico. )"e mata o processo ,ão importa o $%e estea aco,tece,do. com%m $%a,do o %s%rio $%er matar %m processo de ma,eira defi,itiva $%e %se: kill -9 8132
@este e&emp"o o coma,do kill e,via %m si,a" 6?^?LL G9H para o processo com P?/ '132. 5 correto seria e,viar o si,a" 6?)NA e s= se o processo ,ão termi,ar e,viar 6?^?LL: kill -SIGTERM 8132 9 es!era um !ouco 9 ps -eo pid | grep 8132 kill -SIG!I"" 8132
5 motivo de 6?^?LL ,ão poder ser tratado * por$%e e"e precisa mesmo ter o poder de termi,ar o processo. 5s demais si,ais podem ter tratadores $%e se ,ão camarem a f%,ão e4it a,tes de se% t*rmi,o farão com $%e se% pro+rama co,ti,%e roda,do de o,de foi i,terrompido. 6%po,a $%e vocJ $%eira desabi"itar o f%,cio,ame,to do Ctr"C. Qasta faer a"+o assim: signal(FNCNUD, FNCENCU)
5 s
5,de * c"aro si+a,d"er; pode ser o%tro ,ome de f%,ão... m e&emp"o com re"aão ao 6??@ se o %s%rio di+itar Ctr"C d%ra,te a e&ec%ão de se% processo poderia ser este:
6?!LNA são in!lidos ,o i,do8s.
20
static void sigintEhandler(int signal) !rint"(V'nWsu8rio !ediu interru!TOo&'nX X4W UY2 J4NI2&'nX) 9 /* 4m algum lugar do seu !rograma, registramos o mani!ulador !ara FNCNUD */ signal(FNCNUD, sigintEhandler)
simp"es assim... 6= preciso a"ert-"o $%e a f%,ão signal>) * obso"eta. 5 m*todo preferido para re+istrar ma,ip%"adores de si,ais * %sa,do a f%,ão sigaction>). )sta f%,ão permite %m a%ste fi,o do re+istro e ma,ip%"aão de si,ais. )"a permite re+istro de ma,ip%"adores $%e tJm acesso a mais i,formaes sobre o si,a" e i,c"%sive a possibi"idade de b"o$%ear o%tro si,ais e,$%a,to o tratador estiver em e&ec%ão. )m essJ,cia sinais são i,terr%pes...
;m exemplo de uso de sinais. no Linux !"+%mas f%,es ,ão retor,am at* $%e a"+%ma coisa aco,tea. )ssas f%,es são ditas b"o$%eadas; pe"o sistema operacio,a". Por e&emp"o por defa%"t a f%,ão recv>) $%e "J %m co,%,to de caracteres vi,dos de %m socket ,ão retor,a at* $%e te,a b#tes "idos ,os b%ffers do driver de rede... ma ma,eira de criar %ma roti,a com s%porte o rec%rso de timeout %sa,do recv>) * esta: int alarm /* +ani!ulador do sinal. */ int sigalarm(int signal) alarm B 9 /* Zssinala o handler de interru!TOo !ara FNCZGH+. */ signal(FNCZGH+, sigalarm) 9 /* ede ao ernel !ara gerar um FNCZGH+ !ara o nosso !rocesso em timeoutEinEseconds segundos. */ alarm(timeoutEinEseconds) /* Ueste !onto o seu !rocesso !ode ser V;loqueadoX. */ len recv("d, ;u""er, si6eo"(;u""er), ) /* ede ao ernel !ara ignorar o !edido anterior, se a "unTOo acima nOo "or ;loqueada. */ alarm() /* Fe o alarme "oi dado, "a6 algo& */ i" (alarm) 9 /* trata erro de timeout aqui */ 9
!o assi,a"ar o ma,ip%"ador sigalarm>) ao si,a" 6?!LNA $%a,do este ocorrer o processo ,ão ser termi,ado do 6?!LNAH processo b"o$%eado; termi,ar e retor,ar... Lo+oGcomportame,to depois de recv>)defa%"t co"ocamos %m alarm>G)mas parao dier ao Der,e" $%e sevai o 6?!LNA ,ão foi e,viado ,ão o e,vie maisE 6e o si,a" foi e,viado setamos a varive" alarm para 1 i,dica,do $%e o tempo "imite passo%.
*ão use signal<=. use sigaction<= ! f%,ão signal>) * obso"eta e ,ão deve mais ser %sada. )"a ai,da e&iste por motivos de 21
compatibi"idade. 5 correto oe em dia * %sar a f%,ão sigaction>) $%e * bem mais f"e&) ,a rea"idade %sa sigaction>) para faer a s%a m+ica mas o tipo de i,terr%pão Gse permite restart o% ,ão da f%,ão b"o$%eadora; por e&emp"oH depe,de do si,a" em si ,ão de a"+%m a%ste c%idadoso $%e vocJ possa faer... !ssim %se sigaction>) para %m me"or .ine tunning s= comportame,to do tratador do si,a".
7xiste mais sobre sinais do (ue diz sua vã 'iloso'ia>>> ?sso ai em cima * ape,as %m aperitivo sobre si,ais. 6i,ais podem ser b"o$%ados mascarados. Podemos tratar si,ais em treads etc... Co,s%"te %m bom "ivro sobre dese,vo"vime,to para ,i& como o materia" de ic/ard %9 (tevens G!dva,ced Pro+rammi,+ i, te @?U ),viro,me,t ird )ditio,; por e&emp"oH.
22
Capítulo %! &esol'endo d('idas )requentes sobre a *in#ua#em C !,tes de cair de boca; ,o assemb"# * co,ve,ie,te te,tar acabar de ve com a"+%mas dMvidas $%e est%da,tes de "i,+%a+em C tJm. !s pri,cipais pe"o $%e posso perceber são sobre parametriaão de f%,es e o %so de po,teiros. !$%i vai %ma disc%ssão sobre esses ite,s $%e faem o pro+ramador ,ovato pe,sar $%e C * comp"icada e ceia de armadi"as.
?eaders e %dulos: ;ma (uestão de organização !"+%,s de me%s "eitores tJm a dMvida recorre,te sobre o por$%e da e&istJ,cia de ar$%ivos com e&te,são .;... @%m c=di+o fo,te em C * com%m termos diversos ar$%ivos com e&te,são .c; Gcamados de m=d%"os;H e ar$%ivos com e&te,são .; Gcamados de eaders; o% cabea"os;H. 5s m=d%"os serão compi"ados $%ase sempre separadame,te e depois "i,Dados para mo,tarem o e&ec%tve" o% bib"ioteca fi,a". 5s ar$%ivos /eader e&istem para or+a,iar me"or os c=di+os fo,te. )"es não são bib"iotecas de f%,es. Nepito e e,fatio: Ar$ui!os header não são bibliotecas Qib"iotecas e&istem em dois sabores: )stticas e di,Kmicas. Qib"iotecas estticas são co,%,tos de f%,es $%e serão "i,Dadas ao se% c=di+o fo,te forma,do %m pro+rama mo,o"
5 motivo da defi,ião do s
23
/* headerB.h */ #include VheaderL.hX -----%<----- corte aqui -----%<----/* headerL.h */ #include VheaderB.hX
!o rea"iar as dec"araes dos /eaders desse eito some,te se os s
C"amadas de 'unç6es contidas no mesmo m%dulo @%m c=di+o como abai&o vocJ espera $%e a f%,ão . sea camada pe"a f%,ão g mas ,ão * isso $%e +era"me,te aco,tece: /* teste.c */ int "(int @) return @ = @ int g(int @) return @ * "(@)
)m casos como esse o compi"ador te,de a criar %ma f%,ão . $%e pode ser camada por f%,es co,tidas em o%tros m=d%"os e incorporla o% sea codific-"a inline ,a f%,ão g. Com isso vocJ acaba com d%as c=pias do mesmo c=di+o: ma $%e pode ser camada e o%tra $%e foi i,corporada. Vea como fica em assemb"#: " lea ret
ea@,[rdi=rdi]
g lea ea@,[rdi=rdi] imul ea@,edi ret
Jeveria ser Vcall "X.
!$%i ,ão +ra,des prob"emas mas ima+i,e $%e . sea %ma roti,a +ra,de com %mas 200 i,str%es. !o i,v*s de %m simp"es C!LL em g ter>attr)) ,o i,
EEattri;uteEE((noinline)) int "(int @) return @=@ int g(int @) return @*"(@)
@aman"o de inteiros e ponteiros 6e vocJ %so% C com i,do8s deve ter se per+%,tado: Pra $%e diabos e&iste o tipo Y"o,+YB !fi,a" ,o i,do8s Y"o,+Y e Yi,tY tJm e&atame,te o mesmo tama,o e a mesma semK,tica Gambos são i,teiros de 32 bits de tama,oH. ?sso tamb*m * v"ido para o modo 32 bits da maioria dos sistemas operacio,ais. @o modo &'(-(4 a coisa * mais comp"icada... )&istem $%atro mode"os de %so dos tipos i,teiros para o modo &'(-(4 depe,de,do do sistema operacio,a" em %so. )"as são co,ecidas por si+"as: ?L32P(4 Go% LLP(4H LP(4 Go% ?32LP(4H ?LP(4 e 6?LP(4. si+"as o Y?Y correspo,de ao tipo YLY ao Y"o,+Y e YPY S YPo,teiroY. ?32LP(4 si+,ifica i,t de 32@essas bits\ "o,+ e po,teiros de (4 bits; porYi,tY e&emp"o. )is %ma tabe"a mostra,do as difere,as em bits e,tre os tipos dos $%atro mode"os e $%em os %sa Ge&c"%< os po,teiros $%e ,os $%atro mode"os e"es tJm sempre (4 bits de tama,oH: )odelo short
I*2HP36 I2H*P36 I*P36 (I*P36
1( 1( 1( (4
int
>istema -peracional
long
32 32 (4 (4
32 (4 (4 (4
i,do8s P56?U !Q? I!L GIe""o !veE;H @?C56
0abela H: 'odelos de inteiros e sistemas o&eracionais
! maioria dos sistemas operacio,ais de (4 bits at%ais $%e são baseados em P56?U difere,ciam os tipos Y"o,+Y e Yi,tY. Aesmo assim o tipo Y"o,+ "o,+Y foi i,corporado ,a especificaão de C para +ara,tir te,amos!i,da %m tipoa e&p"
*ão 5 prudente con'iar nos taman"os dos tipos de'ault a"ve vocJ te,a se acost%mado com as ,ovas ar$%itet%ras de processadores o,de os tipos c/ar s/ort int, long e long long te,am tama,os defi,idos. @ão * %ma boa id*ia co,fiar ,isso se vocJ prete,de criar c=di+o para vrias p"ataformas. )m primeiro "%+ar não eGistem tipos s/ort long e long long. )ssas são variaes de tama,o do int. )m se+%,do "%+ar esses tam,os variam de acordo com o processador. )is %m e&emp"o ,a tipo tabe"a S se+%ir:
2>
Tipo
H,4
,4,*
3, seu *periores
c/ar
' ' ' 1(
' 'B 1(B 1(
' 1( 32 3223
s/ort int int long int
0abela 2: 0aman/o de ti&os &or &rocessador
@%m processador de ' bits como o O-'0 $%ase todos os tipos de i,teiros tJm ' bits de tama,o. Fa se,tido por$%e trata-se de %m processador de ' bitsE ,o '0'( &rovavelmente o tipo int tem 1( bits e essa ser a difere,a e,tre s/ort e long... ,o 3'( o tipo s/ort int * difere,te do c/ar. Aar$%ei com B; 5s tama,os em bits $%e ,ão te,o mais certea Gfa tempo $%e ,ão "ido com esses processadoresH. esse,cia" $%e vocJ co,s%"te a doc%me,taão do compi"ador para o processador a"vo o% faa %so do e ader limits./ $%e co,t*m co,sta,tes como CI!N]A!U 6I5N]A!U ?@]A!U e L5@]A!U e&p"icita,do o m&imo va"or $%e pode ser armae,ado ,esses tipos. !"is se$%er podemos s%por $%e %m c/ar te,a sempre ' bits... )m comp%tado res a,ti+os Ga"+%,s main.rames por e&emp"o %m c/ar pode m%ito bem ter 7 bitsH. Para isso limits9/ for,ece a co,sta,te CI!N]Q?6. 5%tro deta"e * o %so do operador sizeo.. )"e sempre "e dar o tama,o em b#tes de %m tipo at* mesmo po,teiros. 6e,do %m operador Ss vees e"e ,ão pode ser %sado ,o pr*-processador do compi"ador. Faer a"+o como mostrado abai&o ca%sar erro de pr*-compi"aão: #i" si6eo"(char *) & R 9 #endi"
/a< a importK,cia dos s
7xiste di'erença entre !declarar# e !de'inir# um s$mbolo Primeiro vamos a %ma defi,ião de s
VocJ est declarando %m s
de#inido
)&iste tamb*m %m ata"o o,de vocJ pode dec"arar e defi,ir %m s
?sso * %m ata"oE 5 $%e vocJ est rea"me,te fae,do * dec"arar o s
2(
i,t; e "o+o em se+%ida defi,i,do o se% co,teMdo como te,do o va"or 2. ),tão ,ão parece aver m%ita difere,a e,tre declarar e de.inir certoB ! difere, a est ,os casos o,de ,ão * poss
?,forma ao compi"ador $%e em a"+%m "%+ar e&iste %ma f%,ã o camada &rint. $%e toma %m po,teiro para %m c/ar, co,sta,te e %ma "ista variv e" de parKme tros retor, a,do %m int. @o co,te&to do %so dessa f%, ão ,ão * ,ecessrio saber o,d e e"a foi de#inida. )sse * %m tipo de dec"araão $%e vocJ e,co,tra em /eaders como stdio9/.
4i'erença entre declaração e uso R%a,do vocJ %sa operadores de po,teiros e&iste %ma difere,a e,tre dec"ar-"o e %s-"o. !s d%as coisas abai&o são difere,tes: int *! @
/* declarando um !onteiro que conter8 o endereTo da vari8vel @. */
*! B
/* Wsando o o!erador de indireTOo !ara colocar B dentro do endereTo contido na vari8vel ! (declarada, acima, como !onteiro&). */
! primeira "i,a dec"ara o po,teiro YpY G%sa,do o YkYH e i,icia"ia a varive" YpY com o e,dereo de Y&Y. ! mesma coisa pode ser feita assim: int *! ! @
5 po,to * $%e ,a dec"araão o YkY ,ão * %m operador mas %m artif
-arnteses Pode parecer rid
/* JeclaraTOo de !rot?ti!o. KunTOo aceita um !ar^metro do ti!o int. */ /* Jeclara !onteiro de arraQ !ara B ints. Fem os !ar5nteses terPamos um arraQ de !onteiros. */ 6 (@ = 3) * Q /* Fem os !ar5nteses o 3 seria multi!licado ao Q& */ i (int)c /* onverte a vari8vel c !ara o ti!o int. */ "(L) /* hama a "unTOo " !assando o valor L como !ar^metro. */
@os dois primeiros casos temos dec"araes o,de os parJ,teses são ,ecessrios. @os dois M"timos temos operadores difere,tes Gcasti,+ e camada de f%,ãoH e ,o terceiro caso temos %ma reso"%ão de ambi+%idade.
7scopo dos parBmetros de 'unç6es ma f%,ão em C pode receber parKmetros vi,dos de o%tras f%,es $%e a camam. ma f%,ão sempre * camada por o%tra f%,ão. !ssim temos a f%,ão camadora e a f%,ão camada. @ão 27
mist*rio ,isso. oda f%,ão pode receber parKmetros. ) %m deta"e importa,te: ParKmetros de f%,es são e,carados como se fossem variveis "ocais S pr=pria f%,ão e s= podem ser a"terados de,tro de"a. Vea %m e&emp"o de %ma simp"es f%,ão $%e pree,ce %m b%ffer com eros: /* rimeira versOo da "unTOo. Wsa os !ar^metros como se "ossem inalter8veis. */ void "ill6erosB(char *!tr, si6eEt si6e) si6eEt i "or (i i < si6e i==) !tr[i] -----%<----- corte aqui -----%<----/* Fegunda versOo. Wsa os !ar^metros como vari8veis locais. */ void "ill6erosL(char *!tr, si6eEt si6e) hile (si6e--) !tr[si6e]
fci" provar $%e os parKmetros são "ocais S f%,ão: si6eEt s char ;u""er[BLA] s si6eo"(;u""er) "ill6erosL(;u""er, s) !rint"(2 valor de si6e 7 %d'n, s)
@o fim das co,tas o fra+me,to de roti,a acima imprimir o va"or 1024 mesmo $%e YsieY sea a"terado de de,tro da f%,ão .illzerosH. ?sso * co,die,te com o fato de $%e poder
5 se+%,do parKmetro ,este caso * %ma co,sta,te $%e por defi,ião ,ão pode ser a"terada. Aas de,tro da f%,ão esse va"or * co"ocado ,a varive" "oca" YsieY. 6e essa e&p"icaão ,ão bastar istoricame,te parKmetros são passados pe"a pi"a o% sea %ma c=pia dos parKmetros são empi"ados e %sados pe"a f%,ão. !s variveis e co,sta,tes ori+i,ais passados S f%,ão ,ão são tocados por e"a.
-rot%tipos de 'unç6es com%m ,%m c=di+o mais comp"e&o escrito em C o% C $%e vocJ vea dec"araes de f%,es de ma,eira i,comp"eta;. ?sso serve para avisar o compi"ador o $%e est por vir sem $%e vocJ te,a $%e defi,ir %ma f%,ão com a,tecedJ,cia. Provave"me,te isso ,ão * ,e,%ma ,ovidade para vocJ. 5 deta"e * $%e Ss vees essas dec"araes i,comp"etas podem parecer meio co,f%sas: e@tern void qsort(void *, si6eEt, si6eEt, int (*)(const void *, const void *))
5,de estão os ,omes dos parKmetros ,a dec"araão acimaB 5,de est o corpo da f%,ãoB ) esse $%arto parKmetro ma"%coB @o caso espec
5 $%e essa dec"araão ,ão di * $%a" serão os ,omes das variveis "ocais associadas aos parKmetrosE issoE @ão ,e,%ma i,formaão adicio,a" para a f%,ão ,essa dec"araão. 5s prot=tipos s= e&istem para dier ao compi"ad or: )% ai,da ,ão sei $%em * esse cara mas e"e se parece com isso aiE;. For,ecer o ,ome dos parKmetros * opcio,a". Prot=tipos em mi,a opi,ião são co,str%es e&ce"e,tes para or+a,iar c=di+o. Cost%mo %s-"os para co"ocar mi,as f%,es em %ma ordem "=+ica em me%s c=di+os-fo,te. Por e&emp"o: #include #include /* Uesse meu c?digo eu uso uma "unTOo calc(), mas ela ser8 de"inida somente J42NF da "unTOo main(). */ int calc(int) int main(int argc, char *argv[]) int valor i" (argc & L) "!rint"(stderr, Wso test 'n) return B valor atoi(argv[B]) /* Z "unTOo main() !recisa sa;er como 7 a "unTOo calc() !ara !oder us8-la& Jai o !rot?ti!o, l8 em cima. */ !rint"(2 tri!lo do valor %d 7 %d'n, valor, calc(valor)) return /* Kinalmente, calc() 7 de"inida aqui. */ int calc(int valor) return (valor = valor)
c"aro $%e ,ão fa ,e,%m ma" co"ocar o ,ome dos parKmetros ,o prot=tipo. !"is * at* %ma boa ideia $%e o compi"ador far testes de si,ta&e e,tre a dec"araão Gdo prot=tipoH e a defi,ião da f%,ão. Aas ao mesmo tempo ao ,ão co"ocar ,omes de parKmetros vocJ se "ibera de ter $%e certificar-se $%e todos os ar$%ivos $%e co,te,am as defi,ies de s%as f%,es te,am $%e ter em a"+%m o%tro "%+ar prot=tipos com parKmetros ,omeados e&atame,te como ,a defi,ião. )% prefiro ,ão ,omear parKmetros ,os prot=tipos. /i+amos $%e essa * %ma prtica tradicio,a" e,tre os pro+ramadores $%e "idam com a "i,+%a+em C...
-roblemas com algumas estruturas com mscaras de bits ! especificaão da "i,+%a+em C ,os di $%e o %so de mscaras de bits * a"+o depe,de,te de imp"eme,taão;. !o faer a"+o assim: struct mQstrucEs unsigned @S unsigned QL_
VocJ pode esperar $%e o primeiro bit do membro Y#Y sea co"ocado imediatame,te depois do M"timo bit do membro Y&Y. )m a"+%mas ar$%itet%ras isso pode ser verdade mas ,ão $%a,do fa"amos das ar$%itet%ras ?,te" e do compi"ador CC Ge a"+%,s o%trosH. ! estr%t%ra acima prod%ir dois /5N/s o,de os ( bits i,feriores estarão ,o primeiro /5N/ atrib%
29
struct mQstrucEs unsigned @S unsigned QL_ EEattri;uteEE((!aced))
!+ora a estr%t%ra ter e&atame,te > b#tes. 5s 33 bits estarão compactados o mais pr=&imos poss ls;) Q QQQQQQQQ QQQQQQQQ QQQQQQQQ QQ@@@@@@ b b ;it 3B ;it G5 o !rimeiro ;Qte e isola @. mov6@ ea@,;Qte !tr [s] and ea@,@3K mov [a],ea@ coloca em a. mov6@ ea@,;Qte !tr [s] mov6@ ec@,;Qte !tr [s=B] coloca os L !rimeiros ;its de Q no lugar certo. shr al,S mov6@ ea@,al coloca os R ;its do !r?@imo ;Qte de Q no lugar certo. sal rc@,L or rc@,ra@ coloca os !r?rimos BS ;its de Q no lugar certo. mov6@ ea@,;Qte !tr [s=L] sal ra@,B or ra@,rc@ mov6@ ec@,;Qte !tr [s=3] sal rc@,BR or rc@,ra@ e "inalmente coloca o ltimo ;it de Q no lugar certo. mov6@ ea@,;Qte !tr [s=A] and ea@,B sal ra@,LS or ra@,rc@ arma6ena o valor de Q. mov [;],ea@
R%e c=di+o orr
30
G5 SA ;its da mem?ria... mov6@ ra@,;Qte !tr [s] mov rc@,ra@ Cuarda valor lido em HI. Nsola os S ;its in"eriores. and ea@,@3" mov [a],ea@ ega os L_ ;its restantes. shr rc@,S and ec@,@_"""""" mov [;],ec@
Aas o po,to * $%e ao %sar mapas de bits o se% c=di+o vai ficar e,orme e * c"aro %m ta,to "e,to. ?sso * especia"me,te v"ido com estr%t%ras compactadas. 5bserve a+ora o c=di+o e$%iva"e,te com a estr%t%ra sem o atrib%to &acked G+erado pe"o compi"adorH: mov ea@,[s] and ea@,@3" mov [a],ea@ mov ea@,[s=A] and ea@,@_"""""" mov [;],ea@
bem parecido com mi,a imp"eme,taão ,ão *B 5 motivo de %sar )!U ao i,v*s de N!U * $%e a estr%t%ra ,ão tem (4 bits de tama,o... Aas ,a verdade $%e dados tamb*m são a"i,ados ,ão prob"emas em "er %m R5N/ o,de temos ape,as 33 bits G%m bit a mais $%e %m /5N/H. Por isso mi,a roti,a pode ser %m po%$%i,o mais rpida $%e a +erada pe"o compi"ador... Aesmo assim sem a compactaão da estrt%ra o c=di+o do compi"ador fica =bviame,te mais simp"es e rpido em re"aão ao c=di+o a,terior. 6i+a a dica: )vite campos de bits sempre $%e p%der.
8inalmente: -onteiros ma das coisas $%e ca%sa certo desespero Ss pessoas $%e tiveram o primeiro co,tato com "i,+%a+e,s como C e C são as criat%ras do i,fer,o; co,ecidas como po,teiros. )spero poder i,f%,dir %m po%co de a%toco,fia,a e mostrar $%e po,teiros ,ão mordem são $%ase %,s a,i,os e $%e são %m dos rec%rsos mais Mteis $%e o%tras "i,+%a+e,s faem $%estão de esco,der. 6empre $%e vocJ "er a pa"avra po,teiro; pode sem medo s%bstit%<-"a por e,dereo de mem=ria; o% simp"esme,te e,dereo;. ) saiba $%e todo s
R%a,do a varive" estamos pedi,doo ao compi"ador crieespao %m espao mem=riadec"aramos com o tama,o de %m+"oba" int G4 Y&Y b#tesH e ape"ide; e,dereo i,icia"$%e desse de Y&Y.,a ?sso $%er dier $%e Y&Y s= e&iste ,o se% c=di+o fo,te e de,tro do compi"ador. 5 ,ome rea" dessa varive" * o se% e,dereo. !ssim $%a,do atrib%
@este e&emp"o o e,dereo 0&(01024 * %m e&emp"o de o,de o compi"ador pode decidir co"ocar a 31
varive" ,a mem=ria. Aesmo em assemb"# $%e * %ma "i,+%a+em de ,
@ 7 um sPm;olo que equivale a um endereTo de mem?ria da sessOo de dados onde reservamos o es!aTo !ara um dord.
section .te@t 9 mov dord [@],B oloca o valor de 3L ;its B no endereTo a!elidado !or @. 9
4eclarando e usando ponteiros )m C o co,ceito de po,teiro; * %m po%co mais especia"iado. rata-se de %ma varive" $%e co,t*m %m e,dereo ao i,v*s de %m va"or. ma varive" do tipo po,teiro fa referJ,cia a %m dado co,tido ,a mem=ria de ma,eira i,direta isto * essa varive" especia"; Go po,teiroH co,t*m %m e,dereo $%e apo,ta; para %m dado do tipo dec"arado. R%a,do faemos a"+o assim: int * !
/iemos $%e a varive" YpY ser %sada para co,ter %m e,dereo para a"+%ma re+ião da mem=ria Go% sea * %m po,teiroEH $%e poss%i %m dado do tama,o de %m int. Aas ate,ão: ! dec"araão acima ,ão i,icia"ia a varive"E m e&emp"o me"or est ,o +rfico abai&o:
Figura 3: Ponteiro que a&onta &ara uma vari?vel
!$%i o compi"ador esco"e% o e,dereo 0&(01432 para a varive" Y&Y e o e,dereo 0&(01024 para a varive" YpY. 6= $%e essa M"tima * %m po,teiro $%e foi i,icia"iada com o e,dereo de Y&Y Gvia operador H. @ote... a varive" * p; e ,ão kp;E Por $%estão de esti"o prefiro declarar po,teiros %sa,do o YkY pr=&imo ao ,ome da varive". ?sso serve ape,as para embe"ear; o c=di+o. 6e vocJ preferir separar a dec"araão do eito $%e fi acima por motivos de c"area fi$%e S vo,tade... Co,forme vimos em re"aão aos mode"os ?L32P(4 e ?32LP(4 ,a ar$%itet%ra &'(-(4 todo po,teiro importa o tipo associado a e"e tem e&atame,te ' b#tes de tama,o Go tama,o de %m R5N/,ão o% sea (4 bitsH. )is %m e&emp"o simp"es de dec"araão e %so de %m po,teiro:
32
#include int @ B int main(int argc, char *argv[]) /* declaraTOo de !onteiro ! de"inido como tendo o endereTo de @. */ int *! @ !rint"(%lu'n%d'n, !, *!) return
5 c=di+o acima imprimir %m va"or a"eat=rio; T %m e,dereo esco"ido pe"o compi"ador T e o va"or 10. Aas o $%e si+,ifica esse YkpY %sado como parKmetro ,a camada de &rint.B /ifere,te da dec"araão da varive" esse o%tro YkY * %m operador de derre#er=ncia ou indireçãoH6. 5 co,ceito * $%e %ma varive" do tipo po,teiro co,t*m %ma referJ,cia Go e,dereoH %sada para obter o dado apo,tado e ao %sar o operador YkY vocJ di ao compi"ador: pe+%e o dado c%o e,dereo est ,o po,teiro;. Nepare $%e e&istem dois mome,tos em $%e "idamos com po,teiros: 1. ! dec"araãoXdefi,ião: 5,de reservamos o espao para a varive"\ 2. 5 %so: R%a,do %samos o operador de i,direão para obter o dado apo,tado. ! dec"araão de %m po,teiro * feita como $%a"$%er o%tra varive" e&ceto $%e o tipo * se+%ido de %m YkY Go% o ,ome da varive" * precedido pe"o asterisco depe,de,do de como vocJ e,caraH. ) tamb*m como para $%a"$%er varive" t%do o $%e o compi"ador far * a"ocar espao s%ficie,te para caber %m e,dereo. 5 tipo associado ao po,teiro * %sado em operaes aritim*ticas e,vo"ve ,do o po,teiro. Po,teiros unsigned são va"ores i,teiros e as mesmas re+ras da aritim*tica v"idas para somar são v"idas para e"es: Podemos i,creme,tar o% decreme,tar %m po,teiro\ podemos doislongs po,teiros Gembora isso ,ão sea " m%ito Mti"EH\ podemos somar %m va"or i,teiro a %m po,teiro\ podemos s%btrair dois po,teiros Gisso * Mti"EH o% %ma co,sta,te...
@o e&emp"o abai&o ass%mo $%e o po,teiro YpY foi i,icia"iado em a"+%m o%tro "%+ar. )sse fra+me,to serve para respo,der a per+%,ta: 5 $%e aco,tece $%a,do i,creme,tamos %m po,teiro dec"arado como se,do do tipo intB /* Jeclarei como e@tern !ara di6er que esse !onteiro "oi iniciali6ado em algum outro lugar... */ e@tern int *! 9 !==
Vamos s%por $%e o e,dereo co,tido em YpY sea 0&(01040. /epois de i,creme,t-"o não obteremos 0&(01041 mas sim 0&(01044E ?sso aco,tece por ca%sa do tipo associado ao po,teiro. m int poss%i 4 b#tes de tama,o G32 bitsH e,tão o po,teiro * i,creme,tado de 4 em 4. 6e tiv*ssesmos po,teiros de tipos mais comp"e&os como ,o e&emp"o: /* 4ssa estrutura tem L ;Qtes de tamanho. */ struct verticeEs "loat @, Q, 6, "loat n@, nQ, n6 "loat r, g, ;, a "loat s, q
24 Camarei de ope rador de indireJo da$%i pra fre,te pois dereferJ,cia; parece ser %ma pa"avra i,e&iste,te ,a "<,+%a port%+%esa.
33
struct verticeEs *vrt@!, *! 9 ! vrt@! = B
!ss%mi,do $%e Yvrt&pY te,a sido i,icia"iado em a"+%m o%tro "%+ar o po,teiro YpY co,ter o e,dereo co,tido em Yvrt&pY mais >20 b#tes $%e o tipo Ystr%ct vertice]sY tem >2 b#tes de tama,o. ),tão recapit%"a,do: char *! char *! s ! s *! a !==
/* isso 7 uma declaraTOo de um !onteiro ! nOo iniciali6ado. */ /* Nsso 7 a declaraTOo de um !onteiro ! iniciali6ado com o endereTo de s. */ /* Nsso coloca o endereTo de s no !onteiro !. */ /* Nsso coloca a constante a no endereTo contido no !onteiro !. /* /* Nsso incrementa o endereTo contido em !. */
-roblemas com ponteiros para estruturas I %m prob"ema com o %so do oper ador de i,direão e a ,otaão de estr%t %ras Ge %,ioesH. 5 operador de membro de dados Y.Y tem maior precedJ,cia do $%e o operador de i,direão YkY. Por ca%sa disso o c=di+o abai&o ,ão fa o $%e vocJ espera: struct F int @ /* Z!enas um e@em!lo de iniciali6aTOo de !onteiro !ara estrutura. */ struct F *! s 9 /* Nsso nOo "a6 o que voc5 !ensa que "a6& */ *!.@ 3
!cabaremos com a"+%m erro de compi"aão. de se s%por $%e kp.&; si+,ifi$%e a derreferJ,cia do po,teiro YpY se+%ida da obte,ão do membro de dados Y&Y mas como Y.Y tem precedJ,cia maior o compi"ador e,te,de $%e Yp.&Y * o po,teiro. 5 $%e * fa"soE )&istem d%as ma,eiras de reso"ver isso: Podemos %sar parJ,teses para acabar com a ambi+%idade: (*!).@ 3
/* 4ssa 7 a sinta@e correta& */
5% desde o padrão !@6? da "i,+%a+em C e&iste %m ata"o. 5 operador Y-Y * %sado para obter %m membro de %ma estr%t%ra atrav*s de %m po,teiro. 5% sea o $%e est S es$%erda de Y-Y deve ser sempre %m po,teiro para %ma estr%t%ra e S direita %m membro de dados. ! mesma "i,a acima fica assim: !->@ 3
! coisa f%,cio,a do mesmo eito para membros de %,ies.
-onteiros e strings VocJ deve ter topado com %ma stri,+ em C. 6ão a$%e"as co,sta,tes cercadas por aspas d%p"as GlH. 6i,to dier $%e a co,tradião ,a pr=&ima se,te,a vai dar %m ,=; ,o se% c*rebro: ma stri,+ ,ão * %ma stri,+E %m arra# de c/ars termi,ado com o b#te 0 GeroHE 5 $%e ocorre * $%e as f%,es da bib"ioteca padrão da "i,+%a+em C i,terpretam arra#s de c/ars termi,ados com ero como se fossem stri,+s. ?sso tor,a a "i,+%a+em f"e&
operadores especia"iados para "idar com e"as. 5% vocJ as trata como arra#s diretame,te o% "ida com e"as atrav*s de f%,es da bib"ioteca padrão como strc&y strcat strdu& etc.
4i'erenças entre declarar ponteiros e arras contendo !strings# )&istem a"+%,s eitos de dec"ararmos e i,icia"iarmos stri,+s;: char *strB $ello char strL[] $ello char str3[] $, e, l, l, o, '
6empre $%e topar com %ma co,sta,te do tipo stri,+ cercada por aspas d%p"as o compi"ador trad%ir isso para %m arra# co,te,do os caracteres i,divid%ais e %m Y0Y GeroH adicio,a". !ssim a primeira dec"araão * a de %m po,teiro $%e co,ter o e,dereo do arra# $%e co,t*m ( b#tes GYIY YeY Y"Y Y"Y YoY e Y0YH. !s dec"araes de str2 e str3 são e$%iva"e,tes e,tre si. )"as diem para o compi"ador $%e os ( b#tes devem ser a"ocados ,a re+ião de dados da mem=ria e i,icia"iados com YIY YeY Y"Y Y"Y YoY e Y0Y. /epois disso os scontando com o zero .inal), mas o array .oi e4&licitamente declarado como tendo N c/ars >bytes): char strA[] $ello
com&ilador colocar? os N &rimeiros bytes da constante no array, descatar? o se4to byte e, talvez, emita um aviso sobre isso9
)&iste %ma difere,a e,tre dec"arar %m po,teiro $%e apo,ta para %ma co,sta,te e %m arra# i,icia"iado com %ma. ) * s%ti": @o primeiro caso a co,sta,te ,ão pode ser a"terada por$%e afi,a" de co,tasreservada * %ma constante casoem dos arra#s aserco,sta,te * %sada para i,icia"i ar o co,teMdo da mem=ria para e"esE e@o pode runtime modificada. Para i"%strar eis %m pro+rama $%e fa"ar miserave"me,te e&p"odi,do o fami+erado 6e+me,ta,tio, Fa%"t; em ,ossas caras provave"me,te por$%e co,sta,tes $%a,do são armae,adas ,a mem=ria ficam em %ma sessão read5only do c=di+o: /* strto.c */ #include #include /* Nsto 7 um !onteiro !ara uma constante& */ char *s $ello, orld& int main(int argc, char *argv[]) char *! ! strto(s, , ) hile (! & UWGG) !rint"(%s'n, !)
/* 2correr8 um segmentation "ault aqui& */
! strto(UWGG, , ) return -----%<----- corte aqui -----<-----
3>
gcc -g -o s#r#ok s#rrok.c gd$ ./s#r#ok (gd;) r Ftarting !rogram strto rogram received signal FNCF4C, Fegmentation "ault. strto () at ../sQsde!s/@RSESA/strto.FBf Bf ../sQsde!s/@RSESA/strto.F Uo such "ile or directorQ. (gd;) $# # strto () at ../sQsde!s/@RSESA/strto.FBf #B @AS" in main (argcB, argv@_"""""""eBcR) at strto.cBB
5 prob"ema com esse pro+rama * $%e strtok espera poder escrever ,o arra# apo,tado por YsY e ,ão co,se+%e. 6e vocJ m%dar a dec"araão de YsY para: char s[] $ello, orld&
%do f%,cio,ar perfeitame,te.
ais ponteiros e arras !ssim como com po,teiros e&iste %ma difere,a e,tre dec"araão e %so. @o %so de arra#s o operador de i,de&aão YjY T %sado para obter %m item de %m arra# T * ,a verdade %m ata"o para aritm*tica de po,teiros. )sse operador toma %m po,teiro como base e %m <,dice $%e * somado a esse po,teiro para obter %m e,dereo. /e posse desse e,dereo ca"c%"ado o dado * acessado. 5s dois %sos abai&o são e$%iva"e,tes: int @[B] 9 Q @[3] /* @ 7 um !onteiro e 3 7 um deslocamento. */ Q *(@ = 3) /* a mesma coisa&&& */
5 ,ome da varive" do arra# Y&Y * %m po,teiro para o primeiro item do arra#. Podemos camar esse s
/* ! a!onta !ara o inPcio do arraQ. */ /* a mesma coisa&&& */
5% sea se vocJ ,ão se se,te co,fortve" em %sar o ,ome de %m arra# como se,do o po,teiro para o item de <,dice 0 GeroH e,tão pode sempre pe+ar o e,dereo do item ero e&p"icitame,te. a mesma coisa. 5 fato de $%e o operador YjY sea %ma ,otaão de po,teiros esco,dida permite %m %so es$%isito; da ,otaão de arra#s +raas S propriedade com%tativa da adião... $%e Y&3Y * a mesma coisa $%e Y3&Y os dois %sos abai&o são e&atame,te idJ,ticos: Q @[3] Q 3[@]
/* @ 7 a ;ase e 3 7 o deslocamento. / /* 3, agora, 7 a ;ase e @ 7 o deslocamento. */
po%co provve" $%e vocJ obte,a a"+%m erro de compi"aão. a"ve %m aviso... ta"ve...
4eclarando e inicializando arras. estruturas e unions @este t=pico $%ero dei&ar re+istrado %m comportame,to Mti" ,os compi"adores C $%e est 3(
especificado e porta,to * +ara,tido $%e sempre f%,cio,e. !o dec"arar e defi,ir ape,as %m item de %m arra# estr%t%ra o% %,io, o compi"ador a%tomaticame,te pree,cer o resta,te dos ite,s G,ão i,icia"iados ,o c=di+o fo,teH com eros: /* test.c */ #include struct mQstructEs int @ int Q int 6 struct mQstructEs s B /* de"ine a!enas @. */ int a[3] L /* de"ine a!enas a[]. */ int main(int argc, char *argv[]) !rint"(s %d, %d, %d'n a [%d, %d, %d]'n, s.@, s.Q, s.6, a[], a[B], a[L]) return -----%<---- corte aqui ---%<---- gcc -o #es# #es#.c ./#es# s B, , a [L, , ]
Vi% s=B /efi,imos ape,as o primeiro item da estr%t%ra dec"arada como YsY e o primeiro item do arra# YaY mas o compi"ador a%tomaticame,te ero% os ite,s resta,tes. !i,da ,o caso do CC e&iste %ma e&te,são para i,icia"iaes de estr%t%ras e %,io,s $%e pode ser Mti". Podemos e&p"icitar $%a" membro ser i,icia"iado. 6%bstit%a a i,icia"iaão da estr%t%ra YsY acima por: struct mQstructEs s .6 B
) vocJ obter s 0 0 1 n;. ! mesma coisa pode ser feita com %m arra# basta e&p"icitar o <,dice do item a ser i,icia"iado: int a[3] [B] L /* Nniciali6a o item [B] com L e o resto com 6eros. ndices de arraQs sem!re comeTam com []. */
)sses rec%rsos são e&te,ses $%e estão dispo,
5 casti,+ * ,ecessrio por $%e o compi"ador pode ficar co,f%so se e"e ,ão for i,formado. 5%tra co,sideraão s%ti" ao %sar esse macete; * $%e criamos %m po,teiro para %m arra# co,sta,te. ?sso * difere,te de dec"arar: dou;le ![] B, L, 3
?sto * %sar "iterais compostos podem ca%sar o mesmo prob"ema $%e temos ao dec"arar stri,+s co,ta,tes atrib%
5s "iterais compostos podem ser %sados para passar arra#s "iterais para f%,es: e@tern int "(int *@) 9 @ "((int []) B, L, 3)
/e $%a"$%er ma,eira aco essa e&te,são m%ito es$%isita...
-onteiros. 'unç6es e a pil"a Po,teiros são m%ito Mteis $%a,do trata-se de passar parKmetros para f%,es por referJ,cia; ao i,v*s de por va"or;. )specia"me,te se estamos fa"a,do de estr%t%ras comp"e&as. 6%po,a $%e te,amos %ma estr%t%ra com vrios ite,s como: struct vecticeEs "loat @, Q, 6, "loat n@, nQ, n6 "loat r, g, ;, a "loat s, q
)ssa estr%t%ra co,t*m 13 .loats e tem o tama,o tota" de >2 b#tes Gcad a .loat tem 4 b#tes de tama,oH. !+ora repare ,as dec"araes de f%,es abai&o: e@tern int hecUormal(struct verticeEs v) e@tern int hecUormalL(struct verticeEs *v!)
6e camarmos a primeira f%,ão todos os >2 b#tes da estr%t%ra serão empi"ados a,tes da camada. /e fato >( b#tes da pi"a serão %sados $%e ,a ar$%itet%ra &'(-(4 todos os ite,s ,a pi"a devem ser a"i,ados por R5N/s Gde ' em ' b#tesH. 6e %sarmos a se+%,da f%,ão t%do o $%e ser passado para a f%,ão "/eckormalH serão os ' b#tes $%e correspo,dem ao tama,o de %m po,teiro. )sses ' b#tes podem ,em mesmo serem empi"ados de acordo com a convenJo de c/amada $%e mostrarei ,o pr=&imo cap( b#tes e tivermos >0 camadas ac%m%"adas o %so da pi"a ser de apro&imadame,te 32 ^iQ G32000 b#tes e&atame,te a"*m dos >( b#tes de parKmetros empi"ados temos $%e co,tar tamb*m com o e,dereo de retor,o das f%,es camadorasEH. @ão parece +ra,de coisa ,ão *B !co,tece $%e 32 ^iQ * o tama,o de todo o cace L1 para cada ,Mc"eo em certas ar$%itet%ras. ) ,%m ambie,te m%"titreaded podemos ter pi"as me,ores $%e isso. R%ero dier $%e com %so i,te,so da pi"a teremos prob"emas em o%tras reas... ! pi"a * %sada para co,ter o%tras coisas a"*m de parKmetros de f%,es e e,dereos de retor,o. @ão estamos co,ta,do a$%i com variveis "ocais $%e ,ão p%deram ser ma,tidas em re+istradores bem como variveis temporrias e va"ores de re+istradores $%e precisam ser preservados e,tre camadas... 5% sea se %sarmos passa+em de parKmetros por va"or de estr%t%ras comp"e&as ,%m pro+rama +ra,de corremos o risco de e&a%rir a pi"a 2> toma,do %m erro de stacD overf"o8; ,a cara e abortar o pro+rama ,o meio de %m processame,to cr Aas ,ão * ,ecessrio preoc%par-se demais com a pi"a... 5s sistemas opera cio,ais moder,os a"ocam basta,te espao para e"as ,o users&ace. Cerca de 1 AiQ * a"ocado para e"a... ) a pi"a ai,da pode crescer. 6= $%e isso va"e para a tread pri,cipa" do processo. !s tread sec%,drias ,orma"me,te são i,icia"iadas com %ma pi"a de tama,o fi&o e pe$%e,o.
3'
7ntendendo algumas declaraç6es !malucas# usando ponteiros 6e ,ão bastasse todas as e&p"icaes acima $%e af%+e,tam os ,ovatos temos o verdadeiro terror ,a f"e&ibi"idade e ,a si,ta&e %sada por C e C com a dec"araão de po,teiros. !fi,a" vocJ pode $%erer %m po,teiro simp"es para %m tipo primitivo o% pode $%erer a"+o como %m po,teiro para %m arra# de po,teiros de f%,es;. Comecemos por a"+o simp"es. /ec"arar %m arra# de po,teiros: int *iZrraQ[3]
/* arraQ de 3 !onteiros do ti!o int. */
Aas e se $%is*ssemos dec"arar %m po,teiro para %m arra# de 3 ints;B @oto% a difere,aB @o caso acima temos 3 po,teiros ,%m arra# e a+ora $%ero %m po,teiro para %m arra# de 3 ite,s. Para obter isso preciso e,+a,ar; o compi"ador %sa,do parJ,teses: int (*iZrraQ)[3]
/* iZrraQ 7 um !onteiro !ara um arraQ de 3 ints. */
raas aos parJ,t eses diem os ao compi"ador $%e i1rray * o po,teiro para %m arra#. @o caso a,terior o Yi,t kY * o tipo do arra# ,o se+%,do Yi,tY. )is o%tro e&emp"o ,o caso de dec"araão de f%,es: int *"(void) int (*")(void)
/* "unTOo que retorna !onteiro do ti!o int. */ /* onteiro (nOo iniciali6ado) !ara uma "unTOo que retorna int. */
5%tro tipo de dec"araão $%e vocJ pode precisar * a de po,teiro para po,teiro;: char **!!
/* !! 7 um !onteiro que a!onta !ara um !onteiro que a!onta !ara um char. */
VocJ pode ver a %ti"idade disso $%a,do temos %m arra# de stri,+s: /* astr 7 um arraQ de !onteiros. */ char *astr[] hello, orld, UWGG char **!! /* a!onta !ara o !rimeiro item do arraQ acima. */ !! !! astr /* ercorre o arraQ astr usando o !onteiro !!. */ hile (*!! & UWGG) !rint"(%s'n, *!!) !rint"(2 !rimeiro char da string 7 %c'n, **!!) !!==
!$%i fao YppY apo,tar para o primeiro item do arra# YastrY composto de 3 po,teiros para c/ar. YkppY ,os d e,tão o e,dereo i,icia" de cada stri,+ i,divid%a"me,te. 6e %sssemos YkkppY obter
Figura R: Estrutura usando &onteiro &ara &onteiros9
! %ti"idade desse tipo de co,str%ão vem do fato $%e se %m po,teiro pode ser %sado para apo,tar para %m item de %m arra# e,tão se %sarmos %m arra# de po,teiros podemos ter %ma estr%t%ra bidime,sio,a" o% %m arra# de arra#s; 2(. 2( ?sso * bem difere,te de %m arra# bidime,sio,a"; ,o co,te&o da "i,+%a+em C. 5 $%e camo de arr a# de arra#s; * %m po,teiro para %m arra# de po,teiros;. I %ma disti,ão s%ti".
39
5 $%e acabo de descrever * o $%e ocorre com o se+%,do parKmetro da f%,ão main. R%a,do vocJ e&ec%ta se% pro+rama a "i,a de coma,do * divida em stri,+s Gcada stri,+ * %m arra# de carsH e os po,teiros para essas stri,+s são co"ocados ,%m arra#. ! f%,ão main recebe o po,teiro para esse arra# de po,teiros. por isso $%e dec"arar Yar+vY como Ycar kar+vjY o% Ycar kkar+vY * esse,cia"me,te a mesma coisa: int main(int argc, char *argv[]) /* 4sta 7 a "orma cannica da declaraTOo de main */ int main(int argc, char **argv) /* 4ssa 7 a mesma coisa que a declaraTOo acima. */
Com re"aão a o%tras dec"araes ma"%cas; podemos ter a"+%mas bem comp"icadas: int * (*"[B])(int) /* arraQ de B !onteiros !ara "unT\es que retornam !onteiros !ara int. */
Pode ser desafia,te criararra#s dec"araes para por e&emp"o %m de po,teiros $%e retor,am po,teiros para de f%,es;... Necome,do $%e arra# vocJ evite esses tiposdedef%,es ma"%$%ices.
;tilidade de ponteiros para 'unç6es ma dMvida $%e %m "eitor me aprese,to% foi sobre os po,teiros para f%,es. !co $%e fico% c"aro $%e os compi"adores %sam ape"idos para e,dereos de coisas $%e estão "oca"iadas ,a mem=ria. F%,es ,ão são difere,tes. )m assemb"# %ma camada para %m procedime,to via i,str%ão C!LL %sa como parKmetro o e,dereo de e,trada do procedime,to. ) como po,teiro; * ape,as %ma forma mais reb%scada de fa"armos de e,dereo; podemos dier $%e C!LL %sa %m po,teiro. )m C podemos dec"arar %m po,teiro para %ma f%,ão e cam-"a atrav*s deste po,teiro: /* "unc!tr 7 declarada como um !onteiro !ara uma "unTOo. */ int (*"unc!tr)(int) /* 4sta 7, de "ato, a de"iniTOo de uma "unTOo. */ int "(int @) return @ = @ int main(int argc, char *argv[]) /* Ztri;ui ao !onteiro "unt!tr o endereTo do !onto de entrada da "unTOo ". */ "unc!tr " /* hama a "unTOo " indiretamente, usando o !onteiro "unc!tr. */ !rint"(2 do;ro de %d 7 %d'n, L, "unc!tr(L)) return
5 pr=prio s
void (*6ero"illE!tr)(void *, si6eEt)
40
/* Hotina de iniciali6aTOo chamada no inPcio do seu c?digo. */ void init(void) i" (sseE!resent) 6ero"illE!tr 6ero"illEsse else i" (canEuseEasm) 6ero"illE!tr 6ero"illEasm else 6ero"illE!tr 6ero"illEc int main(int argc, char *argv[]) 9 /* init vai decidir qual das 3 "unT\es usar. */ init() 9 /* hama 6ero"illE@@@ ia !onteiro& */ 6ero"illE!tr(;u""er, si6eo"(;u""er)) 9 return
A biblioteca padrão: libc oda ve $%e vocJ compi"a e "i,Da; %m c=di+o em C "eva %,to s
Figura +: InicializaJo de um &rograma em "
Proc%re i,terpretar esse +rfico de camadas como %ma rvore bi,ria: Ostart cama OOlibOstartOmain $%e cama OOlibcOcsuOinit e depois main e depois ,a ordem Oinit OgmonOstart .rameOdummy OOdoOglobalOctorsOau4 e cada %m dos co,str%tores re+istrados ,o arra# constructorsS99nT. /epois dessas i,icia"iaes todas a f%,ão main * fi,a"me,te camada. R%a,do e"a sai e4it * e&ec%tado e e"e e&ec%ta todos as f%,es re+istradas com ate4it depois as re+istradas ,o arra# .iniarray e os destr%tores... 6= para i"%strar eis o c=di+o fo,te comp"eto de %m /elloorld tota"me,te escrito em assemb"# $%e pode ser e&ec%tado e ,ão %sa a libc27: 27 5 padrão de camada para s#sca""s ,o modo 32 bit s * %m po%co difere, te do modo (4 bits. )m ambo s os modos poder
41
helloorld.asm ;its SA section .data msg d; $ello, orld&, B len equ - msg section .te@t glo;al Estart Estart mov ra@,B mov rdi,B mov rsi,msg mov rd@,len sQscall
sQsErite sQscall FDJ2WD
mov ea@,S sQsEe@it sQscall @or rdi,rdi c?digo de erro de saPda. sQscall -----%<----- corte aqui -----%<---- %asm -& el&'( hello)orld.asm -o hello)orld.o ld -s hello)orld.o -o hello)orld ./hello)orld $ello, orld& ls -l hello)orld -r@r@r-@ B user user BL Je6 Lf LBA3 helloorld
5 s
@os pro+ramas em C a "ibc * o motivo pe"o $%a" se% c=di+o ,ão ter me,os $%e ' ^iQ de tama,o. Nepare $%e a versão em p%ro assemb"# tem ape,as >12 b#tes. ! bib"ioteca padrão fa m%ito traba"o de i,icia"iaão e fi,a"iaão. /e %ma forma +era" a f%,ão OlibcOcsuOinit * respo,sve" pe"a e&ec%ão de construtores... )"es ,ão são coisas restritas ao C. raas ao es$%ema de atrib%tos do CC podemos criar f%,es $%e serão e&ec%tadas antes de main como se fossem co,str%tores de obetos ,o C. /a mesma forma e&istem f%,es de fi,a"iaão o% destr%tores; $%e são camados $%a,do o c=di+o em C * e,cerrado: /* test.c */ #include void EEattri;uteEE((constructor)) ctor(void) !rint"(KunTOo chamada antes de main().'n) void EEattri;uteEE((destructor)) dtor(void) !rint"(KunTOo chamada de!ois de main().'n) int main(int argc, char *argv[]) !rint"($ello&'n) return -----%<----- corte aqui -----%<---- gcc -o #es# #es#.c ./#es# KunTOo chamada antes de main(). $ello& KunTOo chamada de!ois de main().
42
5 c=di+o de i,icia"iaão * a porão da libc $%e * "i,Dada de forma esttica. 5 resta,te das f%,es como &rint. por e&emp"o são "i,Dadas; de forma di,Kmica. 5 CC ass%me a opão -"c; por defa%"t2'.
A libc 'az um monte de coisas !por baixo dos panos# )is %ma comparaão com o c=di+o /elloorld9asm mostrado a,teriorme,te e o c"ssico /ello9c Para compar-"os vo% %sar a ferrame,ta strace $%e mostra ape,as camadas syscalls. 6e vocJ $%iser ver i,c"%sive camadas S bib"iotecas %se o %ti"itrio ltrace com a opão Y-6Y: ls -l total LA -r@r@r-@ -r-r-r--r@r@r-@ -r-r-r--
BB B B
user user user user
user RB Kev BA BA BA3 BA3 hello.c hello user S3 Kev user BL Kev BA BAR helloorld user 33B Kev BA BA_ helloorld.asm
ca# hello.c /* 4is o nosso sim!les hello.c */ #include void main(void) !uts($ello, orld&) s#race ./hello)orld e@ecve(./helloorld, [./helloorld], [/* Sf vars */]) rite(B, $ello, orld&'n, BA) BA Ee@it() === e@ited ith === s#race ./hello e@ecve(./hello, [./hello], [/* Sf vars */]) ;r() @BLc access(/etc/ld.so.nohca!, KE2j) -B 4U24UD (Uo such "ile or directorQ) mma!(UWGG, RBfL, H2DEH4ZJbH2DEkHND4, +ZEHNZD4b+ZEZU2U+2WF, -B, ) @_"R";cBcd access(/etc/ld.so.!reload, HE2j) -B 4U24UD (Uo such "ile or directorQ) o!en(/etc/ld.so.cache, 2EHJ2UGb2EG24I4) 3 "stat(3, stEmodeFENKH4CbSAA, stEsi6eBB3LB, ...) mma!(UWGG, BB3LB, H2DEH4ZJ, +ZEHNZD4, 3, ) @_"R";cB;B close(3) access(/etc/ld.so.nohca!, KE2j) -B 4U24UD (Uo such "ile or directorQ) o!en(/li;/@RSESA-linu@-gnu/li;c.so.S, 2EHJ2UGb2EG24I4) 3 read(3, 'B__4GK'L'B'B''''''''''3'>''B''''3L'3_'L'''''..., R3L) R3L "stat(3, stEmodeFENKH4Cb_, stEsi6eBRALA, ...) mma!(UWGG, 3f33AA, H2DEH4ZJbH2DE4I4, +ZEHNZD4b+ZEJ4UkHND4, 3, ) @_"R";;;e_ m!rotect(@_"R";;daL, Lf_BL, H2DEU2U4) mma!(@_"R";;"aL, LA_S, H2DEH4ZJbH2DEkHND4, +ZEHNZD4b+ZEKNI4Jb+ZEJ4UkHND4, 3, @B;;) @_"R";;"aL mma!(@_"R";;"aR, B_RR, H2DEH4ZJbH2DEkHND4, +ZEHNZD4b+ZEKNI4Jb+ZEZU2U+2WF, -B, ) @_"R";;"aR close(3) mma!(UWGG, AfS, H2DEH4ZJbH2DEkHND4, +ZEHNZD4b+ZEZU2U+2WF, -B, ) @_"R";cB; mma!(UWGG, RBfL, H2DEH4ZJbH2DEkHND4, +ZEHNZD4b+ZEZU2U+2WF, -B, ) @_"R";cBae archE!rctl(ZH$EF4DEKF, @_"R";cBae_A) m!rotect(@_"R";;"aL, BS3RA, H2DEH4ZJ) m!rotect(@S, AfS, H2DEH4ZJ) m!rotect(@_"R";cBc", AfS, H2DEH4ZJ) munma!(@_"R";cB;B, BB3LB) "stat(B, stEmodeFENKH4CbSSA, stEsi6e, ...) mma!(UWGG, AfS, H2DEH4ZJbH2DEkHND4, +ZEHNZD4b+ZEZU2U+2WF, -B, ) @_"R";cBcc rite(B, $ello, orld&'n, BA) BA e@itEgrou!(BA) === e@ited ith BA ===
Pera aiE Por$%e e4ecve est se,do camadaB !c o,tece $%e *inu4 ,ão cria %m processo do ,ada;. odos os processos são .orks do processo init e depois * feita a camada para e4ecve para s%bstit%ir o ,ovo; processo pe"a ima+em co,tida ,o ar$%ivo e&ec%tve"... /epois disso a primeira coisa $%e vocJ ,ota * a te,tativa de abrir %m ar$%ivo de co,fi+%raão 2' ! opão -" precisa ape,as da porão do ,ome da bib"iote ca $%e se+%e Y"ibY e precede Y.soY o% Y.aY. Por e&em p"o se vocJ precisar %sar f%,es da bib"ioteca libbit5H9so s= precisar especificar -"5Nbit-2; para o CC.
43
camado ld9so9no/ca&. ?sso e&iste por$%e a"+%mas bib"iotecas podem ter sido pr*-carre+adas e estão atre"adas a feat%res espec
)sse traba"o todo * %m dos motivos pe"os $%ais dese,vo"ver ap"icaes i,teiras em assemb"# * impraticve".... ! libc co,t*m %m e,orme co,%,to de .eatures $%e faci"itam m%ito ,ossas vidas. 6em e"a vocJ teria $%e criar t%do isso ma,%a"me,te S medida $%e ,ecessitar. ! va,ta+em da libc * $%e essas i,icia"iaes são feitas ape,as %ma ve bem como roti,as de fi,a"iaão T se ,ecessrias. ma ve $%e o c=di+o em main * e&ec%tado todo o co,tro"e est com a s%a ap"icaão. c"aro de temp os em temp os vocJ cede esse co,tro"e S libc o% a o%tras bib"iotecas como &t/read por e&emp"o. Aas * %m preo m%ito pe$%e,o para pa+ar em troca de performa,ce estabi"idade e dispo,ibi"idade de ferrame,tas i,teressa,tes.
Cuidados ao usar 'unç6es da libc !s f%,es da "ibc são co,str%
44
em caso de erro 30. !co,tece $%e s#stem tem o pote,cia" de ca%sar +raves prob"emas de se+%ra,a e ,ão * recome,dado por diverso s advisories especia"iados. 5 m*todo correto de disparar %m ,ovo processo * atrav*s do par de f%,es .ork e e4ec. Forking * a aão de criar %ma c=pia do processo at%a" de forma $%e ambos os processos co,ti,%arão a e&ec%ão a partir do .ork. ! f%,ão .ork retor,ar %m de trJs va"ores: •
-1 se o ,ovo processo ,ão pode ser criado a partir do processo at%a"\
•
0 * retor,ado para o processo fi"o\
•
m va"or positivo * retor,ado para o processo pai co,te,do o P?/ do processo fi"o.
! f%,ão .ork tem %m efeito co"atera" i,teressa,te: 5 processo fi"o erda todos os dados descritores de arquivos e o%tros rec%rsos do pai. )sses rec%rsos s= diver+irão do pai $%a,do forem modificados pe"o fi"o. ! partir da criaão do processo fi"o com base ,o processo pai $%eremo s $%e esse ,ovo processo sea substituído pe"a car+a de %m ,ovo e&ec%tve". ?sso * feito por e4ec. )"e sobrepe o processo. 5 c=di+o para e&ec%tar %m processo fi"o arbitrrio dessa ma,eira * esse: static char const * const arg ./!rocL !idEt !id 9 i" ((!id "or()) -B) "!rint"(stderr, 4HH2 UOo "oi !ossPvel carregar o !rocesso "ilho&) e@it(4INDEKZNGWH4) /* 2u outra instruTOo !ara desistir da criaTOo do !rocesso "ilho. */ /* Fe "or o "ilho, su;stitui o !rocesso carregando um novo e@ecut8vel. Uote que o !rimeiro !ar^metro 7 igual ao segundo. 2 !rimeiro !ar^metro 7 o arquivo que ser8 Ve@ecutadoX. 2 segundo !ar^metro 7 equivalente a argv[] e assim !or diante. */ i" (!id ) e@ecl(arg, arg, UWGG) /* 9 o !ai continua aqui 9 */ 9
Aesmo depois da e&ec%ão de e4ecl Go% derivadosH a"+%,s atrib%tos do processo ori+i,a" são preservados afi,a" o processo ai,da * %m .ork do processo ori+i,a" s= com a ima+em bi,ria modificada. Aas a maioria desses atrib%tos são s%bstit%
30 )mbora e&istam difere,as e,tre sistemas P56?UE @o Li,%& por e&e mp"o * recome,dve" $%e se %se o macro )U?6!6 para obter o va"or rea" de retor,o.
4>
Capítulo 4! &esol'endo d('idas sobre a lin#ua#em Assembly sempre bom ter em me,te $%e "i,+%a+em de m$%i,a; * a M,ica "i,+%a+em $%e se% processador e,te,de. odas as o%tras e&istem para $%e vocJ pro+ramador te,a co,dies de dier ao comp%tador o $%e e"e deve faer. )ssas o%tras "i,+%a+e,s precisam ser trad%idas e ,o processo de trad%ão a"+%ma i,te,ão pode ser perdida ma" i,terpretada. Com assemb"# ,os apro&imamos basta,te da "i,+%a+em de m$%i,a; e,te,dida pe"o processador.
O processador pode ter !bugs# ),care se% processador como se fosse %m pe$%e,o comp%tador $%e est e&ec%ta,do co,sta,teme,te %m pro+rama. )sse pro+rama * feito para decodificar i,str%es e e&ec%t-"as. 6= $%e como em $%a"$%er pro+rama e"e pode co,ter b%+s. Para saber $%ais b%+s se% processador tem * ,ecessrio saber $%a" * a versão s= soft8are; $%e e"e est roda,do. ?sso * feito fae,do %ma co,s%"ta via i,str%ão CP?/: /* version.c */ #include #include #include struct versionEs unsigned ste!!ingA unsigned modelA unsigned "amilQA unsigned tQ!eL unsigned L unsigned e@modelA unsigned e@"amilQR static const char *!rocessorEtQ!es[] 2riginal 24+, 2verdrive, Jual, Heserved const char *getMrandFtring(void) void main(void) unsigned a, ;, c, d int tQ!e, "amilQ, "amilQL, model, ste!!ing EEc!uid(B, a, ;, c, d) tQ!e ((struct versionEs *)a)->tQ!e "amilQ "amilQL ((struct versionEs *)a)->"amilQ model ((struct versionEs *)a)->model ste!!ing ((struct versionEs *)a)->ste!!ing i" ("amilQ S bb "amilQ B) i" ("amilQ B) "amilQL = ((struct versionEs *)a)->e@"amilQ model = ((struct versionEs *)a)->e@model << A
47
!rint"(Feu !rocessador '%s''n 'tDi!o %s'n 'tKamPlia @%LI'n 't+odelo @%LI'n 'tFte!!ing @%LI'n, getMrandFtring(), !rocessorEtQ!es[tQ!e], "amilQL, model, ste!!ing) const char *getMrandFtring(void) static char str[Af] unsigned *! si6eEt id@ unsigned a, ;, c, d int i ! (unsigned *)str "or (i L i < A i==) EEc!uid(@R = i, a, ;, c, d) *!== a *!== ; *!== c *!== d *(char *)! ' /* Hetorna string a !artir do !onto onde nOo h8 es!aTos. */ return (const char *)str = strs!n(str, ) -----%<----- corte aqui -----%<----- gcc -o ,ersio% ,ersio%.c ./version Feu !rocessador Nntel(H) ore(D+) i-3_ W 0 3.AC$6 Di!o 2riginal 24+ KamPlia @S +odelo @3Z Fte!!ing @f
),care os campos fam<"ia mode"o e ste&&ing como se fosse a versão do soft8are do se% processador. @o e&emp"o acima em %ma de mi,as m$%i,as de teste temos %m i> c%a versão * (.>'.9. 6e vocJ tiver o mesmo bra,d; de processador Gi>-3>70H pode ser $%e se% ste&&ing sea difere,te. Para a versão (.>' se o steppi,+ for maior $%e 9 e,tão o se% processador tem me,os b%+s $%e o me%...
A mesma instrução pode gastar mais tempo do (ue deveria omemos o e&emp"o de %ma i,str%ão m%ito simp"es: add r/mSA,immSA
rXm(4; si+,ifica $%e o opera,do do "ado es$%erdo aceita %m re+istrador GrH o% referJ,cia S mem=ria GmH de (4 bits. 5 opera,do do "ado direito imm(4; di $%e essa i,str%ão aceita %m va"or imediato %m va"or. 5 ma,%a" de otimiaão da ?,te" ,os di $%e essa i,str%ão tem "atJ,cia de 1 cic"o de m$%i,a mas isso depe,de se estamos %sa,do re+istrador o% mem=ria do "ado es$%erdo. !s d%as i,str%es abai&o tem "atJ,cia difere,tes: add ra@,B add qord [rd@],B
Casta B ciclo Casta L ciclos
R%a,do %samos referJ,cia S mem=ria %m cic"o adicio,a" * +asto por$%e o va"or de (4 bits tJm $%e ser "ido somado ao va"or 1 e depois +ravado de vo"ta. ?sso ,ão aco,tece $%a,do o opera,do * %m 4'
re+istrador. )&istem ai,da a"+%mas idiossi,crasias... !s i,str%es abai&o co,somem tempos difere,tes mesmo $%e ,ão aa o cic"o de "eit%ra-operaão-escrita: cm! ra@,[rsi] cm! [rsi],ra@
Casta L ciclos. Casta 3 ciclos.
!mbas as i,str%es comparam Gs%btraemH o co,teMdo de %m re+istrador GN!UH com o co,teMdo da mem=ria Gapo,tada por N6?H. Aas $%e a se+%,da i,str%ão fa referJ,cia ,o primeiro opera,do e"a +asta 1 cic"o e&tra. Para ter %ma ideia i,t%itiva sobre o +asto de tempo de %ma roti,a * bom ass%mir essa re+ra: NeferJ,cias S mem=ria adicio,am pe"o me,os %m cic"o de m$%i,a e se for do "ado desti,o; da i,str%ão mais %m.
*em todas as instruç6es !gastam# tempo )sse * %m co,ceito dif
5 +asto de tempo da se+%,da i,str%ão est i,corporado ,o +asto da primeira. )specia"me,te por$%e e"a ,ão depe,de de ,ada da primeira... @o e&emp"o ?AL m%"tip"ica )!U por )QU e co"oca o res%"tado ,o par de re+istradores )/U:)!U. @ote $%e o A5V $%e se+%e %sa )CU e )6?. 5%tro e&emp"o de A5V $%e ,ão +asta tempo * o acesso a %ma re+ião da mem=ria mapeada para o *ocal 1PI". 6e+%,do a doc%me,taão da ?,te" essa re+ião * mapeada i,ter,ame,te e ,ão co,some ,e,%m cic"o de "eit%ra por parte do processador... )sses A5Vs podem ser co,siderados como i,sta,tK,eos.
A pil"a e a !red zone# VocJ ver ,o pr=&imo cap
49
-re'ixos !"+%mas i,str%es por ca%sa do %so dos re+istradores são codificadas com tama,o maior do $%e vocJ espera. )is %m e&emp"o: 3B L AR3B
@or ea@,ea@ @or ra@,ra@
)sse b#te 0&4' ,a fre,te dos dois b#tes $%e compem %m U5N )!U)!U; * o prefi&o N)U. )"e i,dica $%e a i,str%ão %sa re+istradores este,didos. @o e&emp"o acima as d%as i,str%es faem e&atame,te a mesma coisa: eram N!U. 5%tros prefi&os e&istem. !"+%mas i,str%es especiais poss%em o prefi&o 0&0F. 5%tras são prefi&os de repetião como N)P N)PO e N)P@O: B 3
Z K3Z K3Z KLZ
movsd re! movsd re!n6 movsd re!6 movsd
5 prefi&o N)P@O * o mesmo %sado pe"o N)P Gsão a mesma coisaH. o N)PO * %m prefi&o difere,te. !"*m do prefi&o temos a i,str%ão A5V6/ G0&!>H. )&istem mais prefi&os. 6e s%a i,str%ão %sa %m po,teiro e %m se"etor de se+me,to difere,te de /6 e"a ser prefi&ada i,dica,do o se"etor %sado. 5 mesmo va"e $%a,do %sar %m se"etor difere,te de 66 para po,teiros com e,dereo-base %sa,do N6P o% NQP. !"*m desses prefi&os corri$%eiros a"+%mas e&te,ses do processador %sam prefi&os especiais. )&iste %m prefi&o U5P Getended PerationH dispo,
mov a@,[esi] mov ea@,[esi]
?sso si+,ifica $%e a maioria das i,str%es $%e "idam com o tipo s/ort podem ter %m b#te a mais e por esse motivo o compi"ador prefere "idar com ints ,em $%e sea ape,as ,o c=di+o fi,a". 5 prefi&o 0&(7 * o address override. @o modo &'(-(4 sempre $%e temos %ma i,direão como )6?j o processador prefere %sar re+istradores de (4 bits afi,a" %m e,dereo ca,h,ico tem >2 bits de tama,o. /a< se %sssemos N6?j ,a i,str%ão acima o prefi&o 0&(7 ,ão seria %sado: L R K
RMS S_RMS SSRMS SSS_RMS ARRMS S_ARRMS
mov mov mov mov mov mov
ea@,[rsi] ea@,[esi] a@,[rsi] a@,[esi] ra@,[rsi] ra@,[esi]
2!erandos e 2!erando de 2!erando de 2!erando de 2!erando de 2!erando de
endereTos do tamanho es!erados. 3L ;its, mas endereTo em 3L ;its& BS ;its, mas endereTo em SA& BS e endereTo de 3L& SA e endereTo de SA (!re"i@o H4I). SA (H4I) e endereTo de 3L (@S_).
5 importa,te * perceber $%e se se%s opera,dos foram de 32 bits e os po,teiros de (4 ,e,%m prefi&o * adicio,ado S i,str%ão. ) por estra,o $%e parea o %so de opera,dos de ' bits ,ão acresce,ta prefi&os a ,ão ser $%e o o%tro opera,do sea %ma i,direão %sa,do po,teiros de 32 bits: RZS
mov al,[rsi]
Atenção! 5 prefi&o N)U ,ão * fi&ado em 0&4'. /e fato e&iste mais $%e %m desses prefi&os
>0
depe,de,do do formato da i,str%ão. Aas os prefi&os 0&(( e 0&(7 são fi&os e s%as semK,ticas são as citadas. ! dica a$%i * a de $%e vocJ deve evitar o %so de tipos de 1( o% (4 bits ta,to $%a,to poss
Como vimos a,teriorme,te a i,str%ão A5V !UN6?j; tem 3 b#tes de tama,o com %m prefi&o 0&((. ! i,str%ão A5V ,este caso te,de a ser mais "e,ta $%e A5V6U. c"aro $%e ,em sempre o CC %sar essa t*c,ica. Por e&emp"o o c=di+o pode precisar da parte s%perior de )!U mas e"e tem preferJ,cia por faer isso.
>1
>2
Capítulo +! ,isturando C e Assembly )&istem d%as formas de mist%rar f%,es escritas em C e em assemb"#. @o primeiro modo * %sa,do o $%e se cama de assembler inline. !ssemb"er; Gcom YerYH si+,ifica mo,tador. ?,"i,e; por$%e o c=di+o em "i,+%a+em assembl' Gcom Y#YH ser mist%rado com o c=di+o em C. 5 se+%,do modo * %sa,do %m assembler e&ter,o como o A!6A !6 o% @!6A. sarei esse M"timo por s%a simp"icidade e portabi"idade Ga"*m do $%e * free soft8are;H. !,tes de comearmos a ba+%,a * importa,te e,te,der como o compi"ador C or+a,ia as f%,es para $%e possamos %sar o mesmo padrão com as "ista+e,s em assemb"# %sa,do %m assemb"er.
Convenç6es de c"amada devem ser sempre preservados e,tre camadas. Com o i,do8s a coisa ,ão * tão f"e&. Ar$uitetura
P56?U !Q?
i,do8s
8armetros
etorno e!emserpreser!ados
Inteiros
N/? N6? N/U NCU N' e N9
N!U
Ponto flutuante
UAA0 at* UAA7
UAA0
Inteiros
NCU N/U N' e N9 N!U
NQU NQP N6? N/? N12
Ponto flutuante
UAA0 at* UAA3
at* N1>. UAA( at* UAA1>
NQU NQP N12 at* N1>.
UAA0
0abela 6: egistradores usados na convenJo de c/amada 4+3536
6e o%verem mais parKmetros do $%e re+istradores dispo,
>3
int "(int @, ...)
@o prot=tipo acima o compi"ador ,ão tem como saber de a,temão o ,Mmero de parKmetros. 6e camarmos a f%,ão desta ma,eira: "(B,L,3,A,,S,_,R)
5 compi"ador co"ocar os primeiros ( parKmetros ,os re+istradores de acordo com a co,ve,ão e os dois resta,tes ,a pi"a. )mpi"a,do31 primeiro o va"or ' e depois o 7: mov edi,B mov esi,L mov ed@,3 mov ec@,A mov rRd, mov rfd,S su; rs!,BS mov dord !tr [rs!],_ mov dord !tr [rs!=R],R call " add rs!,BS
Z`usta HF !ara em!ilhar os dois dords. Uote que _ est8 no to!o da !ilha. Gim!a a !ilha.
5%tro e&emp"o Mti" para me"or compree,são da co,ve,ão de camada &'(-(4 * $%a,do temos %ma f%,ão assim: void "(int @, "loat Q, int 6)
5 parKmetro 4 ser passado atrav*s do re+istrador N/? o y atrav*s de UAA0 e z pe"o N6?. ?sso $%er dier $%e N6? * o se+%,do parKmetro i,teiro da se$%J,cia mesmo $%e o se+%,do parKmetro rea" sea %m .loat.
Convenç6es de c"amada
cdec"
odos os ar+%me,tos da f%,ão são empi"ados da direita para es$%erda.
fastca""
5s dois primeiros ar+%me,tos são passados pe"os re+istradores )CU e )/U respectivame,te. 5 resta,te * empi"ado da direita para es$%erda como em cdecl. Variaão da a,ti+a co,ve,ão &ascal. 5s ar+%me,tos são passados da direita para es$%erda pe"a pi"a. !i,da a f%,ão camada * respo,sve" por "impar; a pi"a a,tes de sair.
stdca""
0abela N: "onvenJKes de c/amada no modo 2H bits9
!ssim como ,a co,ve,ão %sada ,o modo &'(-(4 o re+istrador )QU deve sempre ser co,servado. ! co,ve,ão cdecl * a co,ve,ão padrão para $%a"$%er compi"ador C. !s o%tras se %sadas devem ser e&p"icitame,te i,formadas. @o caso do i,do8s * com%m observar dec"araes como esta: int ZGGMZj kin+ain($NUFDZU4, $NUFDZU4, GFDH, int)
)sse "1**B1"M ,a dec"araão da f%,ão * certame,te %m macro $%e * s%bstit%
>4
Go% stdcallH. ! e&ceão * a f%,ão s&rint. $%e aceita ,Mmero varive" de parKmetros... 5 $%e s= * poss
5 c=di+o +erado pe"a f%,ão acima pode aparecer de vrias formas. ! mais provve" se a m&ima otimiaão for %sada * a $%e vem a se+%ir: "
mov ea@,[es!=A] add ea@,[es!=R] ret
ega a. soma com ;.
Lembre-se $%e sempre $%e %m va"or * co"ocado ,a pi"a o po,teiro de pi"a G6tacD Poi,terH * decreme,tado e depois o va"or * +ravado ,o "%+ar apo,tado. Como a f%,ão . %sa a co,ve,ão cdecl sabemos $%e YbY * empi"ado primeiro se+%ido por YaY. /epois dos dois empi"ame,tos a i,str%ão call * %sada para camar a f%,ão o $%e ca%sa o empi"ame,to do e,dereo de retor,o S f%,ão camadora. por isso $%e %samos esp4j para obter o va"or de YaY Go M"timo va"or empi"adoH $%e )6P apo,ta para %ma posião da pi"a $%e co,t*m o e,dereo de retor,o...
Figura V: Pil/a, antes e de&ois de c/amar a .unJo com a convenJo cdecl9
@a fi+%ra acima YaY * o va"or co,tido ,o ar+%me,to a passado para a f%,ão. !ssim como YbY * o va"or do ar+%me,to b. ! camada * feita assim: @ "(B,L) -----%<----- corte aqui ?digo equivalente... !ush dord L 4m!ilha !ush dord B 4m!ilha call " su; es!,R
-----%<----note a ordem do em!ilhamento... L B
Gim!a a !ilha.
5 c=di+o em assemb"# acima * ape,as %m e&emp"o didtico. mais provve" $%e se% compi"ador faa a"+o assim: add es!,R mov dord !tr [es!=A],L mov dord !tr [es!],B call " su; es!,R
Zloca L ints na !ilha. oloca os L ints na ordem es!erada. chama ". lim!a a !iha.
>>
5%tros deta"es di+,os de ,ota são: •
•
5 tipo .loat * passado como se fosse %m tipo int o% sea o co,teMdo bi,rio da varive" * empi"ado ,o mesmo espao de 32 bits $%e seria %sado por %m int9 Note $%e ,ão %so de re+istradores 66) a%tomaticame,te como ,a co,ve,ão %sada pe"a ar$%itet%ra &'(-(4\ ipos com (4 bits de tama,o são passados atrav*s do empi"ame,to de dois va"ores de 32 bits. ! porão mais si+,ificativa * empi"ada primeiro. 5 motivo * $%e ao acessar esses va"ores via po,teiros de de,tro da f%,ão a ordem little endian tem $%e co,ti,%ar se,do obedecida\
•
ipos com me,os de 32 bits G c/ar e s/ortH são co,vertidos para o e$%iva"e,te de 32 bits
•
a,tes de serem empi"ados\ Como ,ão possibi"idade de %sar o par de re+istradores N/U:N!U ,o modo 32 bits o tipo este,dido OOintH+ te,de a ,ão estar dispo,
@este po,to vocJ pode se per+%,tar: Por $%e a co,ve,ão .astcall ,ão * a preferida dos compi"adores ,o modo i3'(B;. !fi,a" %sar re+istradores ,os dois parKmetros i,iciais evita pe"o me,os dois empi"ame,tosE !co,tece $%e .astcall ,ão * %sado por ,e,%m sistema operacio ,a" e os criadores de compi"adores estão "ivres para imp"eme,tar essa co,ve,ão como bem os co,vier. o ca so do Borland "-- Builder Go% Embarcadero "-- Builder como preferiremEH... @este compi"ador a te,dJ,cia de %sar 3 re+istradores ao i,v*s de 2: )!U )/U e )CU ,esta ordem ,%ma co,ve,ão camada por e"es de register. Como .astcall ,ão * ,em de perto padro,iada e,tão * pr%de,te evit-"a. ! ,ão ser $%e vocJ saiba rea"me,te o $%e est fae,do... /e todo modo a co,ve,ão padro,iada do modo &'(-(4 * s%perior Ss co,ve,es mostradas a$%i. 5s po,tos de i,teresse ,esse t=pico são: ! co,ve,ão de camada ,o modo i3'( * di#erente da %sada ,o modo &'(-(4 Go $%e as tor,a i,compat
8unç6es com nDmero de parBmetros varivel no x12&23 @a co,ve,ão cdecl os parKmetros são passados pe"a pi"a mas ,o &'(-(4 os ( primeiros são passados por re+istradores. Como * $%e fica o caso de camadas para f%,es $%e poss%em ,Mmero varive" de parKmetrosB 6%po,a $%e te,amos a dec"araão de . abai&o e %ma camada: e@tern void "(int @, ...) "(B,L,3,A) -----%<----- corte aqui -----%<----e@tern " g mov ec@,A mov ed@,3 mov esi,L mov edi,B call "
R%er dier a co,ve,ão de camada &'(-(4 co,ti,%a va"e,do i,c"%sive para f%,es com ,Mmero de parKmetros i,defi,ido...
-il"a. nos modos i /12 e x12&23 @ão sei se fico% evide,te. Pi"as ,esses dois modos comportam-se de ma,eiras difere,tes. @o modo i3'( cada e,trada ,a pi"a tem 32 bits de tama,o. ?sso $%er dier $%e )6P ser i,creme,tado o% decreme,tado de 4 em 4 b#tes. ,o modo &'(-(4 a"*m de %sarmos o re+istrador >(
este,dido N6P cada e,trada ,a pi"a tem (4 bits de tama,o o% sea $%a,do N6P for movido; ser de ' em ' b#tes.
;m detal"e sobre o uso de registradores de /0 e 23 bits @a ar$%itet%ra &'(-(4 os re+istradores de 32 bits são %m s%bco,%,to dos re+istradores de (4 bits. )!U por e&emp"o * a porão dos 32 bits me,os si+,ificativos do re+istrador N!U. @o caso dos re+istradores este,didos N' at* N1> para acessar os 32 bits i,feriores basta %sar %m s%fi&o: N'/ at* N1>/ o,de Y/Y si+,ifica /5N/. 6e %sar o s%fi&o YY estaremos acessa,do os 1( bits me,os si+,ificativos T YY de 5N/. 5 deta"e $%e $%ero mostrar * $%e ao %sar )!U ao i,v*s de N!U os 32 bits s%periores do re+istrador de N!U são a%tomaticame,te erados. ?sso se deve ao fato $%e a i,str%ão $%e "ida com )!U * a mesma $%e "ida com N!U. Por e&emp"o: test.asm ;its SA section .te@t glo;al ""unction
B
" mov ra@,B mov ea@,B ret -----%<----- corte aqui -----%<---- %asm -& el&'( -l #es#.s -o #es#.o #es#.asm ca# #es#.s ;its SA L section .te@t 3 A glo;al ""unction S " _ MRB mov ra@,B R MRB mov ea@,B f Z 3
ret
Nepare $%e o microc=di+o GopH das d%as i,str%es A5V são idJ,ticas. )"as s= serão difere,tes se N!U for i,icia"iado com %m va"or maior $%e 32 bits. C"aro $%e o $%e se ap"ica a )!U e N!U ap"ica-se a todos os o%tros re+istradores de %so +era" GN!U NQU NCU N/U N6? N/? NQP N6P N' at* N1>H.
7xemplo de 'unção em assembl usando a convenção de c"amada )is as "ista+e,s de %ma simp"es f%,ão em C e o c=di+o +erado pe"o compi"ador em !ssemb"#: /* sim!le.c */ int "(int @, int Q, int 6) return @ * Q = 6 -----%<----- corte aqui -----%<---- sim!le.s gerado !elo com!ilador 4ntrada HJN @ HFN Q HJI 6 FaPda 4ZI " imul edi,esi HJN 4JN*4FN (@ @*Q) lea ea@,[rdi=rd@] 4ZI 4JN=4JI (return @=6) ret
!o ser camada pe"o c=di+o em C a f%,ão YfY receber o va"or de Y&Y pe"o re+istrador N/? Y#Y pe"o >7
N6? e YY pe"o N/U de acordo com a co,ve,ão. N!U * %sado para devo"ver o res%"tado $%e ,o caso * do tipo Yi,tY. ),tão a roti,a preoc%pa-se ape,as com a /5N/ me,os si+,ificativa de N!U Go% sea )!UH. 5 compi"ador %sar )/? )6? e )!U por$%e especificamos o tipo Yi,tY. Vis%a" C %sar a co,ve,ão da Aicrosoft s%bstit%i,do N/? por NCU N6? por N/U e o N/U por N': 9 " !roc near imul ec@,ed@ lea ea@,[rc@=rR] ret " end! 9
Aviso sobre retorno de 'unç6es com tipos complexos F%,es podem retor,ar tipos comp"e&os como structs e unions mas ,ão * %ma boa id*ia retor,ar esses tipos por va"or... Co,sidere o $%e aco,tece $%a,do retor,amos va"ores de tipos primitivos como int por e&emp"o... 5 va"or retor,ado * %ma c=pia do va"or co,tido de,tro da f%,ão. @o c=di+o: int "(int @) int tem! @ = @ return tem!
Eão estamos retor,a,do a varive" tem& mas %ma c=pia de se% co,te%do para o camador. !
mesma coisa aco,tece com estr%t%ras retor,adas por va"or como ,o e&emp"o: struct mQFtruc int count int arraQ[] struct mQFtruc "(int @) struct mQFtruc ms @, , B, L, 3, A return ms -----%<----- corte aqui -----%<----" mov ra@,rdi mov [rdi],esi ms.count @ mov [rdi=A], mov [rdi=R],B mov [rdi=BL],L mov [rdi=BS],3 mov [rdi=L],A ret
Nepare: ! f%,ão co,ti,%a retor,a, do N!U mas desssa ve retor, %m po,teiro para a estr%t%ra $%e ter sido a"ocada pe"a forma f%,ão$%e camadora po,teiro essa estr%t%ra * passado pe"odever re+istrador N/? da mesma seria feitodese..am f%,ão fosse para escrita assim:
>'
struct mQFtruc !->count @ !->arraQ[] !->arraQ[B] !->arraQ[L] !->arraQ[3] !->arraQ[A] return !
*"(struct mQFtruc *!, int @) B L 3 A
)ste parece ser %m rec%rso i,teressa,te mas dJ %ma o"ada ,o c=di+o +erado pe"a roti,a abai&o: struct mQFtruc int count int @[BL] struct mQFtruc "(int @) int i struct mQFtruc ms @ "or (i i < BL i==) ms.@[i] @=B return ms -----%<----- corte aqui -----%<----" !ush r;! mov ed@,LL mov e;!,esi Cuarda o !ar^metro @. !ush r;@ @or esi,esi ai !reencher a estrutura com 6eros. mov r;@,rdi Cuarda o !onteiro da estrutura VescondidaX. su; rs!,L_L Zloca es!aTo !ara a estrutura na !ilha. mov rdi,rs! call memset lea lea lea .GB mov add cm! `ne
rRd,[r;!=B] rd@,[rs!=A] rc@,[rs!=LL]
rRd @ = B rd@ a!onta !ara o Pncio de @[]. rc@ a!onta !ara o "im de @[].
[rd@],rRd rd@,A rd@,rc@ .GB
escreve em @[i]. avanTa i. chegou ao "im nOo ontinua !reenchendo.
mov mov mov mov call add
rsi,rs! rdi,r;@ ed@,LL [rs!],e;! memc!Q rs!,L_L
rsi a!onta !ara a estrutura na !ilha. rdi a!onta !ara estrutura VescondidaX. amos co!iar LL ;Qtes. 4screve o !arOmetro @ em count. Ka6 a c?!ia. Gim!a a !ilha.
mov !o! !o! ret
ra@,r;@ r;@ r;!
Hetorna o !onteiro !ara a estrutura VescondidaX.
Co,ti,%amos obte,do N!U como resposta co,te,do o po,teiro esco,dido; passado para a f%,ão tremendamente complicada dob#tes $ue de!eria mas como E ! f%,ão a"oca 20>2repare b#tes Gos >12e"aintfico% Ys do arra# e o count damais estr%t%raH mais 20 GBEH. )"a pree,ce todo o arra# com eros G%sa,do memsetH co"oca em N'/ o va"or de 4 passado para a f%,ão e %sa N/U e NCU ,as iteraes do "oop pree,ce,do o co,teMdo da pi"a com os va"ores deseados... Lo+o depois memc&y copia toda a estr%t%ra para a re+ião da mem=ria dada pe"o po,teiro esco, dido; e retor,a esse po,teiro em N!U.
) esse * %m c=di+o simp"esE s vees o compi"ador se vJ obri+ado a faer %so do se"etor de se+me,to F6 para co,ter %m e,dereo base e tor,a todo o c=di+o praticame,te i"e+9
po%co performticoE !+ora compare o c=di+o a,terior com este: struct mQFtruc *"(struct mQFtruc *!tr, int @) int i !tr->count @ "or (i i < BL i==) !tr->@[i] @=B return !tr -----%<----- corte aqui ------%<----" mov ra@,rdi mov [rdi],esi @or ed@,ed@ lea ec@,[rsi=B] .GB mov [ra@=A*rd@],ec@ add rd@,A cm! rd@,LAR `ne .GB ret
)ste c=di+o fa a mesma coisa G"itera"me,teH $%e o a,terior sem pree,cer o arra# 4 com eros e sem faer %ma c=pia para %ma estr%t%ra esco,dida; ,os parKmetros. )"a * me,or e mais rpidaE /ei&o essa dica: amais retor,e estr%t%ras e %,ies por va"orE
O uso da pil"a ! pi"a * %sada para receber parKmetros $%e ,ão caibam ,%m re+istradores o% se a $%a,tidade de parKmetros for maior $%e %ma certa $%a,tidade de acordo com a co,ve,ão de camada. Nepare $%e para P56?U !Q? e&istem > re+istradores $%e s%portam parKmetro s i,teiros e ' re+istradores $%e s%portam parKmetros em po,to f"%t%a,te. 6e por e&emp"o tiv*ssemos %ma f%,ão dec"arada como: int "(int, int, int, int, int, int, "loat)
5s primeiros ci,co parKmetros serão passados via N/? N6? N/U N' e N9 mas o se&to Yi,tY ser ,ecessariame,te co"ocado ,a pi"a. 5 M"timo parKmetro ser passado por UAA0. 5%tro %so para a pi"a * o armae,ame,to temporrio e de variveis "ocais G$%e ,ão caibam ,os re+istradores dispo,
/* salva HMI, HI e HJI na !ilha. */
/ Hecu!era HMI, HI e HJI da !ilha. */
Cada %ma das i,str%es P6I s%btrai ' do re+istrador N6P e depois move o co,teMdo do re+istrador se,do emp%rrado; %sa,do N6P como po,teiro. 5 c=di+o e$%iva"e,te do primeiro P6I seria mais o% me,os assim: (0
su; rs!,R mov [rs!],r;@
@o caso ,o c=di+o $%e precisa emp%rrar; vrias coisas para a pi"a Ge depois p%&-"as; de vo"taH o compi"ador +era"me,te reso"ve faer a s%btraão Ge depois a adiãoH %ma s= ve:
Z`usta o HF !ara LA ;Qtes !ara ;ai@o. Uote que LA 7 3 ve6es o tamanho de cada um dos registradores. 2 motivo de serem guardados de tr8s !ara "rente 7 que a !ilha cresce !ara ;ai@o.
su; mov mov mov 9 mov mov mov add
rs!,LA [rs!=BS],r;@ [rs!=R],rc@ [rs!],rd@ rd@,[rs!] rc@,[rs!=R] r;@,[rs!=BS] rs!,LA
)m teoria a primeira roti,a com os P6Is e P5Ps +astaria cerca de 12 cic"os e,$%a,to a roti,a acima +astaria ape,as '.
Eariveis locais e a pil"a Vimos como os ar+%me,tos de %ma f%,ão são passados sea por re+istradores sea pe"a pi"a mas e $%a,to as variveis "ocaisB 6e vocJ compi"ar se% c=di+o com a"+%m , e@tern int g(void) void "(void) int @ g()
// hama g() !ara iniciali6ar @.
!rint"(%!'n, @)
// Uote que tomamos o endereTo de @ aqui. -----%<----- corte aqui -----%<----.section .data "mt d; %!,B, .section .te@t e@tern g e@tern !rint"
(1
" call g lea rsi,[rs!-A] mov
[rsi],ea@
mov rdi,"mt call !rint" ret
// amos !assar o !onteiro !ara !ritn". // 4ntOo, coloca-o em HFN (L argumento de !rint"). // 4ZI cont7m o resultado retornado !or g(). // Zrma6ena 4ZI na vari8vel local, na !ilha. // HJN 7 o !rimeiro argumento de !rint"(). // hama !rint"().
@o e&emp"o acima o res%"tado da camada S f%,ão g>) ,o re+istrador )!U * armae,ado ,a pi"a em N6P-4j por$%e a f%,ão &rint. precisa do po,teiro da varive" "oca" 4. !i,da se+%,do a co,ve,ão de camada os dois ar+%me,tos de &rint. devem ser passados pe"a ordem em N/? e N6?. Por isso ca"c%"ei N6? a,tes de %s-"o como po,teiro. Como re+ra +era" toda varive" "oca" $%e se% c=di+o precisa acessar atrav*s de po,teiros * co"ocada ,a pi"a... Aesmo para a$%e"es casos o,de o compi"ador co,se+%e ma,ter as variveis "ocais em re+istradores a re+ião de armae,ame,to "oca" Gabai&o do e,dereo de retor,oH pode ser %sado como armae,ame,to temporrio. 6%po,a $%e s%a f%,ão %se N12 e a f%,ão camada tamb*m o %se. ,ecessrio +%ardar o co,teMdo de N12 ,o espao "oca" camar a f%,ão e depois rec%per-"o: mov [rs!-R],rBL call "unc mov rBL,[rs!-R]
! co,ve,ão de camada %sada pe"a ar$%itet%ra &'(-(4 prevJ $%e a"+%,s re+istradores podem ser descartados e,tre camadas mas o%tros devem ser preservados G"embraBH. 5 artif
O compilador não usa todas as instruç6es 6e vocJ der %ma o"ada ,o vo"%me 2 dos ma,%ais de dese,vo"vime,to de soft8are da ?,te" para os modos i3'( e &'(-(4 poder e,co,trar i,str%es como UL! )CUO UCI L55P e o%tras com ,omes i,teressa,tes. !"+%mas parecem bem Mteis mas depois de o"ar para m%itas "ista+e,s em assemb"# +eradas pe"o se% compi"ador C perceber $%e e"e ,ão as %sa... @@C!E 5 motivoB Performa,ce. !"+%mas dessas i,str%es mais especia"iadas são rea"me,te "e,tas. Aais "e,tas do $%e %m c=di+o $%e fa a mesma coisa %sa,do i,str%es mais discretas;. @os e&emp"os abai&o a primeira roti,a * mais rpida $%e a se+%,da: !rimeira rotina... .GB 9 "a6 alguma coisa aqui 9 su; rc@,B `n6 .GB -----%<----- corte aqui -----%<---- segunda rotina... .GL 9 "a6 alguma coisa aqui 9 loo! .GL
! i,str%ão L55P fa e&atame,te a mesma coisa $%e 6QX@O acima mas s%rpree,de,teme,te * mais "e,taE
32 6obre caces veremos mais S fre,te.
(2
! "ista+em abai&o mostra o%tro caso o,de %ma i,str%ão especia"iada era mais "e,ta $%e a se$%J,cia de i,str%es mais discreta: !rimeira rotina... ;6ero mov rc@,rsi @or al,al .GB mov [rdi],al inc rdi dec rc@ `n6 .GB ret -----%<----- corte aqui -----%<---- segunda rotina... ;6ero mov rc@,rsi @or al,al re! stos; ret
Como ,o caso a,terior a primeira roti,a fa a mesma coisa $%e a se+%,da. Aas a primeira era mais rpida. 6ome,te ,as ar$%itet%ras mais rece,tes Gse ,ão me e,+a,o a partir da (andy BridgeH o %so do prefi&o N)P com as i,str%es de ma,ip%"aão de b"ocos 656Q e A5V6Q ficaram mais rpidas... ! i,str%ão UCI * o%tro caso i,teressa,te... !pare,teme,te e"a * bem Mti": roca o co,teMdo e,tre dois re+istradores Go% re+istrador e mem=riaH. !s d%as "ista+e,s parciais abai&o seriam e$%iva"e,tes: 9 usando @chg !ara trocar HZI !elo contedo de mem?ria @chg ra@,[varB] 9 -----%<----- corte aqui -----%<----9 mov r;@,[varB] mov [varB],ra@ mov ra@,r;@ 9
)&ceto $%e a se+%,da "ista+em %sa o re+istrador NQU como armae,ame,to temporrio e a primeira ,ão o fa. @esse caso UCI parece ser bem atrae,te pois fa o $%e 3 A5V; faem sem %sar %m re+istrador e&tra. 6e fosse s= isso e"a seria de fato m%ito i,teressa,teE !co,tece $%e UCI $%a,do %m dos parKmetros * %ma referJ,cia S mem=ria tamb*m modifica o estado do si,a" L5C^[ da CP. )ste si,a" i,forma os o%tros processadores $%e o barrame,to de e,dereos e dados estão travado s; e ,ão podem ser modificado s. ?sso +ara,te $%e UCI ir "ermodificar-+ravar a mem=ria sem i,terferJ,cias de o%tros processadores. Com isso a i,str%ão +asta mais cic"os de m$%i,a do $%e deveria fica,do mais "e,ta $%e os 3 YA5VYs. @chg ra@,[rdi] @chg rd@,rc@
4ssa instruTOo usa o !re"i@o G2j automaticamente. 4ssa instruTOo %o usa o !re"i@o G2j autom8tico.
UCI * m%ito boa $%a,do temos $%e faer trocas e,tre re+istradores. )stra,ame,te o compi"ador ,%,ca a %saE )&istem ai,da i,str%es mais comp"e&as $%e ,ão %sadas pe"o compi"ador: 6ea pe"a bai&a performa,ce pe"a i,%ti"idade; o% pe"o %so m%ito espec
4etal"es interessantes sobre a instrução *O- e o pre'ixo F7@5P * a i,str%ão $%e ,ão fa ,ada s= +asta tempo. )"a * basta,te %sada para a"i,ar c=di+o. (3
ipicame,te @5P * %ma i,str%ão $%e +asta ape,as %m b#te ,o se+me,to de c=di+o mas a ?,te" a este,de% para $%e possa %sar mais espao se ,ecessrio +asta,do a mesma $%a,tidade de cic"os de c"ocD. )sses ,ovos @5Ps permitem operadores e são co,e cidos como /inted no&s . )is e&emp"os da "ista+em obtida pe"o @!6A33: B
;its SA L 3 A S _
B Z
f SSKBK SSKBKA SSKBKA
section .te@t no! no! ord no! ord no! ord
[ra@] [ra@=ra@] [nos!lit ra@=]
R f B BB BL B3
B3 BS BZ LL LS LM
KBK KBKA KBKA ARKBK ARKBKA ARKBKA
no! no! no! no! no!
[ra@] [ra@=ra@] [nos!lit ra@=] [ra@] [ra@=ra@] [nos!lit ra@=]
dord dord qord qord qord
odas essas variaes +astam ape,as %m M,ico cic"o de c"ocD mas tJm tama,os difere,tes. Nepare $%e podemos %sar @5Ps de 1 3 4 > ' e 9 b#tes. !"+%mas dessas verses %sam o% o prefi&o 0&(( o% o prefi&o 0&4'. 5 prefi&o 0&(( di ao processador $%e opera,do ter 1( bits de tama,o. 5 prefi&o N)U Ge,tre 0&4' e 0&4fH * %sado ,o modo de (4 bits para i,dicar $%e o opera,do tem de fato (4 bits de tama,o. 5 tama,o defa%"t de opera,dos ,a ar$%itet%ra &'(-(4 * /5N/ G32 bitsH. Por isso @5P /5N/ N!Uj; ,ão tem prefi&o N)U mas @5P R5N/ N!Uj; tem. @ão se preoc%pe com o prefi&o N)U o% o prefi&o 0&((. 5s compi"adores tomam co,ta disso... Para obter @5Ps de 2 b#tes podemos %sar a i,str%ão UCI: @chg a@,a@
Nsso ser8 tradu6ido !ara VSS fX, no micro-c?digo. como se coloc8ssemos o !re"i@o SS antes do U2.
5bter @5Ps de ( e 7 b#tes de tama,o * mais comp"icado mas * poss
)mbora essas i,str%es te,dam a rea"iar %ma operaão aritm*tica Gsem afetar $%ais$%er f"a+sH o processador percebe $%e ,ada est se,do feito de fato e e"as s= +astarão 1 cic"o de m$%i,a. R%a,to ao prefi&o N)P Ss vees o compi"ador o co"oca ,a fre,te de i,str%es o,de e"e ,ão se ap"ica como ,o e&emp"o: re! ret
5 $%e o compi"ador te,ta faer a$%i tamb*m * a"i,ame,to. 6e e"e %sasse @5P para a"i,ar o N) +astaria %m cic"o de m$%i,a adicio,a" des,ecessariame,te... !o %sar N)P $%e s= f%,cio,a com i,str%es de ma,ip%"aão de b"oco GA5V6 656 L5/6 CAP6H e ,ão afeta $%ais$%er o%tras e"e evita isso.
33 5 modificador nos&lit ,o e,dereo efetivo i,dica ao @!6A $%e este ,ão dever otimiar; a e&pressão.
(4
LOO- e LOO-*G são di'erentes. mas F7-*G e F7- são a mesma coisa ) por fa"ar em ma,ip%"aão de b"ocos e&istem dois tipos de prefi&o N)P: m $%e testa se o f"a+ OF * ero e o%tro se e"e * %m. !o %sar N)P; vocJ est %sa,do N)P@O... Aas c%idado $%e com i,str%es $%e ,ão afetam OF %sa-se N)P. sa,do as i,str%es de b"oco com N)P@O o% N)PO o processador vai testar o co,teMdo do re+istrador NCU co,tra ero para determi,ar a $%a,tidade m&ima de repeties. /epois e"e vai e&ec%tar a i,str%ão decreme,tar NCU i,creme,tarXdecreme,tar Gdepe,de,do do f"a+ /FH N6? eXo% N/? Gdepe,de,do da i,str%ãoH testar o f"a+ OF e repetir t%do de ,ovo depe,de,do do prefi&o. ! i,str%ão abai&o pode ser escrita em pse%do-c=di+o como: re!n6 scas; corte aqui -----%<---------%<----/* !seudo-c?digo */ e@tern struct "lags e"lags void re!n6Escas;(unsigned long rc@, void *rdi, char al) hile (rc@ & ) rc@-- e"lags.6" i" (*rdi al) e"lags.6" B ;rea i" (&e"lags.d") rdi== else rdi--
L55P L55PO e L55P@O por o%tro "ado são difere,tes e,tre si. ! primeira i,str%ão testa some,te se NCU * ero o% ,ão decreme,ta,do-o a,tes de sa"tar... !s o%tras d%as testam o co,teMdo do f"a+ OF antes de decreme,tarem NCU.
Assembl inline /e,tro de se% c=di+o em C vocJ pode %sar c=di+os em assemb"#. ?sso f%,cio,a ,a maioria dos compi"adores CXC mas a si,ta&e pode variar de compi"ador para compi"ador. Como estamos %sa,do o CC a si,ta&e pode parecer %m ta,to co,f%sa: EEasmEE EEvolatileEE ( string_com_código_asm" [saída] [entrada] [registradores modificados] )
! pa"avra reservada ]]asm]] * basta,te =bvia mas por$%e esse b"oco deve ser marcado como ]]vo"ati"e]]B !co,tece $%e mesmo %m c=di+o em assemb"# pode ser otimiado pe"o CC. !o marcar o c=di+o como volatile diemos ao compi"ador $%e este ,ão deve rea"iar otimiaes. Aas ate,ãoE Aarc ar o b"oco como volatile * ape,as %m pedido ao compi"ador $%e e"e pode i+,orar. 5%tra coisa: VocJ pode %sar as pa"avras reservadas asm; e vo"ati"e; sem os underscores: asm volatile ( string [saPda] [entrada] [registros !reservados] )
(>
6= %so ]]asm]] e ]]vo"ati"e]] por$%e a doc%me,taão do CC assim s%+ere $%e se faa para evitar co,f"itos de names&ace. Aas se vocJ der %ma o"ada ,o c=di+o fo,te do Der,e" do Li,%& por e&emp"o ver essa M"tima forma vis%a"me,te mais co,fortve" se,do %sada... )m re"aão aos parKmetros co,tidos ,o b"oco a stri,+ com c=di+o asm; * %ma +ra,de stri,+ co,te,do obviame,te o c=di+o em assemb"#. ! separaão de "i,as pode ser feita com %m Y,Y o% Y\Y. Partic%"arme,te prefiro o M"timo mesmo $%e e"e ba+%,ce %m po%co as "ista+e,s em assemb"# obtidas a partir do CC... 6= * ,ecessrio tomar c%idado com a p"ataforma o,de esses c=di+os assemb"# i,"i,e serão compi"ados... 5 !6 Gassemb"er %sado para compi"ar o assemb"# i,"i,eH %sa Y\Y como i,
/* lista de saPdas */ /* lista de entradas */ /* lista de !reservaTOo. */
!$%i temos a "ista de sa
((
escritor
>igni#icado
a b c d / e 6 Nespectivame,te os re+istradores )!U )QU )CU )/U )/? e )6? o% se%s derivados Gde 1( o% 32 bitsH. r m re+istrador $%a"$%er S esco"a do compi"ador. m mareferJ,ciaSmem=ria + Ne+istrador mem=ria o% co,sta,te. 5 compi"ador esco"e. i o% , Va"or i,teiro GimediatoH. f m re+istrador; do &'7 esco"ido pe"o compi"ador. t % ! & W
5re+istrador;stG0Hdo&'7. 5re+istrador;stG1Hdo&'7. 5 par de re+istradores )/U:)!U o% /U:!U Ne+istrador 66) S esco"a do compi"ador. 5re+istradorUAA0.
34
.
0abela 3: *ista dos &rinci&ais descritores de entrasada &ara assembly inline
@o caso da "ista da descrião de sa
)sse Yq2Y di ao assembler inline $%e deve co"ocar em se% "%+ar o co,teMdo do item 2 da "ista de descritores. @ote $%e o descritor * dec"arado como r; e porta,to o compi"ador far de t%do para s%bstit%<-"o por %m re+istrador. )sse macete * o respo,sve" pe"o fato de re+istradores terem $%e ser prefi&ados com dois YqY. 34 @ote $%e Y!Y não "ida com o par N/U:N!U.
(7
!"*m do %so do <,dice de %m descritor de,tro do c=di+o assemb"# podemos %sar esses <,dices ,os pr=prios descritores. Por e&emp"o: 6%po,a $%e $%eiramos m%"tip"icar %m va"or por 13 em assemb"#. Poder
(
Z saPda ser8 co!iada de HZI !ara VresultX. Z entrada ser8 co!iada de VvalX !ara HZI. Nn"orma que HI "oi alterado na rotina tam;7m&
)% disse $%e os descritores são stri,+s certoB ) stri,+s podem ter mais $%e %m caracter... possigni#icado
? ^ @
?,teiro,afai&ade0..31. ?,teiro,afai&ade0..(3 ?,teiro,afai&ade-12'..127G'bitsH ?,teiro,afai&ade0..2>>G'bitsH
C
Co,sta,tede'0bitsG&'7H Co,sta,te Gpo,to f"%t%a,teH para ser %sada em i,str%ão 66)
e O
Co,sta,tede32bitssi,a"iada. Co,sta,tede32bitssemsi,a". 0abela R: Descritores adicionais q ue &odem ser combinados com outros9
!ssim poder
6e fiermos port; ser 0&70 por e&emp"o o compi"ador pode esco"er compi"ar a i,str%ão acima como 5 0&70!L; ao i,v*s de 5 /U!L;. ),tão fi$%e ate,to: 5s descritores ,ão some,te i,formam e,tradas e sa
Operador de indireção
)ssa difere,a fica evide,te $%a,do %samos %m re+istrador como po,teiro. 6%po,a $%e N/? te,a o e,dereo de %ma varive". Para acessar o co,teMdo desse e,dereo temos $%e %sar o operador de i,direão YjY cerca,do o ,ome do re+istrador: ('
mov
ra@,[rdi]
HZI rece;er8 o long cu`o endereTo 7 dado !or HJN.
;sando a sintaxe )ntel no assembl inline do HCC Por defa%"t o CC s%porta o esti"o ! da "i,+%a+em assemb"#. @este esti"o a ordem dos operadores ,%ma i,str%ão * i,vertida. !i,da a i,str%ão em si carre+a %m modificador die,do o tama,o dos opera,dos. Por e&emp"o: movl A,%ea@
7 a mesma coisa que mov ea@,A.
5 Y"Y depois de YmovY si+,ifica long. 5 va"or 4 precedido de %m Y`Y * %ma co,sta,te $%e ser co"ocada ,o )!U. 5%tra catice do esti"o ! * a ,otaão %sada para refere,cias S mem=ria. !o i,v*s de %sar o operador de i,direão YjY e a ,otaão ?,te": [MZF4 = UJN4*+WGDNGNZJ2H = J4FG2Z+4UD2]
R%e parece-me ser mais i,t%itiva $%e o padrão %sado ,o sabor ! $%e %sa ,otaão difere,te. !"+o assim: J4FG2Z+4UD2(MZF4, UJN4, +WGDNGNZJ2H)
Vea a difere,a ,as d%as i,str%es idJ,ticas: mov ra@,[r;@ = rsi*L = 3] movq 3(%r;@,%rsi,L),%ra@
!adrOo Nntel. !adrOo ZDD
! se+%,da i,str%ão re$%er mais ate,ão para ser e,te,dida do $%e a primeira ,ãoB 6%speito $%e a si,ta&e ! deriva do padrão do assemb"# dos a,ti+os processadores AC('000. Para %sar o esti"o ?,te" parecido com o esti"o %sa,do ,o @!6A e em o%tros assemb"ers ,o assembler inline do CC basta co"ocar se% c=di+o e,tre as diretivas .i,te"]s#,ta&; e
.att]s#,ta&;. )is %m e&emp"o simp"es $%e copia %ma varive" para o%tra: unsigned vB3, vL /* 4stilo ZDD (de"ault) */ EEasmEE EEvolatileEE ( movl %B,%%ea@ movl %%ea@,% g (vL) g (vB) ra@ ) /* 4stilo Nntel */ EEasmEE EEvolatileEE ( .intelEsQnta@ mov ea@,%B mov %,ea@ .attEsQnta@ g (vL) g (vB) ra@ )
,ecessrio dier ao assemb"er i,"i,e $%e o esti"o ! deve ser retomado se,ão vocJ obter erros de compi"aão depois do b"oco ]]asm]].
-roblemas com o assembler inline do HCC Lembre-se $%e o CC te,de a otimiar todo o c=di+o $%e e"e trad% inclusi!e o c=di+o co,tido ,o b"oco ]]asm]]. e,tamos evitar isso com o %so de ]]vo"ati"e]] mas ,em sempre o compi"ador ,os obedece. ?sso pode ser basta,te prob"emtico para a$%e"es $%e +astaram oras refi,a,do %ma roti,a para te,tar obter a me,or $%a,tidade de cic"os de m$%i,a poss
"i&o pe"o compi"ador Go% pior ,em perceber $%e o compi"ador te saca,eo%EH. Nepare $%e o pr=prio es$%ema de passa+em de parKmetros para o b"oco ]]asm]] imp"ica $%e a"+%ma otimiaão ser feita $%er vocJ $%eira $%er ,ão. odo o se,tido de ter %m assemb"er i,"i,e * $%e vocJ pode co"ocar se%s c=di+os otimiados em assemb"# %,to com se% c=di+o C observa,do as re+ras do compi"ador... 6e o compi"ador vai otimiar se% c=di+o de $%a"$%er ma,eira e,tão pra $%e %sar assemb"#B Necome,do $%e ma,te,a se%s c=di+os com a me,or $%a,tidade poss
;sando *AS !o i,v*s de %sar o assemb"er i,"i,e criar ,ossas roti,as em assemb"# em %m c=di+o fo,te separado oferece tamb*m s%as va,ta+e,s. )m primeiro "%+ar ,ão depe,dJ,cia dos rec%rsos de otimiaão do CC Go% de se% compi"ador CXC preferido H. 5%tra coisa i,teressa,te * $%e o @!6A * cross &lat.orm. ?sso $%er dier $%e podemos criar c=di+os em assemb"# para serem %sados ,o Li,%& 56XU i,do8s e o%tros ambie,tes com po%ca o% ,e,%ma modificaão ,o c=di+o ori+i,a"3>. ! preferJ,cia pe"o @!6A * $%e e"e * %m desses compi"adores free soft8are; $%e estão dispo,
amos usar @RS-SA. Zqui comeTa o segmento de c?digo.
glo;al ""unction 2 la;el " ser8 Ve@!ortadoX como !onto de entrada de uma "unTOo. Z "unTOo a;ai@o equivale a int "(int @) return 3*@ " mov ea@,edi add ea@,ea@ add ea@,edi ret
Qasicame,te e&istem $%atro tipos de sectio,s; o% se+me,tos;: C=di+o dados i,icia"iados dados ,ão i,icia"iados e co,sta,tes. )stes são especificados ,a diretiva 6)C?5@ Go% 6)A)@H Y.te&tY. ?sso Y.dataY Y.bssY o% $%e Y.rodataY respectivame,te. ! si+"a * ori+i,ria dedo Block (tartedcomo by (ymbol $%er dier o se+me,to 9bss não fa parte Q66 da ima+em bi,ria se% pro+rama co,tid o ,o ar$%ivo em disco... )sse se+me,to * criado e pree,cido com eros pe"a bib"ioteca libc... /ados ,ão i,icia"iados; em C são sempre i,icia"iados com erosE /ifere,te de o%tros assemb"ers ,ão e&istem diretivas espec ?sso ,ão * " m%ito verdade iro. 6istemas operacio,ais tJm es$%emas difere,tes. Por e&emp"o como vimos ,a co,ve,ão de camadaE
70
"ista+em acima seria escrita mais o% me,os assim Gpara i3'(H: .RS! .model "lat,stdcall .code 4@!orta o !rocedimento ". !u;lic " Uo +ZF+ 7 necess8rio usar H2 e 4UJ !ara demarcar uma "unTOo. " !roc near mov ea@,edi HJN 7 o !rimeiro !ar^metro tam;7m na convenTOo da +icroso"t& add ea@,ea@ add ea@,edi ret " end! end
@ote os proc ,ear; e e,dp;... @o caso do @!6A %m po,to de e,trada de f%,ão * simp"esme,te %m s /* KunTOo de"inida em tri!le.asm, l8 em cima. */ e@tern int "(int) int main(int argc, char *argv[]) !rint"(3*L3 %d'n, "(L3)) return
5 compi"ador vai criar %m ar$%ivo obeto co,te,do a ima+em bi,ria do se% c=di+o fo,te e os s
Para evitar isso vocJ pode retirar o atrib%to Yf%,ctio,Y ,a diretiva Y+"oba"Y. )sses atrib%tos e&istem 3( Li,%& %sa o padrão E4ecutable and *inkable Format G)LFH. i,do8s %sa o "ommon bAect File Format GC5FFH. 5 formato C5FF foi defi,ido pe"o P56?U e adotado pe"a Aicrosoft com o s%r+ime,to do i,32. @o Li,%& o formato )LF foi e"aborado como %m ava,o sobre o C5FF. 5%tros sistemas @?U podem %sar C5FF tamb*m.
71
para fi,s de otimiaão e doc%me,taão feitas pe"o "i,Der especia"me,te para o formato )LF. !pare,teme,te ,ão tJm $%ais$%er %sos ,o format C5FF.
72
Capítulo 6! erramentas )is a"+%mas ferrame,tas Mteis para o dese,vo"vedor i,c"%i,do deb%++er profi"er criaão de proetos e a,"ise de c=di+o.
H*; Lin9er
*(.;ste@t) *(.;sdata)
. Af .header .entrQte@t .initte@t .initdata EEendEinit . .te@t .te@t3L
*(.header) *(.entrQte@t) *(.initte@t) *(.initdata)
*(.te@t) *(.te@t3L)
. ZGNCU(BS) .rodata *(.rodata*) .videocards videoEcards . *(.videocards) videoEcardsEend . . ZGNCU(BS) .data *(.data*)
73
.signature setu!Esig . G2UC(@aaaa) . ZGNCU(BS) .;ss EE;ssEstart . *(.;ss) EE;ssEend . . ZGNCU(BS) Eend . /JNFZHJ/ *(.note*) /* * Dhe ZFF4HD() sin to . is intentional, "or ;inutils L.BA com!ati;ilitQ */ . ZFF4HD(Eend < @R, Fetu! too ;ig&) . ZFF4HD(hdr @B"B, Dhe setu! header has the rong o""set&) /* UecessarQ "or the verQ-old-loader chec to or... */ . ZFF4HD(EEendEinit < *BL, init sections too ;ig&)
)sse script defi,e %m co,%,to de se+me,tos GsessesH $%e estarão co,tidas ,o ar$%ivo a"vo; GvmlinuzBEH a ordem em e"es aparecerão ,o ar$%ivo depois dos c=di+os "i,Dados e %m co,%,to de s G0&1)FH e os demais se+me,tos o se+%em... 5s s
)mbora o script acima sea c%stomiado para o Der,e" ,o users&ace o "i,Der tem %m script defa%"t o,de %m mo,te de se+me,tos e s
3'
/* +ostra endereTos de inPcio e "im dos segmentos do nosso !rograma */ #include /* 2 Vti!oX dos sPm;olos 7 irrelevante. ara o;ter o endereTo do sPm;olo 7 sem!re usar Vvoid *X, necess8rio !or e@em!lo. */ o o!erador . oderPamos declar8-los como e@tern unsigned long Estart /* onto de entrada */ e@tern unsigned long EEe@ecuta;leEstart, Eend /* NnPcio e "im dos segmentos. */
37 /e posse de s
74
void main(void) !rint"(4ndereTo do inPcio %!'n 4ndereTo do "im %!'n onto de entrada %!'n 4ndereTo de main() %!'nX, EEe@ecuta;leEstart, Eend, Estart, main) -----%<----- corte aqui -----%<---- gcc -o #es# #es#.c ./#es# 4ndereTo do inPcio @A 4ndereTo do "im @SfS onto de entrada @AAL; 4ndereTo de main() @AS
Para obter o e,dereo "i,ear do s
Obtendo in'ormaç6es com obIdump 5 %ti"itrio obAdum& pode "istar %ma s*rie de i,formaes i,teressa,tes sobre ar$%ivos obeto i,c"%i,do e&ec%tveis e bib"iotecas. Lista de se+me,tos Gopão -H "ista de s
7>
Con'igurando o H4J Prefiro a si,ta&e Intel ao i,v*s da si,ta&e ! ,as "ista+e,s de c=di+os em assemb"#. Para co,fi+%rar o /Q basta %sar o coma,do: set disassem;lQ-"lavor intel
5 cato * $%e toda ve $%e for %sar o gdb vocJ deveria di+itar essa "i,a. Fe"ime,te e&iste %ma ma,eira de e&ec%tar certos coma,dos a%tomaticame,te sempre $%e o +db for i,iciado. Qasta co"oc-"os ,o ar$%ivo de co,fi+%raão W9gdbinit: echo set disassem;lQ-"lavor intel > /.gd;init3f
4uas maneiras de listar c%digo assembl no gdb 6%po,a $%e vocJ $%eira "istar o famoso c=di+o e""o 8or"d;: /* test.c */ #include int main(int argc, char *argv[]) !rint"($ello, orld.'n) return -----%<----- corte aqui ----%<---- gcc -g -0 #es#.c -o #es#
ma ve compi"ado com a opão -+ do +cc vocJ pode carre+ar o e&ec%tve" e "ist-"o %sa,do o coma,do disassemble Go% a versão abreviada: disas;H: gd$ ./#es# 9 (gd;) disas main Jum! o" assem;ler code "or "unction @AA <=> su; @AAA <=A> mov @AAf <=f> call @AAe <=BA> @or @AAB <=BS> add @AABA <=L> ret 4nd o" assem;ler dum!.
main rs!,@R edi,@Acc @A3e ea@,ea@ rs!,@R
/Q for,ecer %ma "ista+em co,te,do o e,dereo das i,str%es o offset re"ativo a partir do i, su; rs!,@R !rint"($ello'n) @AAA <=A> mov edi,@Acc S _
@AAf return @AAe @AAB @AABA
<=f>
call
<=BA> @or <=BS> add <=L> ret
@A3e ea@,ea@ rs!,@R
amb*m podemos acresce,tar o co,teMdo bi,rio das i,str%es %sa,do a opão Xr: 39 Nepare $%e o ar$%ivo W9gdbinit pode e&istir em se% sistema. 6e este for o caso mofidi$%e-o com se% editor de te&tos favorito.
7(
(gd;) disas /r main Jum! o" assem;ler code "or "unction main @AA <=> AR R3 ec R @AAA <=A> ;" cc A @AAf <=f> eR dL "" "" "" @AAe <=BA> 3B c @AAB <=BS> AR R3 cA R @AABA <=L> c3
su; mov call @or add ret
rs!,@R edi,@Acc @A3e ea@,ea@ rs!,@R
Listando registradores ma ve $%e s%a sessão de deb%++i,+ est em a,dame,to vocJ pode "istar os re+istradores com o coma,do i,fo;. )&istem d%as ma,eiras: i,fo re+; e i,fo a""-re+;. @em todos os re+istradores são "istados. @oN6P primeiro caso vocJN?P obter os re+istradores de %so +era" NQU NCU N/U N/? NQP N' at* N1> e )FL!6; G,ão NFL!6E AasN!U ,ão importa $%e este N6? * esse,cia"me,te )FL!6 com os 32 bits s%periores eradosEH. @o se+%,do caso os re+istradores de po,to f"%t%a,te e 6?A/ G66) o% !VU depe,de,do de s%a ar$%itet%raH são "istados tamb*m: #include int "(int @) return L*@ int main(int argc, char *argv[]) !rint"(%d'n, "(L)) return
Compi"a,do e i,icia,do ,ossa sessão de deb%++i,+: gcc gd$ -01 #es#-g #es#.c -o #es# Heading sQm;ols "rom test...done. (gd;) $ & Mrea!oint B at @Ac "ile test.c, line . (gd;) r Ftarting !rogram test Mrea!oint B, " (@L) at test.c return L*@ (gd;) i%&o reg ra@ @_""""_ddfecR BA_3_3BRRAARR r;@ @ rc@ @ rd@ @_"""""""eBcR BA_3_ARR3A_fL rsi @_"""""""eB;R BA_3_ARR3A__S rdi @L L r;! @_"""""""e; @_"""""""e; rs! @_"""""""e; @_"""""""e; rR @_""""_ddR3 BA_3_3BR__3_S rf @_""""_de;3B BA_3_3BfLBS rB @ rBB @_""""_aS"d; BA_3_3AR3A3A rBL @AA ABf3LR rB3 @_"""""""eB; BA_3_ARR3A_SR rBA @ rB @ ri! @AB3 @AB3 <"=_> e"lags @LS [ K NK ] cs @33 B ss @L; A3 ds @ es @ "s @ gs @
77
(gd;) disas & Jum! o" assem;ler code "or "unction " > @Ac <=> lea ea@,[rdi=rdi*B] @A" <=3> ret 4nd o" assem;ler dum!.
Como era esperado +raas S co,ve,ão de camada o re+istrador N/? co,t*m o primeiro parKmetro da camada para a f%,ão fGH - marcado em verme"o para camar s%a ate,ão. Nepare $%e ,o disassemb"er da f%,ão o breaDpoi,t est marcado com ;. 5%tra ma,eira de i,specio,ar o co,teMdo de %m re+istrador * %sa,do o coma,do &rint e o ,ome do re+istrador precedido com ` como `ra&.
7xaminando a mem%ria com o H4J !"*m do disassemb"er e da possibi"idade de e&ami,ar o co,teMdo dos re+istradores o coma,do &; do /Q ,os permite eUami,ar %ma re+ião da mem=ria. Qasta for,ecer o formato a $%a,tidade e o e,dereo Go% o s
@"" @ @"" @B
@_" @ @_" @
@ @ @ @
@ @ @ @
sei o re+istrador N6P como e,dereo base para o e&ame pedi,do para e&ami,ar 32 b#tes e mostr-"os em e&adecima" G&X32b&H. Podemos %sar as "etras YbY Y8Y YY e Y$Y para QW) 5N/ /5N/ Ga "etra YdY * %sada para decima";H e R5N/ respectivame,te. 5 Y&Y fi,a" di $%e os va"ores devem ser impressos em e&adecima". Podemos %sar %m tama,o e a "etra YsY para mostrar o b"oco em formato de stri,+. !s "etras YdY e Y%Y mostram os dados em decima" com e sem si,a" respectivame,te. ! "etra YtY mostra os va"ores em bi,rio Ga "etra * devido a pa"avra 5H. ! o%tra formataão i,teressa,te * YfY para po,to f"%t%a,te Gembora para mim ,ão estea c"aro $%a" * o formato rea": .loat double o% long doubleBH.
Obtendo listagens em assembl usando o HCC m rec%rso m%ito Mti" para a,"ise do se% pr=prio c=di+o * pedir ao compi"ador $%e +ere %ma "ista+em em assemb"#. @o CC vocJ pode faer isso %sa,do a opão Y-6Y. @o Vis%a" C basta %sar a opão Y-FaY com o CL.)U). Ai,a preferJ,cia ,o caso do CC * +erar "ista+e,s ,o esti"o ?,te" ao i,v*s do esti"o !. ?sso pode ser obtido adicio,a,do ) 5%tra o CCcoisa ai,daimporta,te permite acresce,tar S "ista+em +erada %sa,do-se aa opão opão Y-masmi,te"Y. Y-fverbose-asmY. * dier aocome,trios compi"ador $%a" ar$%itet%ra ser %sada para otimiaão. ?sso * feito atrav*s da opão Y-marcY. )% prefiro %sar marc,ative; para $%e o CC %se como processador a"vo o da m$%i,a em $%e o c=di+o foi compi"ado. 6e se% processador s%porta a e&te,são !VU o% !VU->12 por e&emp"o o CC %sar as i,str%es este,didas. @%m e&ec%tve" de prod%ão vocJ pode $%erer esco"er %m processador o% ar$%itet%ra espec
)is %m e&emp"o de +eraão de "ista+em assemb"# %sa,do o CC para o se+%i,te c=di+o: /* list.c */ #include /* Z estrutura de nosso n?. */ struct nodeEs struct nodeEs *ne@t void *data si6eEt si6e /* Nnsere um n? de!ois do n? dado !or nodeE!tr. */ struct nodeEs *NnsertUodeZ"ter(struct nodeEs *nodeE!tr, void *data, si6eEt si6e) struct nodeEs *nenode i" ((nenode (struct nodeEs *)malloc(si6eo"(struct nodeEs))) & UWGG) nenode->ne@t nodeE!tr->ne@t nenode->data data nenode->si6e si6e nodeE!tr->ne@t nenode return nenode -----%<----- corte aqui -----%<---- gcc -03 -march%a#i,e -S -masmi%#el -&,er$ose-asm lis#.c
! "ista+em abai&o compi"ada para %m processador i7-4770 fica mais o% me,os assim Ga"is para todos os mode"os de processadores $%e s%portam &'(-(4H: 4ntrada HJN nodeE!tr, HFN data HJI si6e Hetorna HZI. NnsertUodeZ"ter Falva os !ar^metros em HBL, HM e HMI !orque esses registradores t5m que ser !reservados entre chamadas de "unT\es. Z "unTOo malloc(), a;ai@o, !ode modi"icar HJN, HFN e HJI& !ush rBL mov rBL,rsi # data, data !ush r;! mov r;!,rd@ # si6e, si6e !ush r;@ mov r;@,rdi # nodeE!tr, nodeE!tr Zloca LA ;Qtes (si6eo"(struct nodeEs)). mov edi,LA call malloc test ra@,ra@ `e .insertEe@it mov mov mov mov mov
rd@,[r;@] [ra@=R],rBL [ra@=BS],r;! [ra@],rd@ [r;@],ra@
# neEnode Fe HZI UWGG, sai. # # # # #
J.LLB, nodeE!trE(J)->ne@t nenodeEA->data, data nenodeEA->si6e, si6e nenodeEA->ne@t, J.LLB nodeE!trE(J)->ne@t, nenode
.insertEe@it !o! r;@ !o! r;! !o! rBL ret
5s come,trios mais c"aros são co"ocados pe"o CC e os em verme"o são me%s. @ote $%e o si+,ificado de %ma i,str%ão o% referJ,cia S mem=ria * come,tada com o ,ome da varive" do c=di+o ori+i,a" em C refere,ciada o% %m ,ome es$%isito G* o caso de /.2>21 acimaH %sado para %ma varive" temporria. 5%tra ma,eira * pedir ao compi"ador $%e %se o 7U 1ssembler G!6H para +erar %ma "ista+em 79
mista co,te,do o se% c=di+o fo,te como come,trios. ?sso * feito adicio,a,do as opes 5g e 5%a,5 a/lnd ,o +cc e redirecio,a,do a sa
,ecessrio o %so da opão 5g para $%e o 7U 1ssembler te,a como mesc"ar o c=di+o fo,te em C com a "ista+em em assemb"#. ! "i,a de comado acima criar a"+o assim: ca# lis#.ls# B
."ile list.c .intelEsQnta@ no!re"i@ .te@t .Gte@t .!Lalign A,,B
L 3 A S
R f B Bins.c Lins.c 3ins.c Ains.c ins.c Sins.c _ins.c Rins.c fins.c Bins.c BBins.c BLins.c B3ins.c BB
BL B3 BA ABA B BS
.glo;l NnsertUodeZ"ter NnsertUodeZ"ter .GKMLA ."ile B ins.c **** /* insa"ter.c */ **** #include **** **** /* Z estrutura de nosso n?. */ **** struct nodeEs **** struct nodeEs *ne@t **** void *data **** si6eEt si6e **** **** **** /* Nnsere um n? de!ois do n? dado !or nodeE!tr. */ **** struct nodeEs *NnsertUodeZ"ter(struct nodeEs *nodeE!tr, void *data, si6eEt si6e) **** .loc B B3 .c"iEstart!roc .GG !ush rBL .c"iEde"Ec"aEo""set BS .c"iEo""set BL, -BS
L BRB_ AfRfKA
mov r;! rBL, rsi !ush .c"iEde"Ec"aEo""set LA L .c"iEo""set S, -LA LB S ARRfJ mov r;!, rd@ LL f 3 !ush r;@ L3 .c"iEde"Ec"aEo""set 3L LA .c"iEo""set 3, -3L L .loc B B3 LS a ARRfKM mov r;@, rdi BAins.c **** struct nodeEs *nenode Bins.c **** BSins.c **** i" ((nenode (struct nodeEs *)malloc(si6eo"(struct nodeEs))) & UWGG) L_ .loc B BS LR d MKBR mov edi, LA LR Lf .GGB 3 BL 4R call malloc 3 3B .GGL 3L B_ ARR test ra@, ra@ 33 Ba _ABB `e .GS B_ins.c **** Bf
3A
BRins.c
****
3 Bc ARRMB3 Bfins.c
****
3S 3_ B" ARfSR Lins.c **** 3R 3f L3 ARRfSRB BRins.c **** A AB L_ ARRfB
'0
nenode->ne@t nodeE!tr->ne@t .loc B BR mov rd@, pk2HJ DH [r;@] nenode->data data .loc B Bf mov pk2HJ DH [ra@=R], rBL nenode->si6e si6e .loc B L mov pk2HJ DH [ra@=BS], r;! nenode->data data .loc B BR mov pk2HJ DH [ra@], rd@
LBins.c
****
AL A3 La ARRf3 .GS **** **** **** ****
AA
LLins.c L3ins.c LAins.c Lins.c A AS Ld M A_ AR
nodeE!tr->ne@t nenode .loc B LB mov pk2HJ DH [r;@], ra@
return nenode
.loc B L !o! r;@ .c"iEde"Ec"aEo""set LA .GG3
Af Le J B
!o! r;! .c"iEde"Ec"aEo""set BS .GGA
L L" AB
!o! rBL .c"iEde"Ec"aEo""set R
3 A
3B 3
S _ f S SB SL S3 SA
.GG
ret .c"iEend!roc .GK4LA .Gete@t ."ile L ."ile 3 ."ile A ."ile ."ile S
/usr/li;/gcc/@RSESA-linu@-gnu/A.R/include/stdde".h /usr/include/@RSESA-linu@-gnu/;its/tQ!es.h /usr/include/li;io.h /usr/include/stdio.h /usr/include/malloc.h
! "ista+em em assemb"# * e&atame,te a mesma obtida com a opão -6. @o e,ta,to a "ista+em do c=di+o ori+ira" tamb*m * aprese,tada e de %ma forma bem co,f%sa Grepare ,os ,Mmeros das "i,asEH $%e a e,fase * ,o c=di+o em assemb"#... !s otimiaes feitas pe"o compi"ador te,dem a tor,ar a "eit%ra do c=di+o em C meio es$%isita. Pe"o me,os temos come,trio s die,do o $%e est se,do feito com o c=di+o e os ops. @este po,to vocJ pode se per+%,tar $%a" * a difere,a de %sar 5marc/Xnative afi,a" de co,tasB )m certos casos o compi"ador pode esco"er %sar por e&emp"o os re+istradores WAA G>12 bits o% 32 b#tesH. 6e tiv*ssemos mais %m va"or de (4 bits ,a estr%t%ra e $%is*ssemos er-"a comp"etame,te o compi"ador poderia esco"er faer a"+o assim: v!@or @mm, @mm, @mm vmovdqu [rdi],Qmm v6erou!!er
!o i,v*s de a"+o mais tradicio,a": @or mov mov mov mov
ea@,ea@ [rdi],ra@ [rdi=R],ra@ [rdi=BS],ra@ [rd@=LA],ra@
Sobre os endereços em listagens em assembl obtidas com obIdump ou HCC Co,sidere o pro+rami,a abai&o: /* test.c */ int @ 3 int "(int a) return a*@
!o compi"-"o e obtermos a "ista+em em assemb"# Gcom os c=di+os em e&adecima"H obtemos a"+o assim: gcc -03 -masm%a#i,e -c #es#.c -o #es#.o o$6d7mp -d -M i%#el #es#.o 9 Jisassem;lQ o" section .te@t <">
'1
S
R; mov ea@,Jk2HJ DH [ri!= " a" c_ imul ea@,edi f c3
@]
Aar$%ei em verme"o o pedao da i,str%ão A5V prob"emtica... )ssa i,str%ão est c"arame,te obte,do o va"or da varive" 4 $%e foi dec"arada como +"oba"... Aas como * $%e o compi"ador sabe $%e o e,dereo de"a * 0&0B )"e ,ão sabeE Para esse m=d%"o Geste ar$%ivo obetoH a varive" +"oba" 4 * co"ocada ,o se+me,to 9data "o+o ,o i,
l l l l l l l l g g
d" d d d d d d d K 2
*ZMF* test.c .te@t .te@t .data .data .;ss .;ss [email protected]elQ [email protected]elQ .note.CUW-stac .note.CUW-stac .ehE"rame .ehE"rame .comment .comment .te@t a " .data A @
@essa "ista+em da tabe"a de s
;sando o ma9e: 8azendo um bo lo. usando receitas !o i,v*s de compi"ar se%s c=di+os %m a %m cama,do o +cc e o ,asm vrias vees pode-se criar %ma receita; para coi,ar o bo"o todo de %ma ma,eira mais a%tomtica;. ?sso * feito com o %ti"itrio make. Com e"e vocJ cria %m ar$%ivo $%e co,t*m "itera"me,te receitas. )"as são compostas de re+ras e aes. VocJ s= precisa e,cadear as re+ras para $%e %ma depe,da da o%tra e as aes serão feitas ,a ordem correta. m e&emp"o para compi"ar o famoso /elloorld9c: helloorld helloorld.o gcc -o 0 1 helloorld.o helloorld.c gcc -c -o 0 <
Atenção: ! "i,a de coma,do tem $%e comear com %m caractere YtY G%m tab;H.
!$%i temos d%as receitas. ! primeira receita * a mais importa,te por$%e estabe"ece a cadeia de depe,dJ,cias... @o e&emp"o acima a primeira receita ,os di $%e /elloorld depe,de de /elloorld9o. 6e /elloorld9o e&istir e,tão para faer /elloorld a "i,a de coma,do co,te,do o +cc ser camada para "i,Dar o ar$%ivo obeto cria,do o e&ec%tve". 5s macros ` e `u são '2
ata"os para o a"vo G`H e as depe,dJ,cias G`uH. 5 maDe s%bstit%ir esses macros com os ,omes de ar$%ivos corretos co,tidos ,a receita. @ote $%e a primeira receita depe,de de /elloorld9o. ! se+%,da receita ,os di como e"e * feito. )"e depe,de de /elloorld9c. ! "i,a de coma,do abai&o dessa receita fa; o /elloorld9o $%e * a depe,dJ,cia de /elloorld. ! difere,a e,tre ` e `u * $%e o primeiro co,t*m os ,omes das depe,dJ,cias separadame,te. 5 se+%,do co,t*m todas as depe,dJ,cias ,%ma M,ica stri,+. ?sso * Mti" ,%m 'ake.ile assim: test testB.o testL.o test3.o gcc -o 0 1 %.o %.c gcc -c -o 0 <
!$%i todo ar$%ivo com e&te,são Y.oY ser feito; a partir de %m ar$%ivo correspo,de,te com e&te,são Y.cY. 5% sea o +cc ser camado vrias vees %ma para cada ar$%ivo Y.cY ,o diret=rio corre,te. ma ve $%e te,amos Yteste1.oY Yteste2.oY e Yteste3.oY o +cc ser camado de ,ovo para "i,Dar os 3 obetos. 5%tra coisa i,teressa,te do maDe * $%e as "i,as de coma,do das receitas podem ser omitidas. 5 %ti"itrio sabe o $%e faer ,a maioria dos casos. 6e crissemos a"+o como: test testB.o testL.o test3.o gcc -o 0 1 %.o %.c
! si,ta&e Yq.oY e Yq.cY * o e$%iva"e,te do ildcard Yk.oY e Yk.cY. @o script acima o compi"ador +cc ser camado com a opão -c para criar os obetos $%e depe,dem m=d%"os!em C. ParaCC c%stomiar esse* comportame,to variveis dedos ambie,te. varive" ,os di $%a" o compi"ador C podemos $%e vai sera"terar %sado.a"+%mas Por defa%"t make %sa YccY $%e * %m "i,D simb="ico para +cc.
!s opes de compi"aão estão ,a varive" CFL!6. !ssim se $%is*ssemos compi"ar ,ossos c=di+os com a m&ima otimiaão poder
! "ista de obetos do $%a" YtestY depe,de foi co"ocada ,%ma varive" bem como as opes Y-53 -marc,ativeY foram adicio,adas S varive" pree&iste,te CFL!6. !o %sar `GvarH faemos %ma s%bstit%ião "itera" da varive" ,o coma,do o% ,a receita. 5 make tamb*m permite receitas $%e te,am como a"vo %m fa"so ar$%ivo. Por e&emp"o: KGZCF = -23 -marchnative 2M4DF testB.o testL.o test3.o test (2M4DF) () -o 0 1 %.o %.c clean rm *.o
'3
5 a"vo clean ,ão * a receita pri,cipa" e ,ão est ,a "ista de depe,dJ,cias. )"e amais ser e&ec%tado $%a,do camarmos make sem parKmetros. Aas podemos camar make passa,do o a"vo deseado: mae clean
pr%de,te i,formar ao make $%e esse * %m a"vo de ara$%e; G &/ony targetH %sa,do a diretiva .PI5@W: KGZCF = -23 -marchnative 2M4DF testB.o testL.o test3.o # Ji6 ao mae que clean 7 um alvo im!ostor. .$2U clean test (2M4DF) () -o 0 1 %.o %.c clean rm *.o
)sses &/ony targets são Mteis para rea"iarmos operaes difere,tes e at* mesmo $%a,to ,osso script e&i+e mM"tip"os a"vos. Lembre-se $%e a primeira receita * a $%e estabe"ece toda a cadeia de depe,dJ,cias. !ssim se tivermos $%e compi"ar %m Ye""oY e %m Yb#eY por e&emp"o poder
! receita pri,cipa" Ya""Y estabe"ece $%e Ye""oY e Yb#eY tJm $%e ser co,str%
5 "i,Der ser camado ,%m se"" e o YstripY em o%tro ,a se$%J,cia. ?sso pode ser prob"emtico se vocJ $%iser por %ma $%estão de esti"o %sar mais $%e %ma "i,a. @o make %sar vrias "i,as para serem i,terpretadas pe"o mesmo se"" e&i+e o %so do caractere YY ,o fi,a" da "i,a. !i,da $%e make tem macros comea,do com ` se se% coma,do %sa variveis de ambie,te vocJ deve faer as s%bstit%ies %sa,do ``: hello hello.o () -o 0 1 -lm # Zs linhas a;ai@o sOo e@ecutadas num mesmo shell.
'4
i" [ -" 0 ] then ' echo Zrquivo 0 com!ilado com sucesso em kJ. ' "i
'>
'(
Capítulo .! ,edindo per)ormance )&istem a"+%mas i,terpretaes para a pa"avra performa,ce; ap"icveis ao co,te&to da e&ec%ão de soft8are. ! M,ica i,terpretaão $%e i,teressa a$%i * si,h,ima de ve"ocidade;. !o dier ve"ocidade; vocJ pode pe,sar isso como o ,Mmero de i,str%es $%e o processador e&ec%tar ,%ma %,idade de tempo o% ai,da $%a,to tempo o processador "eva para e&ec%tar %m co,%,to de i,str%es. %ma apro&imaão "=+ica. ?,fe"ime,te * impraticve".
Ciclos de m(uina e ciclos de cloc9 odo o tempo +asto ,a e&ec%ão de %ma M,ica i,str%ão * composto de %m co,%,to de cic"os camado de cic"os de m$%i,a;. m cic"o de m$%i,a * por s%a ve composto de %m co,%,to de cic"os de c"ocD e %m cic"o de c"ocD; * per
'7
?,t%ião ,este caso * o"ar para %ma roti,a Gem assemb"#H e ava"iar apro&imadame,te o tempo +asto com base ,a comp"e&idade das i,str%es. ?sso * Mti" ao a,a"isar o% dese,vo"ver %m rasc%,o da roti,a deseada. Como em $%a"$%er coisa ,ossa i,t%ião pode estar tota"me,te errada. Precisamos de evidJ,cias. ) a ma,eira mais simp"es de sabermos $%a,tos cic"os em m*dia %ma roti,a vai +astar * medi,do. @esse cap
Como medir, Para determi,ar a ve"ocidade de %ma f%,ão * ,ecessrio medir a $%a,tidade de cic"os de m$%i,a $%e estão se,do +astos. )&istem d%as ma,eiras de faermos isso: 1. Via ard8are: sa,do e$%ipame,tos como ?C)s G?, Circ% it )m%"atorsH eXo% !,a" isadores L=+icos\ 2. Via soft8are: sa,do co,tadores i,ter,os NC GNea" ime C"ocD T o re"=+io do comp%tadorH o% a"+%m &ro.iler especia"iado como o Intel 0une. ?C)s42 e !,a"isadores L=+icos são caros e e&i+em co,ecime,to e e&periJ,cia com e"etrh,ica. Para a maioria de ,=s pobres mortais esses e$%ipame,tos tJm c%rso proibitivos. @os processadores at%ais e&istem rec%rsos de medião de performa,ce camados de &er.ormance counters. 6= $%e e"es s= estão dispo, a,os de co,ta+em desde o mome,to $%e o processador foi co"ocado em f%,cio,ame,toE 5 e&emp"o abai&o mostra como obter o va"or %sa,do a f%,ão i,tr<,seca OOrdtsc: /* rdtscB.c */ #include #include <@RSintrin.h> /* Erdtsc() tem o !rot?ti!o unsigned long long Erdtsc(void) */ int main(int argc, char *argv[]) !rint"(iclos %lu'n, EErdtsc()) return -----%<----- corte aqui -----%<---- gcc -03 -o rd#sc1 rd#sc1.c ./rd#sc1 iclos RL3RALSSBL_
garantido $%e a i,str%ão N/6C retor,e %m va"or M,ico toda ve $%e for camada Gmesmo $%e 42 )&iste %m a i,s tr%ão não documentada ,os processadores ?,te" Gmas doc%me,tada ,os processadores !A/H camada ?ceQP. rata-se de %m breaDpoi,t; por ard8are mas ,em va"e a pe,a est%d-"aE
''
sea camada em treads difere,tesH:
Aumentando a precisão da medida 5s processadores moder,os te,dem a e&ec%tar i,str%es fora de ordem;. Pode parecer estra,o $%e o co,ceito de %m pro+rama * %stame,te e&ec%ão de i,str%es de forma se$%e,cia" %ma depois da o%tra. 6= $%e a"+%mas vees ,ão fa m%ita difere,a do po,to de vista f%,cio,a" $%e %ma se$%J,cia de i,str%es sea a"terada. ) essa modificaão de ordem pode res%"tar ,%m a%me,to co,siderve" de performa,ce. )is %m e&emp"o. Co,sidere o pe$%e,o fra+me,to de c=di+o abai&o: loo! mov al,[rsi] mov inc [rdi],al rdi inc rsi dec rc@ `n6 loo!
de!end5ncia de ZG, acima.
9
Lembre-se $%e podemos ter d%as o% mais i,str%es se,do e&ec%tadas ao mesmo tempo; ,o mesmo processador "=+ico. @o e&emp"o acima * =bvio $%e as d%as primeiras i,str% es terão $%e ser e&ec%tadas se$%e,cia"me,te por$%e a se+%,da depe,de da at%a"iaão de !L feita ,a primeira i,str%ão. 5 processador esperto como * poder reorde,ar as i,str%es assim: loo! mov al,[rsi] inc rsi mov [rdi],al inc rdi dec rc@ `n6 loo!
He!are que essa instruTOo "oi reordenada.
6e o processador tem a capacidade de e&ec%tar d%as i,str%es sim%"ta,eame,te 43 * evide,te $%e o se+%,do "oop +asta 3 cic"os de m$%i,a e,$%a,to o primeiro e&ec%ta em 4. ?sso ,os d %m a%me,to de performa,ce de 2>q Go% sea o se+%,do "oop * e&ec%tado em 7>q do tempo do primeiroH. $%e i,str%es podem ser reorde,adas ,a te,tativa de a%me,tar a performa,ce o c=di+o sob teste pode ser reorde,ado i,c"%sive co"oca,do i,str%es antes o% depois das "eit%ras do co,tador de cic"os de c"ocD. evide,te $%e isso ,os dar medida errada do +asto de cic"os da$%i"o $%e $%eremos testar. Fe"ime,te podemos %sar i,str%es $%e serializam o processador. 5 termo serializar si+,ifica $%e o processador esperar $%e todas as i,str%es pe,de,tes seam e&ec%tadas e s= e,tão co,ti,%ar o processame,to. ! maioria das i,str%es $%e seria"iam o processador s= podem ser e&ec%tadas em ,
43 Processadores baseados em ar$%itet%tas mais rece,tes T Ias8e"" por e&emp"o T tJm o pote,cia" de e&ec% tarem at* ' i,str%es sim%"ta,eame,teE
'9
/* Z vari8vel @, !assada !ara esse macro, deve ser do ti!o unsigned long long. */ #de"ine DFEH4ZJ(@) ' ' register unsigned int lo, hi ' ' EEasmEE EEvolatileEE ( ' m"ence ' rdtsc ' a (lo), d (hi) ) ' ' (@) ((unsigned long)hi << 3L) b ' (unsigned long)lo '
@o macro acima ,ão peri+o de mist%rar bits e,tre os va"ores das variveis lo e /i $%e os bits s%periores estarão erados Gde ,ovo: N/6C s= at%a"ia )!U e )/U mas era a porão s%perior de N!U e N/UH. 6= $%e esse c"c%"o adicio,a" pode m%ito bem ser co"ocado de,tro do b"oco assemb"# e se %sarmos %ma varive" long como retor,o * +ara,tido $%e N!U vai ser co"ocado ,e"a: #de"ine DFEH4ZJ(@) ' ' register unsigned long r ' ' EEasmEE EEvolatileEE ( ' m"ence ' rdtsc ' shll 3L,%%ed@ ' orl %%ed@,%%ea@X a (r) %rd@ ) '
Como N/6C a"tera i,c"%sive N/U * ,ecessrio co"oc-"o ,a "ista dos re+istradores preservados para dar %ma ca,ce ao CC de sa"v-"o se ,ecessrio. )ssas i,str%esserão e&tras 6IL e 5N reorde,adas depoisC!LL do AF)@C) * c"aro e"as provave"me,te e&ec%tadas em serão para"e"o com a i,str%ão da camada a sermas testada. Aesmo $%e a camada sea co"ocada inline em se% c=di+o essas i,str%es adicio,ais serão empare"adas com o%tras te,do m%ito po%ca i,f"%J,cia ,o va"or fi,a". ) mesmo $%e te,a e"as +astarão ape,as 1 cic"o de c"ocD. @ão se trata de +ra,des perdas... AF)@C) * %ma i,str%ão do 66)2. 6e se% processador for %m a,ti+o Pe,ti%m ??? o% se ,ão s%portar 66)2 vocJ poder $%erer troc-"a por CP?/ mas * ,ecessrio faer a"+%mas modificaes $%e CP?/ a"tera )!U )QU )CU e )/U precisamos co"ocar NQU e NCU ,a "ista de preservaão GN/U tamb*m mas por ca%sa de N/6CH: #de"ine DFEH4ZJ(@) ' ' register unsigned long r ' ' EEasmEE EEvolatileEE ( ' @or %%ea@, %%ea@ ' c!uid ' rdtsc ' shll 3L,%%ed@ ' orl %%ed@,%%ea@X a (r) %r;@, %rc@, %rd@ ) '
)&iste %m &a&er da ?,te" mostra,do $%e esse simp"es %so de "eit%ra do 6C pode ser prob"emtico $%a,do se mede a performa,ce de %ma f%,ão... 5 prob"ema * $%e a se+%,da camada +astar tempo e&ec%ta,do AF)@C) e os A5Vs fi,ais poderão estar fora de ordem. ! ?,te" recome,da formas de "eit%ra difere,tes. ma para o i,
90
EEasmEE EEvolatileEE ( Vm"enceX rdtsc shll 3L,%%rd@ orl %%rd@,%%ra@ a (r) %rd@ ) /* KunTOo a ser medida... */ "() EEasmEE EEvolatileEE ( rdtsc! shll 3L,%%rd@ orl %%rd@,%%ra@ a (rB) %rd@, %rc@ ) /* tsc conter8 a di"erenTa dos timestam!s. */ tsc rB r
5 se+%,do b"oco em assemb"# %sa a i,str%ão N/6CP $%e seria"ia o processador sem o overead da camada de AF)@C).
as. o gcc possui 'unç6es !intr$nsecas# para executar C-;)4 e F4@SC 6im poss%i... )"as estão "oca"iadas ,os eaders ia2Hintrin9/ e c&uid,/ mas como são camadas i,divid%ais * poss 9 unsigned long c, c int dummQ EmmEm"ence() c EErdtsc() "() /* EErdtsc!() usa um !onteiro !ara o;ter o valor do registrador NZ3LEDFEZWIE+FH. */ c EErdtsc!(dummQ) c - c 9 -----%<----- corte aqui -----%<---- c?digo !arcial gerado. om!ilado com -2L 9 m"ence rdtsc mov r;@,ra@ sal rd@,3L or r;@,rd@ call " rdtsc! sal rd@,3L or ra@,r;@ ra@,rd@ su; Ueste !onto, HZI 7 o contedo da vari8vel c.
R%e * %m c=di+o bem dece,te... 6= tome c%idado com as otimiaes do compi"ador. 6e for %sar o m&imo de otimiaes vocJ pode topar com o rearra,o de c=di+o $%e ,ão medir coisa a"+%ma Gas "eit%ras do 6C podem ser rearra,adasH. Para evitar isso recome,do $%e compi"e o c=di+o a ser testado em %m m=d%"o 91
separado e %se a opão de otimiaão Y-53Y. o c=di+o $%e co,t*m as camadas Ss f%,es i,tr<,secas OmmO.ence OOrdtsc e OOrdtsc& ,%m m=d%"o com a otimiaão Y-50Y.
el"orando a medição de per'ormance R%a,do vocJ bri,car %m bocado com a medião de cic"os de c"ocD perceber $%e para %ma mesma f%,ão sob teste a co,ta+em de cic"os * difere,te em cada medida. ?sso * perfeitame,te e&p"icve" +raas ao traba"o feito pe"o processador ao +ere,ciar tarefas p+i,as cace i,terr%pes etc. 5% sea o va"or $%e vocJ est medi,do ,%,ca ser e&ato 44. Como precisamos obter %m si+,ificado a partir dos va"ores "idos e ,ão temos e&atidão ,ada mais %sto $%e %sar o rec%rso da estatstica. ) o meio mais simp"es de obter si+,ificado de %m co,%,to de va"ores * o"ar para a m*dia. 6e te,o >0 va"ores "i+eirame,te difere,tes posso dier $%e %m va"or M,ico represe,ta,do a m*dia desses va"ores * a$%i"o $%e proc%ro. Para f%,es pe$%e,as %ma ma,eira de obter %ma boa m*dia * medir a e&ec%ão de diversas camadas S mesma f%,ão. ! medião a,terior poderia ser feita assim: 9 unsigned long c, cB int dummQ EmmEm"ence() c EErdtsc() /* KunTOo "() e@ecutada ve6es& */ "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() "() cL EErdtsc!(dummQ)
"() "() "() "() "()
"() "() "() "() "()
/* Nm!rime a m7dia sim!les de medidas& */ !rint"(iclos de cloc %lu'n, ((cL cB) / )) 9
6%bstit%ir as >0 camadas e&p" --i) "()
5 "oop ,ão ser dese,ro"ado;. Pe"o me,os ,ão tota"me,teE mais provve" $%e vocJ acabe com %m c=di+o assim: mov e;@, .GB call " dec e;@ `g .GB 9
!o i,v*s de >0 camadas vocJ acabar adicio,a,do %ma i,icia"iaão Gde )QUH >0 decreme,tos e 49 sa"tos co,dicio,ais ,o me"or dos casos... !ssim s%a medião ,ão ser somente da f%,ão mas do c=di+o de co,tro"e do "oop tamb*m. ) assim vocJ d ade%s S precisão $%e $%eria ,a mediãoE
O clculo do gan"o de per'ormance Para perma,ecermos ,a mesma si,to,ia o c"c%"o do +a,o de performa,ce sempre * feito em re"aão a a"+%ma roti,a ori+i,a" $%e s%postame,te * mais "e,ta $%e a roti,a otimiada. ! re"aão * esta: 44 @o apJ,dice Q mostro %m eito de a%me,tar a precisão das medidas.
92
5,de 7 * o +a,o perce,t%a" da roti,a otimiada em re"aão S roti,a ori+i,a". 6%po,a $%e a f%,ão ori+i,a" +aste 1000 cic"os de c"ocD e $%e a roti,a otimiada +aste 100. emos:
5% sea Go% temos %m +a,o de forma performa,ce f%,ão de 900q em re"aão S f%,ão ori+i,a" ve,do de o%tra Fsrcinal ,a * 10 veesotimiada mais "e,taEH. ) se tiv*ssemos o co,trrioB 6e a roti,a otimiada; +astasse mais cic"os $%e a roti,a ori+i,a";B 6%po,a $%e Fsrcinal +astasse 100 cic"os e Fotimizada 12>. 5 va"or de ser de -2>q $%e * e&atame,te a perda de performa,ce da roti,a otimiada; G,ote o va"or ,e+ativoEH:
c"aro $%e para %ma medida estat
!co,tece $%e essa variaão G07'qH * tão pe$%e,a $%e ,ão va"e o esforo. )rros me,ores $%e %,s 2q podem ser desco,siderados... Aas s%po,a $%e te,amos 3 medidas: 1300 200 e '00. 5 va"or m*dio ser de cerca de 7(7 e o erro re"ativo ser de w(9>q. m erro demasiadame,te +ra,de. @este caso va"e a pe,a %sar a m*dia4>... oda ve $%e formos comparar performa,ce essa * a re+ra do o+o: Aedimos a $%a,tidade de cic"os de c"ocD de d%as roti,as a ori+i,a" e a otimiada e ap"icamos a form%"a acima para obter o +a,o o% a perda. Famos isso com vrios medidas e %samos a m*dia para ,os orie,tarmos co,sidera,do a fai&a de erro das medies...
Kuando um gan"o !vale pena#, VocJ ver a"+%mas vees $%e descarto va"ores pe$%e,os de +a,o como despre o +a,o de performa,ce * de apro&imadame,te 4.3q. 5 va"or perce,t%a" * pe$%e,o mas ,ão * some,te e"e o ava"iado. 5 deta"e * $%e o%ve %m +a,o de ape,as > cic"os de c"ocDE 6e o +a,o re"ativo for pe$%e,o e o +a,o abso"%to tamb*m for e,tão descarto esse s%posto +a,o co,sidera,do-o despre Pode ser i,ter essa,te empre+ar %ma a,"ise estat
93
mesmo mas o +a,o abso"%to pode ser i,teressa,te ,o caso dessa roti,a otimiada estar se,do %sada de,tro de %m "oop. 5s dois va"ores tJm $%e ser pesados e tamb*m as circ%,stK,cias... @ão va"e S pe,a %sar %ma versão otimiada; de %ma roti,a $%e ser e&ec%tada ape,as %ma ve $%a,do o +a,o re"ativo * pe$%e,o mas va"e S pe,a %s-"a $%a,do o +a,o abso"%to * +ra,de; e essa roti,a * %sada de,tro de %m "oop o% * camada diversas vees.
;sando !per'# para medir per'ormance Li,%& dispo,ibi"ia %ma ferrame,ta por "i,a de coma,do $%e permite %sar diversos &er.ormance counters. !"*m dos cic"os +astos por %ma roti,a vocJ pode medir cac/e misses &age misses erros ,a predião dos branc/es etc. 5 ,osso c=di+o de teste ficaria simp"esme,te assim: /* test.c */ e@tern void "(void) /* rotina so; teste. */ int main(int argc, char *argv[]) "() return
!o %sar &er. vocJ ,ão mede a performa,ce de %ma roti,a espec
#
# ,ff Ws utili6ed ,3AR j/sec
c!u-migrations , +/sec j/sec BB_ !age-"aults ## ,RB3 ARf.LAL cQcles # 3,AB C$6 stalled-cQcles-"rontend stalled-cQcles-;acend A_.ABB instructions # ,R3 insns !er cQcle __.BLB ;ranches # 3S,B3 +/sec L.AB ;ranch-misses # 3,BB% o" all ;ranches ,LALAB seconds time ela!sed
( =- ,_L% ) ( =-B,% ) ( =-
,R% )
( =- ,3% ) ( =- ,L3% ) ( =- A,B% ) ( =-
B,% )
5 pro+rama YtestY e&ec%tado 20 vees Gopão Y-r 20YH +asto% em m*dia 4'2242 cic"os de c"ocD e&ec%to% 407411 i,str%es fe 77121 sa"tos. @esse perc%rso $%e d%ro% ape,as 240 s ocorreram 117 &age .aults e 2401 branc/ misses. Aas ,ote foi o pro+rama como %m todo i,c"%i,do as roti,as de i,icia"iaão e fi,a"iaão da libc. c"aro $%e vocJ pode te,tar desco,tar os va"ores obtidos por %m pro+rama $%e ,ão fa ,ada. Aas %m pro+rama $%e ,ão fa ,ada ,ão tem m%itas i,icia"iaes e fi,a"iaes para faer temB 5 %ti"itrio &er. * m%ito bom para dar %ma id*ia do $%e est aco,tece,do. )stamos i,teressados ,a performa,ce de roti,as ,ão do pro+rama +era". ?sso si+,ifica $%e o m*todo %sa,do 6C]N)!/ * mais Mti" ,este co,te&to. Aesmo se,do mais impreciso...
94
Capítulo 8! /timi0aç1es 2autom3ticas Compi"adores C e C moder,os co,se+%em me"orar m%ito o c=di+o criado pe"o pro+ramador %sa,do %ma s*rie de a"+oritmos de otimiaão reor+a,ia,do o c=di+o fi,a". !$%i e% vo% te mostrar a"+%mas das otimiaes a%tomticas; rea"iadas por esses compi"adores.
*$veis de otimização )&istem dMias de otimiaes $%e podem ser abi"itadas ,o compi"ador. ),te,der e co,s%"tar toda as possibi"idades * %ma tarefa ca,sativa. Para evitar o ca,sao o compi"ador dispo,ibi"ia ( co,%,tos de otimiaes abi"itadas pe"as opes Y-50Y Y-51Y Y-5sY Y-52Y Y-53Y Y-5fastY. !s opes estão "istadas a$%i ,a ordem em $%e +eram c=di+o do me,os otimiado ao mais otimiado. ! opão Y-50Y criar o c=di+o mais p%ro; poss
!Common Subexpression 7limination#
Nepare $%e parte das d%as e&presses tJm em com%m a s%b-e&pressão 2 k a 3 k b;. !o abi"itar C6) o compi"ador criar c=di+o e$%iva"e,te a isto: Etm! L * a = 3 * ; @ Etm! = c Q Etm! = d
9>
5 +a,o de performa,ce * =bvio: !o i,v*s de $%atro m%"tip"icaes e $%atro adies teremos d%as m%"tip"icaes e trJs adies. 5 +a,o de performa,ce pode ce+ar a perto de 100qE 5%tro efeito co"atera" * a pote,cia" dimi,%ião do c=di+o. C6) a+ressivo pode ser %m prob"ema ao %sar ,ossa roti,a de obte,ão do 6C. )m a"+%,s casos o compi"ador pode e,te,der $%e a camada S 6C]N)!/ e o c"c%"o e,vo"ve,do a mesma varive" * %ma C6) e simp"esme,te e"imi,ar %ma das camadas. Por isso %so a opão -51 o% -52 o% at* Y50Y ,a compi"aão do c=di+o testador.
4esenrolamento de loops 5%tra otimiaão simp"es. 6e vocJ precisa camar %ma f%,ão $%atro vees para faci"itar a codificaão vocJ poderia faer a"+o assim: "or (i i < A i==) JoFomething()
!o ver a"+o assim o compi"ador poder dese,ro"ar esse "oop e"imi,a,do-o comp"etame,te e +erar $%atro camadas para Do(omet/ing>). )ste * o ce,rio mais =bvio. @o e,ta,to o compi"ador pode ser mais esperto com "oops com mais iteraes. 6%po,a $%e ao i,v*s de 4 te,amos 400. 5 compi"ador poder esco"er faer %m dese,ro"ame,to parcia". !"+o mais o% me,os assim: /* Fu!onha que esse se`a o loo! srcinal. * / "or (i i < A i==) JoFomething() /* 2 com!ilador !oderia su;stituir !or isso */ "or (i i < i==) JoFomething() JoFomething() JoFomething() JoFomething() JoFomething() JoFomething() JoFomething() JoFomething()
!$%i o compi"ador esco"e% co,ti,%ar com %m "oop para po%par o cace L1 mas dese,ro"-"o para $%e te,amos me,os sa"tos co,dicio,ais. /ese,ro"ame,to de "oops pode tor,ar se% c=di+o maior e ,ão me"orar ta,to assim a performa,ce por isso o compi"ador tem %m "imite para o des,ro"ame,to. 5 "imite * defi,ido de acordo com a ar$%itet%ra e parKmetros i,ter,os do compi"ador Gmas pode ser a%stadoH... odas as opes de otimiaão e&ceto pe"o ,
ovendo c%digo invariante de dentro de loops
! varive" Y&Y * ca"c%"ada 100 vees co,sidera,do os mesmos va"ores co,tidos ,as variveis YaY e YbY. Aas YaY e YbY ,ão são at%a"iadas de,tro do "oop... Poder
@ a = ; "or (i i < B i==) JoFomething(@)
7liminação de c%digo morto <4ead Code 7limination= s vees criamos roti,as $%e simp"esme,te amais serão e&ec%tadas. 5% $%a,do o são ,ão faem coisa a"+%ma. 5 compi"ador te,tar e"imi,ar esses c=di+os. )is a"+%,s e&emp"os: "or (i i < B i==)
/* loo! !rovavelmente ser8 eliminado. /
i" ( &) JoFomething()
/* JoFomething() `amais ser8 chamado. */
hile (B) JoFomething() JoFomething4lse()
/* JoFomething4lse() `amais ser8 chamado. */
5%tro e&emp"o $%e vocJ pode e,co,trar * o %so de f%,es $%e ,ão retor,am va"or a"+%m ,ão a"teram variveis +"obais. 5 compi"ador pode e"imi,ar essas f%,es em a"+%,s casos. Por e&emp"o: #include int "(int @, int Q) return @*Q void main(void) "(B, L) !uts(VoX)
R%a,do %samos %ma opão de otimiaão difer,t e de -50 o compi"ador vai ser "ivrar da camada para . sem pesta,ear. !i,da o%tro e&emp"o de c=di+o morto * o assi,a"ame,to de %ma varive" para si mesma. %m macete Mti" para evitar avisos de parKmetros ,ão %sados; em s%as roti,as. Por e&emp"o o c=di+o abai&o ta"ve te dJ esse tipo de aviso: int "(int @, int Q) return @=@
6e vocJ rea"me,te $%er $%e a f%,ão acima recebe dois parKmetros mas ,ão %se %m de"es evite o aviso fae,do assim: int "(int @, int Q) QQ return @=@
! atrib%ião de y para si mesmo ser e"imi,ada pe"o compi"ador e e"e ,ão pode rec"amar $%e vocJ ,ão %so% y...
7liminação de armazenamento morto <4ead Store 7limination= /o mesmo eito $%e c=di+o morto * descartado ,a otimiaão o ,ão %so de variveis dec"aradas tamb*m fa com $%e e"as seam descartadas $%a,do poss
estado dos f"a+s. @a ar$%itet%ra s%peresca"ar o processador %sa %m rec%rso estat
5 compi"ador te,de a +erar %m c=di+o mais o% me,os assim: cm! [condicao], `e .GB 9 .GB
@ote $%e o sa"to * feito se a comparaão for #alsaE Aas para aproveitar o branc/ &rediction do processador em "oops o compi"ador te,de a modifica a posião o,de a co,dião de parada de %m "oop * feita. Por e&emp"o: 9 hile (condicao) 9 -----%<----- corte aqui ----%<---- c?digo que voc5 es!era que o com!ilador crie cm! [condicao], `e .GB .GL 9 `m! .GL .GB -----%<----- corte aqui -----%<---- c?digo gerado !elo com!ilador `m! .GB .GL 9 .GB cm! [condicao], `ne .GL
@este caso * esperado $%e a comparaão sea verdadeira para cada iteraão do "oop. !ssim se o compi"ador ,ão te,tasse adivi,ar se sa"tos serão o% ,ão tomados mist%rar "oops e YifYs ca%saria %ma co,f%são dos diabos ,os a"+oritmos de branc/ &rediction do processador tor,a,do o c=di+o mais "e,to. )ssa adivi,aão; ,ão * perfeita. Podemos dar %ma mãoi,a ao compi"ador %sa,do %ma f%,ão emb%tida; camada OObuiltinOe4&ect. )"a * %sada para me"orar a adivi,aão do compi"ador co,siderave"me,te. Como e&emp"o s%po,a $%e esperemos $%e %ma co,dião de %m i. sea #alsa ,a maioria das vees. Poder
6e so%bermos $%e Y&Y ser positivo o% ero ,a maioria das vees o c=di+o acima a%dar o compi"ador a or+a,iar os sa"tos co,dicio,ais para aproveitar ao m&imo o branc/ &rediction. 5 Der,e" %sa d%as macros $%e por s%a ve %sam a f%,ão OObuiltinOe4&ect. rata-se de likely e unlikely: 9'
#de"ine lielQ(c) EE;uiltinEe@!ect(&&(c), B) #de"ine unlielQ(c) EE;uiltinEe@!ect(&&(c), )
)sses ,omes são mais i,t%itivos... likely pode ser trad%ido para possive"me,te;...
Simpli'icaç6es l%gicas 5 $%e vocJ espera $%e o compi"ador faa com e&presses como estaB Q a b (a ;)
@ão * evide,te mas a e&pressão acima * simp"ificada para simp"esme,te # a\;. 5 CC Ge tamb*m o%tros bo,s compi"adoresH rea"iam faci"me,te as se+%i,tes simp"ificaes "=+icas: Gpressãocompleta
x0
x0
y
bH Ga y
a a a a
Gpressãosimpli#icada
0 a a x0
a a
a a
a xbH GaybH Ga
a a
Ga Ga bH ycH
acH Gb y
GabHyGxacHyGbcH Ga xbH Gxa y bH
aBb:c bua 0abela +: (im&li.icaJKes l@gicas .eitas &elo com&ilador9
)ssas e o%tras simp"ificaes são esperadas do po,to de vista do compi"ador. )"as ,ão são v"idas ape,as para e&presses de atrib%ião mas tamb*m aco,tecem com os operadores "=+icos boo"ea,os Gyy e H. Por e&emp"o se tivermos: i" (((a < ) (; < ) (c < )) bb ((a < ) (; > ) (c < )) bb ((a > ) (; < ) (c < )) bb ((a > ) (; > ) (c < ))) JoFomething()
)sse mo,te de comparaes ser simp"ificado pe"o compi"ador para: i" (c < ) JoFomething()
)ste e&emp"o parece =bvio e esse rec%rso * bem i,teressa,te. Aas e"e pode ser prob"emtico se vocJ estiver "ida,do com dispositivos e&ter,os. Por e&emp"o: ma das roti,as do me% a,ti+o c%rso de assemb"# ti,a ,%ma das "ista+e,s a"+o assim: *;it!lane b
5 obetivo era "er o co,teMdo da mem=ria de v
or ;Qte [;it!lane],
?sso era %m passo ,ecessrio para at%a"iar os latc/es dos bit&lanes da mem=ria de v
Simpli'icação de 'unç6es recursivas 5 CC te,de a e"imi,ar as camadas rec%rsivas a%tomaticame,te. 5 c=di+o abai&o * famoso. rata-se do c"c%"o de fatoria": unsigned long "atorial(ungigned long @) i" (@ < ) return B return @*"atorial(@-B)
6em otimiaes o compi"ador criar c=di+o como o mostrado abai&o: "atorial su; rs!,R mov [rs!],rdi cm! qord [rs!], `g .GL mov ra@,B `m! .G3 .GL mov su; mov
ra@,[rs!] ra@,B rdi,ra@
call "actorial imul ra@,[rs!] .G3 add ret
usa a !ilha !ara arma6enamento tem!or8rio.
4is a chamada recursiva.
rs!,R
5 prob"ema com a rec%rsividade * $%e e"a co"oca pressão sobre a pi"a. Cada camada S .atorial acima %sa 1( b#tes da pi"a: 5ito b#tes para o parKmetro e oito para o e,dereo de retor,o co"ocado " pe"a i,str%ão C!LL. 6e passarmos %m parKmetro com va"or +i+a,tesco "o+o teremos %ma e&ceão de (tack ver.lo ,as mãos por ca%sa dos m%itos empi"ame,tos. 5 c=di+o +erado com a m&ima otimiaão ,ão tem $%ais$%er camadas rec%rsivas. 5 compi"ador tra,sforma o c=di+o ori+i,a" em a"+o assim: long "atorial(long @) long r B hile (@ > B) r * @-- return r
c"aro $%e certas rec%rsividades ,ão podem faci"me,te ser simp"ificadas. /e fato a"+%mas tJm simp"ificaes matematicame,te imposs
100
Auto vetorização
$%e temos 2>( i,teiros em cada %m dos arra#s o c=di+o +erado te,der a %sar vetoriaão com va"ores i,teiros G32 bitsH: " @or ea@,ea@ align A .GL movdqa @mm,[;=ra@] !addd @mm,[c=ra@] movdqa [a=ra@],@mm add ra@,BS cm! ra@,BLA `ne .GL re! ret
?sso e$%iva"e mais o% me,os ao c=di+o em C 4(: e@tern int a[LS], ;[LS], c[LS] void "(void) EEmBLRi *!a (EEmBLRi *)a, *!; (EEmBLRi *);, *!c (EEmBLRi *)c "or (i i < SA i==) *!a== EmmEaddEe!i3L(*!;==, *!c==)
Aas ate,ãoE 5 compi"ador ,ão te,tar vetoriar referJ,cias a arra#s se o tama,o do "oop ,ão for co,ecido de a,temão. ! f%,ão abai&o ,ão te,de a ser vetoriada: void "L(int *out, int *a, int *;, si6eEt count) hile (count--) out[count] a[count] = ;[count]
5 compi"ador ,ão tem como saber $%a" * o va"or de Yco%,tY de a,temãoE
Otimizaç6es atrav5s de pro'iling odas as otimiaes do compi"ador são feitas de ma,eira esttica sem "evar em co,ta a e&ec%ão 4( Ver cap
101
de .acto do c=di+o +erado. 5 compi"ador te,ta %sar esse co,%,to de re+ras para +erar o c=di+o
mais performtico poss
-march%a#i,e -&pro&ile-ge%era#e -o #es# #es#.c
B user user LL an S BB3_ test B user user BB3 an S BB3_ test.c B user user BA an S BBAL test.gcda -march%a#i,e -&pro&ile-7se -o #es# #es#.c
B user user SRB an B user user BB3 an B user user BA an
S BBAA test S BB3_ test.c S BBAL test.gcda
! opão Y-fprofi"e-+e,erateY i,eta c=di+o para co"er i,formaes do se% pro+rama e armae,-"o ,o ar$%ivo Y.+cdaY e por isso o e&ec%tve" ficar bem mais $%e deveria. !o compi"ar pe"a se+%,da ve %sa,do a opão Y-fprofi"e-%seY o compi"ador %sa essas i,formaes e otimia me"or o c=di+o +erado. !mbas as opes aceitam parKm etros i,forma,do o ,ome do ar$%ivo Y.+cdaY $%e por defa%"t tem o mesmo ,ome do ar$%ivo Y.cY.
102
Capítulo 5! Caces )ste cap
dados ori+i,a"me,te co,tidos ,a mem=ria N!A. 5 e&a+ero do pedao do s%bco,%,to; * proposita". R%ero dier $%e ape,as %m pedao pe$%e,o da mem=ria * copiado para os caces. ! e&istJ,cia dos caces deve-se ao fato de $%e a mem=ria N!A * "e,ta. ) tem $%e ser $%e mem=rias rpidas são m%ito caras. 5s caces e,tão são artif
Figura G: 1cesso Y mem@ria sem&re ! .eita &elos cac/es9
Processadores moder,os imp"eme,tam vrios ,( ^iQ. Por isso o resta,te do cap
A estrutura dos cac"es /ifere,te da mem=ria do sistema $%e * or+a,iada de ma,eira "i,ear com %m b#te atrs do o%tro a mem=ria do cace * or+a,iada em "i,as;. Cada "i,a tem a estr%t%ra $%e co,t*m bits de co,tro"e %sadostamb*m i,ter,ame,te pe"o processador. e"es determi,am a va"idade da "i,a... Co,t*m %ma eti$%eta; o% ta+;/e,tre se+%idao%tras de 32coisas a (4 b#tes de dados depe,de,do da ar$%itet%ra do processador47.
47 Vo% "idar com "i,a s de tama,o de (4 b#tes da$ %i pra fre,te. Proc essadores como i> e i7 tJm caces com "i,as desse tama,o ,orma"me,te.
103
Figura : Estrutura de uma lin/a do cac/e *9
)ssa ta+; ,ada mais * do $%e os bits s%periores do endereço #isico4' associado a %ma "i,a. 5 processador %sa essa ta+ para determi,ar se %m b"oco de mem=ria est co,tido ,o cace o% ,ão.
Figura H: Estrutura de um endereJo linear no conte4to do cac/e *9
! fi+%ra a,terior mostra como %m e,dereo fisico * i,terpretado pe"o cace. c"aro $%e o offset tem ape,as ( bits de tama,o G2 ((4H. 5 campo "i,a; especifica %ma das >12 "i,as do cace. ) o campo ta+; * a ide,tificaão $%e ser comparada com a respectiva "i,a ,o cace. 6e o e,dereo ,os d o ,Mmero da "i,a ,o cace ao te,tar acessar mem=ria a primeira coisa $%e o processador far * determi,ar se a "i,a * v"ida Ge"a pode ai,da ,ão ter sido %sada;EH e co,t*m a mesma ta+ do e,dereo. Caso a ta+ e&ista ,o cace se a "i,a for i,v"ida e"a ser carre+ada do cace L2 Ga mesma coisa aco,tece do cace L2 para o L3 se esse e&istir e do L3 para a mem=ria do sistemaH. 6e a "i,a for v"ida; mas a ta+ ,ão for a mesma e,tão a "i,a precisar ser trocada;. 5 co,teMdo at%a" ser escrito ,o cace de ,
4eterminando o taman"o de uma lin"a Pode ser Mti" o se% pro+rama saber o tama,o de %ma "i,a do cace L1. Para obtermos essa i,formaão basta %sa a i,str%ão CP?/: #include #include int main(int argc, char argv[]) unsigned int a, ;, c, d /* Z o!eraTOo @B com WNJ nos d8 in"ormaT\es so;re o cache GB. */ EEc!uid(B, a, ;, c, d)
4' Vea sobre e,dereo "i,ear; ,o cap
104
/* ;its BR de 4MI, multi!licados !or R dOo o tamanho da linha de cache GB. */ !rint"(GB cache line si6e %u ;Qtes).'n, (; @"") >> ) return
O dilema do alin"amento e,tar co,ter dados e c=di+o em %ma M,ica "i,a de cace * obviame,te %m fator decisivo para +ara,tir performa,ce. 6e se%s dados M"trapassam o "imite de %ma "i,a corre o risco das c=pias e,tre caces e a mem=ria f b#tes de tama,o mas os primeiros (0 b#tes esteam em %so ,a "i,a. !o co"ocar essa i,str%ão de > b#tes 4 de"es ficariam ,a "i,a v"ida do cace e o b#te e&cede,te ter $%e ficar ,%ma o%tra "i,a $%e pode o% ,ão estar carre+ada ,o cace... VocJ poderia pree,cer os 4 b#tes fi,ais dessa "i,a com @5Ps e co"ocar a pr=&ima i,str%ão ,a "i,a se+%i,te mas isso ca%sar o mesmo prob"ema e criar o%tro: eremos i,str%es i,Mteis $%e +astam tempoE Com dados ocorre o mesmo mas * mais co,tro"ve". 6%po,a $%e se% c=di+o %se %ma estr%t%ra assim: struct mQstructEs long a[_] char ;[] long d
/* S ;Qtes do o""set at7 . */ /* ;Qtes do o""set S at7 S. */ /* R ;Qtes do o""set SB at7 SR. (o!s& ru6a duas linhas&) */
!o dec"arar %ma varive" desse tipo se e"a estiver a"i,ada com o i,
/* S ;Qtes do o""set at7 . (linha B) */ /* R ;Qtes do o""set S at7 S3. (linha B) */ /* ;Qtes do o""set R at7 SL. (linha L) */
Vamos %sar d%as "i,as de $%a"$%er eito mas ao ,ão co"ocarmos %ma varive" parcia"me,te em cada %ma $%a,do %ma de"as for trocada; a o%tra poder co,ti,%ar v"ida. ),tão o di"ema * este: 6empre $%e for poss
ao "o,+o prao. 6= temos >12 "i,as dispo, b#tes Gesse * o "imite imposto pe"a ?,te" e pe"a !A/H. !ssim ,o caso dos c=di+os * mais Mti" o a"i,ame,to de 1( b#tes. ?sso ,ão si+,i fica $%e voc ẽ ,ão possa %sar a"i,ame,tos me,ores como %ma esp*ci e de a%ste fi,o... 5 compi"ador C te,ta a"i,ar "oops e i,
@o e&emp"o acima %samos dois a"i,ame,t os difere,tes. 5 i,
4ica para usar mel"or os cac"es>>> Aa,te,a se%s c=di+os e dados pe$%e,osE 6e p%der e,c%rtar se%s "oops para $%e caibam em %ma "i,a de cace ta,to me"or. 6e,ão proc%re ,ão co,s%mir m%itas "i,as. Lembre-se $%e a"*m do se% pro+rama e&iste o Der,e" device drivers scripts etc se,do e&ec%tadosE m c=di+o $%e tem %m "oop com tama,o de mais de 4 ^iQ 49 pode ca%sar s*rios prob"emas de performa,ce. @este caso (4 "i,as de cace terão $%e estar v"idas para todo o "oop. Aas de,tro do "oop podemos ter camadas para o%tras f%,es o $%e pode i,va"idar parte desses "i,as ca%sa,do a perda de ce,te,as o% mi"ares de cic"os de c"ocD. 49 5 motivo dos 4 ^iQ ficarão c"aros ,o cap
10(
)stea cie,te para o fato de $%e essa dica * impraticve" ,a maioria das vees mas * importa,te $%e sea se+%ida sempre $%e poss
Audaciosamente indo onde um bte Iamais esteve>>> Por ca%sa das fre$%e,tes trocas de "i,as e,tre os caces e a mem=ria o%tro co,ceito importa,te $%a,do "idamos com os caces * o de temporalidade. VocJ pode e,carar o f%,cio,ame,to dos caces sob o aspecto espacial Go tama,o de %ma "i,aH e temporal Go tempo em $%e os dados ficarão sob os c%idados do caceH. R%a,do a !A/ e a ?,te" i,corporaram 6?A/ ,os se%s processadores comearam tamb*m a preoc%parem-se em co,tro"ar a tempora"idade de b"ocos de dados co,tidos ,os caces. !o a%me,tar o tama,o dos re+istradores $%e precisam acessar variveis a"i,adas a pressão; ,os caces a%me,ta co,siderave"me,te. Pode ser Mti" dier ao processador $%e %ma "i,a deve ser ma,tida v"ida por mais tempo $%e o ,ecessrio evita,do a recar+a do cace cada ve $%e %m b"oco de 1( b#tes G66)H sea "ido o% +ravado. 5%tra ma,eira de e,carar a tempora"idade * o $%ão fci"; o processador pode es$%ecer; %ma "i,a de cace. 5 a%ste fi,o; da tempora"idade * feito em todos os ,
>igni#icado
PN)F)CI4
5,de 4 * %m va"or e,tre 0 e 3.
PN)F)CI@!
PN)F)CI
R%a,to me,or o va"or de 4 me,os es$%ec
,ecessrio tomar c%idado com a i,str%ão PN)F)CI... )mbora o a%ste fi,o sea Mti" em certas circ%,stK,cias evita,do +astos de cic"os de c"ocD ,a troca de "i,as isso pode co"ocar +ra,de pressão; ,o cace L1.
8unç6es inline e a saturação do cac"e R%a,do a"+%*m apre,de sobre f%,es inline ,as "i,+%a+e,s C e C te,de a %s-"as para +a,ar performa,ce. !fi,a" camadas e retor,o de f%,es +astam %,s 20 cic"os de c"osD. 5 prob"ema de ab%sar das f%,es i,"i,e * %stame,te a sat%raão do cace L1i. 107
6empre $%e %ma f%,ão i,"i,e * %sada o c=di+o da camada $%e era %m simp"es C!LL * s%bstit%
10'
Capítulo 7! ,emria 9irtual I a,os vi %ma boa a,a"o+ia a respeito de mem=ria virt%a";: m pa"ao te,ta e$%i"ibrar trJs o% mais bo"i,as co"oridas e,$%a,to as o+a ,o ar. /%as de"as estarão o tempo todo ,as mãos de"e mas as o%tras sempre estarão s%spe,sas. )ve,t%a"me,te %ma das bo"as $%e estava ,as mãos do pa"ao ir voar e %ma $%e estava voa,do cair em %ma das mãos. 5 pa"ao ,ão * capa de traba"ar com todas as bo"i,as ao mesmo tempo e,tão %ma de"as ter $%e ser o+ada; e rec%perada depois. Fica parece,do $%e o pa"ao est e$%i"ibra,do; trJs bo"i,as ,esse ato de ma"abarismo $%a,do ,a e"e est "ida,do sempre com d%as. mais o% me,os assim $%e f%,cio,a o meca,ismo de rea"idade &age sa&&ing. ),$%a,to o processador "ida com %ma porão da mem=ria o%tra pode ,ão estar fisicame,te prese,te.
Eirtualização de mem%ria Aem=ria * e,dereada como se fosse %m +ra,de arra#. m e,dereo * %m <,dice para esse arra#. R%a,do diemos $%e a mem=ria * virt%a" diemos $%e %m e,dereo ,ão apo,ta mais para a mem=ria fpace: 5 e,dereo * o mesmo $%e aparece ,o barrame,to de e,dereos do processador. o $%e * %sado para "er o co,teMdo de %m pe,te de mem=ria. • %ogical Address >pace : 5 e,dereo * obtido atrav*s do e,dereo base vi,do de %m descritor de se+me,to atrav*s de %m re+istrador se"etor de se+me,to $%e * adicio,ado a %m offset. ! ,ão ser $%e esteamos "ida,do com mem=ria virt%a" este espao * esse,cia"me,te o mesmo $%e o espao fpace: @este espao %m e,dereo * i,terpretado como %m va"or i,teiro $%e decomposto co,t*m <,dices para tabe"as de trad%ão de p+i,a e %m offset. )sse e,dereo * co,ecido como endereJo linear. $%e estamos "ida,do com oe f
-aginação VocJ ,ão "J %m "ivro de %ma ve s= "JB Faer isso * %m desafio at* pra a$%e"as pessoas com dom<,io abso"%to em "eit%ra di,Kmica;. Por isso %m "ivro * dividido em cap
fa com $%e vocJ possa passar de %m item a o%tro sem $%e te,a $%e vis%a"i-"os ,a tota"idade. ! a,a"o+ia * boa com a$%i"o $%e se% processador fa com o acesso S mem=ria... 5 virtual address s&ace * a tota"idade te=rica da mem=ria $%e pode ser %sada Go "ivro ,a a,a"o+iaH e essa mem=ria * dividida em p+i,as. Co,sidere %ma p+i,a como se,do %m b"oco com tama,o de 4 ^iQ. R%ero dier o processador se fier %so do rec%rso da pa+i,aão e"e dividir o virtual address s&ace ,esses b"o$%i,os. Cada p+i,a * mapeada ,%m co,%,to de tabe"as e a ma,ip%"aão dessas tabe"as s= * poss
Figura 2: EndereJo linear >2H bits)
R%a,do estamos "ida,do com o modo pa+i,ado; do processador o re+istrador de co,tro"e CN3 Page Direc tory 0able co,t*m Cada o e,dereo mem=ria de o%ma tabe"a f
Nepare ,a estr%t%rara de %m e,dereo "i,ear: 5s primeiros dois campos Gdiret=rio; e tabe"a;H são ,a verdade <,dices para e,tradas ,as tabe"as P/ e P. 5 <,dice para a P/ ,os for,ece %ma entrada &ara o diret@rio de &?gina GPage Directory Entry o% P/)H. /a mesma forma o <,dice para a P ,os for,ece %m P) GPage 0able EntryH. /e posse do e,dereo base da p+i,a obtida da P) adicio,a,do o offset co,ti do ,os 12 bits i,feriores do e,dereo "i,ear o processador obt*m o e,dereo f
-aginação e swapping Pa+i,aão * %ma coisa $%e e&iste desde a *poca dos fami+erados main.rames. ! ideia * %stame,te a de $%e mem=ria f0. @os a,ti+os mai,frames >0 @o caso dos a,ti+os main.rames a capacidade de mem=ria era de ape,as a"+%,s $%i"ob#tes G^iQEH.
110
a"+%mas dessas p+i,as eram armae,adas em fita; e o%tras eram mapeadas ,a mem=ria f
@abelas de paginação no modo x12&23 @o modo &'(-(4 essa estr%t%ra de s%bdiret=rios; foi este,dida: Cada tabe"a co,ti,%a te,do ,o m&imo 4 ^iQ mas as e,tradas a+ora tem (4 bits de tama,o. Por ca%sa disso cada tabe"a passa a ter >12 e,tradas e os <,dices ,o e,dereo "i,ear tJm 9 bits de tama,o. ) +raas S ,ecessidade de %m maior espao de e,dereame,to ao i,v*s de ape,as d%as tabe"as passamos a ter $%atro. ! primeira * camada PAL4 G Page 'a& *evel 6 0ableH. ! se+%,da P/P GPage Directory Pointer 0ableH a terceira e a $%arta são ,ossas ve"as co,ecidas P/ e P.
Figura 6: EndereJo linear t&ico >36 bits)9
Para faci"itar a compree,são sobre essas tabe"as da$%i por dia,te fa"arei ape,as sobre a P $%e mapeia %ma p+i,a diretame,te. oda a disc%ssão ap"ica-se Ss o%tras tabe"as s= $%e e"as apo,tam para p+i,as $%e co,t*m tabe"as e ,ão a p+i,a e,dereve" pe"o compo,e,te o..set do e,dereo "i,ear Gisso fico% c"aro at* a$%i creioH. 111
As entradas da -age @able Cada e,trada da P GP)H tem a se+%i,te estr%t%ra: struct ta;leEentrQEs EEattri;uteEE((!aced)) unsigned long !B /* Z !8gina est8 !resente */ unsigned long rB /* read-rite ou read-onlQ */ unsigned long usB /* rivil7gio Wser ou Fu!ervisor */ unsigned long !tB /* !age rite-through */ unsigned long !cdB /* !age cache disa;le */ unsigned long aB /* acessada (!ode ser usada !or so"tare) */ unsigned long dB /* su`a (dirtQ) (!ode ser usada !or so"tare) */ unsigned long !sB /* F4 Fem!re na D4. */ unsigned long gB /* !8gina glo;al */ unsigned long unusedB3 /* !recisa ser 6ero& */ unsigned long addrA /* ;its su!eriores do endereTo "Psico. */ unsigned long unusedLBB /* !recisa ser 6ero& */ unsigned long @dB /* UI ;it Fe setado nOo !ermite c?digo e@ecut8vel. */
!pe,as a"+%,s desses bits ,os i,teressam: 5 bit P se erado i,dica $%e $%a"$%er te,tativa de acesso a %ma p+i,a para essa e,trada ca%sar %m &age .ault. @este caso os demais bits da e,trada ,ão são co,siderados para coisa a"+%ma. 5s bits N e 6 i,dicam respectiv ame,te se a p+i,a pode ser "ida e escrita GreadriteH o% ape,as "ida G read onlyH e o privi"*+io ,ecessrio para acess-"a G user o% su&ervisorH. !s p+i,as re"acio,adas ao Der,e" são marcadas como su&ervisor. 5 bit i,dica $%e essa p+i,a precisa ser ma,tida ,o cace +"oba" de p+i,as Gcamado de LQH a todo c%sto evita,do $%e a trad%ão precise ser refeita a cada acesso S p+i,a. ?sso po%pa tempo. Fa"arei mais sobre LQs adia,te. 5 bit U/ i,dica se a p+i,a pode co,ter c=di+o e&ec%tve" o% ,ão. @o users&ace $%a,do vocJ a"oca mem=ria com malloc o Der,e" cria; e,tradas em tabe"as de p+i,as para o se% processo com o bit U/ setado GU/ * si+"a de eecution DisableH. Por isso ,ão basta a"ocar mem=ria co"ocar %m linguagem de m?quina " e sa"tar para a"+%ma posião mo,te de b#tes co,te,do %m t*c,ica c=di+o em desse b"oc o a"ocado. )ssa de code inAection ,ão f%,cio,a e mostrarei como faJ-"a corretame,te mais adia,te.
As extens6es -A7 e -S7 /e% pra perceber $%e o es$%ema de pa+i,aão ,ão a%me,ta; a $%a,tidade de mem=ria diretame,te acess a ?,te" reso"ve% criar %ma e&te,são $%e a%me,ta o tama,o de %m e,dereo f2 bits G4 PQ do virtual address s&aceH. )ssa e&te,são a P/ysical 1ddress E4tension o% P!) * ativada atrav*s do bit > do re+istrador de co,tro"e CN4. 5 e,dereo "i,ear ai,da tem o mesmo tama,o. 5 $%e P!) permite * ma&ear %ma p+i,a ,%m espao de e,dereame,to virt%a" maior mas as p+i,as co,ti,%am com o mesmo tama,o G4 ^iQH e porta,to a fai&a comp"eta de todos os e,dereos "i,eares poss( Q Go% 4 iQ do modo i3'(H. m deta"e i,teressa,te * $%e a e&te,são P!) tJm $%e estar obrigat5riamente abi"itada ,o modo &'(-(4. 5%tra e&te,são * a P6) G Page (ize E4tensionH i,trod%ida pe"a ?,te" ,o Pentium III. 5 ,ome di: 112
Com essa e&te,são podemos %sar p+i,as maiores $%e 4 ^iQ. 5 Der,e" do Li,%& %sa P6) se dispo,
@ranslation Loo9aside Ju''ers 6e cada ve $%e o processador %sar %m e,dereo "i,ear e"e precisar trad%i-"o e,tão o processame,to ficaria m%ito "e,to. Como e&istem os caces para po%par o processador o acesso S mem=ria diretame,te tamb*m e&istem caces para trad%ão de e,dereos "i,eares camados 0ranslation *ookaside Bu..ers GLQsH. Cada ve $%e acesso S mem=ria * feito %ma compara ão * feita com o co,teMdo dos LQs. 6e a trad%ão estiver dispo,
6abe,do $%e o processador divide a mem=ria f
113
@abelas de pginas usadas pelo userspace !o $%e parece cada processo ,o users&ace tem s%as pr=prias tabe"as de p+i,as copiadas a partir de %m pro cesso pai se,do init o patriarca. odo processo ,ovo s%r+e a partir do .ork de %m processo pai o,de as tabe"as de p+i,as do processo ori+i,a" são copiadas para o fi"o. Por isso ambos os processos comparti"am todos os dados i,c"%i,do descritores de ar$%ivos... @o e,ta,to ao rea"iar o .ork o Der,e" a%sta o stat%s das p+i,as de dados de ambos os processos como read5only e $%a,to %ma te,tativa de escrever ,%ma varive" %ma &age .ault ocorre modifica,do o mapeame,to da p+i,a do processo para %ma o%tra p+i,a com a respectiva c=pia da p+i,a ori+i,a"... )sse procedime,to * co,ecido como co&y5on5rite Gcopia $%a,do escreveH o% C5. !o $%e parece ambos os processos comparti"am do mesmo e,dereo "i,ear como pode ser demo,strado ,o c=di+o abai&o: /* test.c */ #include #include int @ void main(void) !idEt !id !rint"(Zntes do "or - rocesso !ai @ @%BSl@'n, @) !id "or() i" (!id -B) !uts(4HH2 no "or().) return else i" (!id ) /* rocesso "ilho */ !rint"(Je!ois do "or - rocesso "ilho @ @%BSl@'n, @) @ B !rint"(Je!ois do "or (escrita @ %d) - rocesso "ilho @ @%BSl@'n, @, @) else /* rocesso !ai */ !rint"(Je!ois do "or - rocesso !ai @ @%BSl@'n, @) @ L !rint"(Je!ois do "or (escrita, @ %d) - rocesso !ai @ @%BSl@'n, @, @) -----%<----- corte aqui -----%<---- gcc -o #es# #es#.c ./#es# Zntes do "or - rocesso !ai @ @S;Ac Je!ois do "or - rocesso !ai @ @S;Ac Je!ois do "or (escrita, @ L) - rocesso !ai @ @S;Ac Je!ois do "or - rocesso "ilho @ @S;Ac Je!ois do "or (escrita @ B) - rocesso "ilho @ @S;Ac
Como observar ,o processo pai $%a,to processosefi"o o e,dereo "i,ear da varive"vocJ Y&Y *pode 0&(00b4c. Parata,to processos difere,tes isso s= ,o * poss
/e fato ,o modo i3'( o co,teMdo de CN3 para %ma tarefa * ma,tido ,a estr%t%ra do 66 G 0ask (tate (egmentH ,os die,do $%e CN3 * modificado de fato e,tre caveame,tos de co,te&tos. @o modo &'(-(4 isso ,ão * feito com assistJ,cia direta do processador $%e o 66 * bem difere,te ,esse modo. !t%a"iar CN3 co,sta,teme,te tem o da,oso efeito co"atera" de i,va"idar as LQs e&ceto a$%e"as c%as e,tradas em tabe"as de p+i,a esteam marcadas como +"obais;.
Alocando mem%ria: malloc e mmap ! imp"eme,taão da f%,ão malloc Ge s%as derivadas: calloc e reallocH ,a "ibc * i,teressa,te: !o malloc toma co,ta do espao reservado ,o a"ocar $%e 12' ^iQ de mem=ria G32 do p+i,asH eap dame,os ap"icaão. Provave"me,te o "oader sistema operacio,a" o% a pr=pria "ibc pr* a"ocam p+i,as s%ficie,tes para ,ão ter $%e re$%erer remapeame,to.
Para b"ocos me,ores $%e 12' ^iQ malloc %sa a s#stem ca"" sbrk $%e modifica o tama,o da mem=ria a"ocada para a ima+em bi,ria a"ocada ao carre+ar a ap"icaão. )ssa f%,ão a%me,ta a $%a,tidade de p+i,as a"ocadas toma,do como base as $%e estão ". para b"ocos maiores $%e 12' ^iQ malloc %sa a s#stem ca"" mma& $%e a"oca p+i,as pri!adas Gao users&aceH. m a"+oritmo otimist a * ass%mido para malloc isto * a "ibc s%pe $%e a mem=ria re$%isitada est dispo,
R%a,do o sistema operacio,a" a"oca mem=ria e"e o fa sempre com b"ocos de tama,o mM"tip"os de %ma p+i,a. @ão como a"ocar me,os $%e 4 ^iQ por ve. 6e %m tama,o de b"oco c%a +ra,%"aridade ,ão sea do tama,o de %ma p+i,a for re$%isitado se% c=di+o desperdiar mem=ria %ma ve $%e %ma p+i,a i,teira ser a"ocada de $%a"$%er ma,eira. 5 $%e malloc e o%tras roti,as de a"ocaão da libc faem * reaproveitar p+i,as a"ocadas sempre $%e poss( ^iQ para p+i,as de 4 ^iQ. Aais do $%e isso e teremos dLQs i,v"idos $%e precisarão ser va"idados tor,a,do o acesso S mem=ria mais "e,to. !o ma,ter a me,or $%a,tidade poss
!dicio,e a "imitaão de espao ,o cace L1d e vocJ ver $%a,to prob"ema de performa,ce pode co,se+%ir e,cara,do mem=ria como %m rec%rso sem "imites; como e,si,am ,os c%rsos de a,"ise de sistemas... !o i,v*s de %sarmos ma""oc podemos %sar a s#sca"" mma& $%e a"ocar %ma o% mais p+i,as a"i,adas para ,=s. ma desva,ta+em de %sar mma& ao i,v*s de malloc * $%e para "iberar; o b"oco a"ocad o * ,ecessrio %sar munma& passado o e,dereo e tamb*m o tama,o do b"oco previame,te a"ocado Gdifere,te de .ree $%e as estr%t%ras de malloc ma,t*m essa i,formaãoEH. )is %m e&emp"o simp"es de %so de mmap: #include #include 9 void *!tr si6eEt ;lsi6e AfS*B /* Zloca B !8ginas, dei@a que o ernel escolha o endereTo. */ i" ((!tr mma!(UWGG, ;lsi6e, H2DEH4ZJ b H2DEkHND4, +ZEZUU2U+2WF, -B, )) UWGG) /* erro& */ 9 /* Wsa o !onteiro !tr aqui... */ 9 /* Vli;eraX o ;loco. */ munma!(!tr, ;lsi6e) 9
;m exemplo de inIeção de c%digo. usando pginas ! t%rma $%e +osta de e&p"oits vai adorar essa. sar a f%,ão mma& para a"ocar p+i,as ,os d a"+%,s poderes $%e malloc ,ão tem. Por e&emp"o podemos a"ocar %ma p+i,a i,etar %m c=di+o em linguagem de m?quina ,e"a desabi"itar o bit U/ e sa"tar para o c=di+o. )sse * o pri,c #include #include /* Damanho de uma !8gina. */ #de"ine ZC4EFN4 AfS /* ?digo que vai ser in`etado. */ const unsigned char code[] @AR, @Rf, @"R, @AR, @B, @"R, @c3
/* mov ra@,rdi */ /* add ra@,rdi */ /* ret */
int main(int argc, char *argv) long (*"!)(long) int @ 3, value /* Zloca uma nica !8gina. oderPamos alocar o tamanho su"iciente !ara ca;er o c?digo, mas
11(
mma! vai alocar uma !8gina de qualquer `eito& */ "! mma!(UWGG, ZC4EFN4, H2DEH4ZJ b H2DEkHND4, +ZEZU2U+2WF b +ZEHNZD4, -B, ) i" ("! & UWGG) /* o!ia o c?digo !ara a !8gina */ memc!Q("!, code, si6eo"(code)) /* Jesa;ilita a escrita na !8gina e ha;ilita a e@ecuTOo. */ m!rotect("!, ZC4EFN4, H2DEH4ZJ b H2DE4I4) /* 4@ecuta o c?digo in`etado via !onteiro. */ value "!(@) /* Jealoca a !8gina& */ munma!("!, ZC4EFN4) !rint"(2 do;ro de %d 7 %d.'n, @, value) else !uts(UOo consegui alocar uma !8gina&) return
5 c=di+o i,etado acima * bem simp"es. )"e ,ão co,t*m referJ,cias S mem=ria. 6e tivesse ter
5 @!6A criar %m ar$%ivo obeto assim: S f
4R B 3 AR Rf KR AR B 3
call S ret mov ra@,rdi add ra@,ra@ ret
5 $%e se+%e o va"or 0&)' * o e,dereo re"ativo; para o,de o C!LL sa"tar em re"aão a pr=&ima i,str%ão. o va"or $%e ser acresce,tado ao N?P. )sse c=di+o ,ão precisa de fi&-%ps mas se fossemos imp"eme,t-"os para essa roti,a ter a esse %,si+,ed i,t; comp"eta,do o a%ste. )&istem casos o,de %ma versão do C!LL %sa %m e,dereo abso"%to G%m e,dereo "i,earH e ,este caso e"e ter ' b#tes de tama,o. @este caso os fi&-%ps são obri+at=rios. o caso de sa"tos i,diretos. Criar %m code inAection desse eito * traba"oso... 6e vocJ $%iser %m ? compi"er rea"; ,o se% c=di+o recome,do o %so da lib\I0>1. A!iso: sar a sessão 9data o% 9bss para co,ter %m c=di+o e&ec%tve" cost%ma fa"ar por$%e o sistema operacio,a" a"oca p+i,as para essas sesses com atrib%tos $%e impedem a e&ec%ão de c=di+o Gbit U/ setadoH. 6e vocJ te,tar faer a"+o assim: char ;u""er[B] '@c3 /* 3 H4D */
>1 /o8,"oad em ttps:XX888.+,%.or+Xsoft8areX"ibitX
117
/* Jeclara um !onteiro !ara uma "unTOo e coloca o endereTo do ;u""er nele. */ void (*"!tr)(void) (void (*)(void));u""er /* hama a "unTOo via !onteiro. */ "!tr()
! camada YfptrGHY vai ca%sar %m se+me,tatio, fa%"t;. ) a mesma coisa vai aco,tecer se vocJ a"ocar %m b%ffer com malloc. 5 $%e fi com mma& foi criar %ma e,trada de p+i,a com o atrib%to PN5])U)C o% sea o bit U/ eradoE
Kuanta mem%ria '$sica est dispon$vel, importa,te $%e s%a ap"icaão te,te ,ão %sar mais mem=ria do $%e a fisicame,te dispo,
/* Feconds since ;oot */ /* B, , and B minute load averages */ /* Dotal usa;le main memorQ si6e */ /* Zvaila;le memorQ si6e */ /* Zmount o" shared memorQ */ /* +emorQ used ;Q ;u""ers */ /* Dotal sa! s!ace si6e */ /* sa! s!ace still availa;le */ /* Uum;er o" current !rocesses */ /* Dotal high memorQ si6e */
unsigned longmemEunit "reehigh /* memorQ si6e*/ */ unsigned int /* Zvaila;le +emorQ unithigh si6e in ;Qtes char E"[L-L*si6eo"(long)-si6eo"(int)] /* adding to SA ;Qtes */
@ão * coi,cidJ,cia $%e essa f%,ão retor,e os mesmos va"ores $%e vocJ obt*m %sa,do o coma,do free: "ree -lh total +em _._C Go _._C $igh M -/= ;u""ers/cache Fa! _.fC
used B.3C B.3C M ASR+ M
"ree S.AC S.AC M _.LC _.fC
shared M
;u""ers cached + R3S+
!cima temos os va"ores pessimista Gem verme"oH e otimista GverdeH da mem=ria f
Li,%& te,tar "iberar a mem=ria %sada por b%ffers e caces $%a,do as ap"icaes dema,darem rec%rsos. @a maioria das vees * se+%ro obter a mem=ria f
fa%"ts operaes de s8ap e&ec%tadas pe"o processo e at* mesmo caveame,tos de co,te&to de tarefas. /ifere,te de sysin.o os va"ores obtidos são retor,ados em ^iQ ,ão em b#tes. @o caso do i,do8s vocJ pode %sar a f%,ão 7etProcess'emoryIn.o para obter os va"ores de N66 G$%e ,a ,ome,c"at%ra da Aicrosoft * camado de %orking (et (izeH. )ssa f%,ão * parte da P6!P? Gpode ser ,ecessrio importar a psapi.d"" depe,de,do da versão do se% i,do8sH. Para obter a mem=ria f
119
120
Capítulo ! :reads; VocJ provave"me,te tem %m processador $%e poss%i mais de %m n"cleo e deve estar se per+%,ta,do se treads ,ão são a so"%ão defi,itiva para +a,o de performa,ce... ?,fe"ime,te ,ãoE 0/reads e&istem para dividi r o traba"o; permiti ,do a e&ec%ão de %ma mesma roti,a em vrias
fre,tes teoricame,te em para"e"o. )&iste %m pote,cia" +a,o de performa,ce +era" $%e dois o% mais processos traba"a,do em partes difere,tes podem termi,ar o traba"o $%e %ma roti,a discreta "evaria o dobro do tempo... Aas ,ão * sempre assim. ) * ,ecessrio e,te,der como as treads f%,cio,am para tirar boa va,ta+em de"as... Para e,te,der o $%e * de fato %ma tread * preciso e,te,der os co,ceitos de conteGto de tare#a e a difere,a e,tre tare.a e t/read. !mbas são %,idades de e&ec%ão e ao fa"ar de ambas fa"amos de para"e"ismo. arefa; est associada a %m rec%rso de i,fraestr%t%ra prese,te ,o processador desde o 2'( $%e se refere ao c/aveamento de conte4to de tare.a $%e não F implementado ,o modo &'(-(4. Pe"o me,os ,ão da mesma forma $%e o * ,o modo i3'(. ConteGto de tare#a * o co,%,to de va"ores de todos os re+istradores $%e estavam se,do %sados por
%m processo a,tes de"e ser i,terrompido. 5/56 os re+istradores i,c"%i,do: •
5s de %so +era": /e N!U at* N1> N6P N?P NQP N6? e N/?\
•
5s se"etores de se+me,to C6 F6 e 6 Gos demais ,ão são %sados ,o modo &'(-(4H\
•
5s re+istradores 6?A/ GUAA0 at* UAA1> eXo% WAA0 at* WAA1>H\
•
! pi"a do coprocessador matemtico\
NFL!6 R%a,do o Der,e" m%da de %ma tarefa para o%tra e"e sa"va o co,te&to de tarefa i,teiro em a"+%m "%+ar carre+a o co,te&to da o%tra tarefa de o%tro "%+ar e sa"ta para o C6:N?P da ,ova tarefa. 6= assim a +ara,tia de $%e a ,ova tarefa co,ti,%ar e&atame,te de o,de paro%. )ssa troca de tarefas * camada de ca!eamento de tare#a o% task sitc/ing. @oto% $%e esse caveame,to imp"ica ,ecessariame,te ,a i,terr%pão da e&ec%ão de %ma tarefa e o rei,
0/read por o%tro "ado * %m co,ceito mais abra,+e,te . )m processadores com vrios ,Mc"eos o%
sistemas com vrios processadores podemos e&ec%tar tarefas de forma verdadeirame,te para"e"a Gcama-se (imetrical 'ulti Processing, o% 6APH. Aas %ma tread pode tamb*m ser e&ec%tada em fatias de tempo G0ime slicing 'ulti ProcessingH e ,este caso aver task sitc/ing. @o $%e co,cer,e o caveame,to de tarefas isso s= pode ser feito media,te %ma a e,tre+a do co,tro"e do se% pro+rama $%e * e&ec%tado ,o users&ace para o Der,e" GDer,e"spaceH. ! forma como isso * feito depe,de do sistema operacio,a" mas a maioria dos sistemas dece,tes o faem de forma preemptiva...
ultitare'a preemptiva e cooperativa @os idos do i,
serão caveadas da,do a impressão de m%"tiprocessame,to. @o es$%ema de m%"titarefa cooperativa a ap"icaão cooperava; com o sistema operacio,a" por assim dier e,tre+a,do o co,tro"e de tempos em tempos para o Der,e". 5 prob"ema * $%e se ,a ap"icaão s%r+isse %m "oop i,fi,ito o% ,e,%ma f%,ão da !P? fosse camada a i"%são de m%"tiprocessame,to era $%ebrada. m dos modos como o i,do8s faia isso era atrav*s de %ma camada e&p"
! f%,ão 7et'essage e&ec%tava o sced%"er a"*m de obter a M"tima me,sa+em da fi"a... os sistemas @?U sempre foram baseados em m%"tiprocessame,to preemptivo. Preemptividade; * a capacidade do Der,e" de i,terromper %ma tarefa sem a cooperaão do c=di+o ,o users&ace. !o co,trrio da cre,a pop%"ar preemptividade ,ão tem ,ada aver com processame,to sim%"tK,eo. 5 si+,ificado da pa"avra * evide,te: do dicio,rio %m dos si,h,imos * a,tecipado;. !$%i isso $%er dier $%e o Der,e" co,tro"a o caveame,to ,ão o se% pro+ramaE
Dltiplos processadores odo processador e&ec%ta c=di+o apo,tado pe"o par de re+istradores C6:N?P. Para faer isso o processador * co"ocado ,%m modo espec
atrav*s do barrame,to ?CC o Q6P pode e,viar i,terr%pes para os !Ps i,icia,do s%spe,de,do o% i,terrompe,do treads. 5 c=di+o respo,sve" por decidir para o,de %ma tread vai ser e,viada; o% se e"a vai ser co,te&t%a"iada para ser caveada * tarefa de %m pedao de c=di+o do Der,e" camado sc/eduler.
Como o sc"eduler 5 c"amado, ! ma,eira mais fci" * atrav*s de i,terr%pes ao processador. Certos dispositivos ,o se% comp%tador e,viam %m pedido de i,terr%pão ao processador pedi,do ate,ão. Por e&emp"o $%a,do vocJ pressio,a %ma tec"a em se% tec"ado o circ%ito associado a e"e pede $%e o processador pare t%do o $%e est fae,do para e&ec%tar %ma roti,a espec2. 6e o sced%"er for camado pe"a roti,a da i,terr%pão desse timer e"e ter ca,ce de cavear tarefas a cada 1' ms de i,terva"o. /essa forma o sced%"er i,terrompe tarefas e rei,icia o%tras de acordo com %m a"+oritmo comp"icado $%e "eva diversos fatores em co,ta: Prioridade da tarefa G$%ais tarefas terão maiores o% me,ores fatias de tempo para siH para"e"ismo rea" vers%s time s"ici,+ etc. @o caso do Li,%& o ,ome adotado para o a"+oritmo * CF6 G "om&letly Fair (c/edulerH. 5 $%e ,os i,teressa saber * $%e o sced%"er rea"iar caveame,to de tarefas $%a,do for ,ecessrio e ma,ter re+istros de tarefas para"e"iadas Gvia 6APH. 8inalmente. uma explicação de por(ue SS não 5 zero no modo x12&23 R%a,do fa"ei sobre os se"etores ,o modo &'(-(4 mostrei $%e ape,as o se"etor C6 * co,siderado pe"o processador. odos os o%tros G/6 )6 F6 6 e 66H são i+,orados. @a ocasião mostrei %m pe$%e,o c=di+o para imprimir o co,teMdo dos se"etores e para s%rpresa +era" o re+istrador 66 co,t*m %m va"or difere,te de ero e pior com %m NPL co,die,te com o users&aceE )&iste ape,as %m motivo pe"o $%e posso perceber: R%a,do * feito %m caveame,to de tarefa e,tre o ring G e o ring 2 via i,terr%pão o processador sa"va o co,teMdo de 66:N6P ,a pi"a e era 66. 5 sistema operacio,a" pode e,tão ma,ter %m va"or v"ido em 66 ,o users&ace como %ma ma,eira de saber rapidame,te em $%e ring e"e est. Aais importa,te: 66 poder co,ter %m <,dice para %m descritor $%e te,a i,formaes importa,tes para o Der,e" sobre o processo $%e foi caveadoE *a prtica. o (ue 5 uma !t"read#, Para simp"ificar %ma tread * %ma f%,ão. )ssa f%,ão * e&ec%tada como se estivesse ,%m processo separado mas comparti"a,do todos os rec%rsos do processo $%e crio% a tread. /e fato treads tamb*m são co,ecidas como lig/teig/t &rocesses o% processos "eves;. !"*m do ,ome ,ão m%ita difere,a e,tre t/reads e &rocessos: !mbos tJm pi"a e co,te&tos pr=prios por e&emp"o. 6obre rec%rsos comparti"ados com o processo; $%ero dier $%e s%as treads e,&er+am todas as variveis +"obais do se% pro+rama. ?sso * difere,te de %m .ork o,de %m ,ovo processo * criado >2 Co,s%"te a co,fi+%ra ão do se% Der,e" via s%do s#sct" Der,e".sced]"ate,c#],s;. @o me% caso a "atJ,cia do sced%"er * de 1' mi"isse+%,dos Go% 1'000000 de ,a,osse+%,dosH.
123
com base ,a c=pia do processo ori+i,a" e os dados do ,ovo processo s= são copiados; se forem modificados pe"o processo fi"o Gco&y5on5riteH. ?sso ,ão aco,tece com treads. m deta"e sobre a pi"a assi,a"ada a %ma tread: aco,se"ve" $%e e"a sea pe$%e,a para ,ão co"ocar pressão ,o sistema de pa+i,aão. !"*m do poss
Criando sua pr%pria t"read usando pt"reads Ptreads o% Posi4 0/reads * a bib"ioteca padrão em ambie,tes P56?U Gobviame,teH para "idar com treads Gmais obvio ai,daEH. rata-se de %m co,%,to de f%,es para criar e ma,%sear treads. ) * bem fci" de ser %sado. Nes%midame,te $%a,do vocJ cria s%a tread est cria,do %ma ramificaão para"e"a do f"%&o de e&ec%ão desassociado do f"%&o da tread pri,cipa" Ga tread do processoH. !ssim teremos dois f"%&os de e&ec%ão. )m a"+%m mome,to teremos $%e %,tar; G AoinH o f"%&o ,ovo com o f"%&o da tread pri,cipa". )ssa %,ão; co"oca a tread pri,cipa" para dormir e,$%a,to e"a espera pe"o t*rmi,o da tread sec%,dria. sar treads com ptreads * esse,cia"me,te a"+o assim Gomiti todos os tratame,tos de erro para faci"itar a "eit%raH: !threadEt tid /* Ndenti"icador da nova thread. */ !threadEattrEt tattr /* Ztri;utos da nova thread. */ void *mQthread(void *) /* rot?ti!o da "unTOo que ser8 e@ecutada na nova thread. */ void *!aramE!tr /* onteiro !ara os !ar^metros que a thread rece;er8. */ int retval /* alor retornado !ela thread, se algum. ode ser de qualquer ti!o. Wso int como e@em!lo a!enas. */ /* Nniciali6a os atri;utos de"ault da thread, alterando a!enas o tamanho da !ilha !ara o menor !ossPvel. */ !threadEattrEinit(tattr) !sthreadEattrEsetstacsi6e(tattr, D$H4ZJEFDZjE+NU) /* ria e !\e a nova thread em e@ecuTOo. */ !threadEcreate(tid, tattr, mQthread, !aramE!tr)
124
/* ontinua a "a6er algo na thread !rinci!al enquanto a thread secund8ria roda. */ 9 /* 4s!era !ela hora de `untar a thread criada com a !rinci!al. oloca a thread !rinci!al !ara dormir enquanto a thread identi"icada !or tid nOo retorna. */ !threadE`oin(tid, retval) /* Ueste !onto a thread secund8ria `8 nOo e@iste mais. */
@ote $%e a,tes de criarmos a tread temos $%e i,formar se%s atrib%tos. ! f%,ão &t/readOattrOinit i,icia"ia esses atrib%tos com va"ores defa%"t. )is a"+%,s de"es: • • •
! tread ser criada como Joinable] 5 ,
Pode ser ,ecessrio %sar %ma a f%,ão do tipo &t/readOattrOset Go,de UUU * o atrib%to a ser modificadoH para faer a%stes fi,os. @o e&emp"o acima %m dos atrib%tos $%e modifi$%ei foi o tama,o da pi"a da tread. Por defa%"t ptread criar pi"as do mesmo tama,o i,formado por Y%"imitY: 7limi# -s RBfL
Como podem ver ,o me% sistema o tama,o de pi"a defa%"t * de ' AiQ >3. ! f%,ão receber %m va"or i+%a" o% s%perior S co,sta,te PIN)!/]6!C^]A?@ caso co,trrio a tread ,ão ser criada G &t/readOcreate retor,ar %m va"or difere,te de ero i,dica,do erroH.
&t/readOattrOsetstack precisa
R%a,to ao atrib%to Aoinable * perfeitame,te poss
Criando t"reads no Windows sar a !P? do i,do8s para criar treads * tamb*m bem fci" mas o co,tro"e das treads ,ão * tão faci"itado assim. @ão a faci"idade de %,tar; as treads por e&emp"o. /ifere,te de &t/reads as treads do i,do8s são desassociadas da tread pri,cipa". Aas e&iste %ma ma,eira de em%"ar %m oi,; como pode ser visto mais adia,te... Para criar %ma tread s= precisamos %sar a f%,ão "reate0/read $%e toma seis parKmetros:
>3 @ão $%e a tread o% o proces so criem %ma pi"a de ' AiQ. 5 sistema a"oc a %ma p+i,a prese,te; G4 ^iQH e as demais p+i,as como ,ão prese,tes;. !ssim pe"o processo de &age .ault pode-se faer a pi"a crescer at* ' AiQ se ,ecessrio.
12>
$ZUJG4 kNUZN reateDhread( GF4WHNDEZDDHNMWD4F l!DhreadFecuritQZttri;utes, FN4ED dFtacFi6e, GD$H4ZJEFDZHDEH2WDNU4 l!FtartZddress, G2NJ l!arameter, Jk2HJ dreatingKlags, GJk2HJ l!DhreadNd )
@a !P? do i,do8s +era"me,te os va"ores defa%"t são ass%midos ao se passar %m po,teiro @LL Go% eroH. o caso dos dois primeiros parKmetros e dos f"a+s de criaão Gatrib%tosBH. )is %m e&emp"o de criaão de %ma tread: $ZUJG4 hthread /* rot?ti!o da nossa "unTOo que ser8 V!araleli6adaX. */ Jk2HJ kNUZN +QDhreadKunc(G2NJ) /* Vcria threadX e coloca !ara e@ecutar. */ i" ((hthread reateDhread(UWGG, BLR*BLA, /* ilha de BLR jiM. */ +QDhreadKunc, UWGG, , UWGG)) UWGG) 9 trata erro aqui 9 9 "a6 alguma coisa 9 /* V`oinX */ kaitKorFingle2;`ect(hthread, NUKNUND4)
6e o parKmetro do tama,o da pi"a for 0 e,tão "reate0/read %sar %ma pi"a de 1 AiQ de tama,o Gesse * o tama,o de pi"a defa%"t do i,do8sH. 5 parKmetro do tipoia LPIN)!/]6!N]N5?@) po,teiro para. %ma f%,ão oe&ec%tada pe"a tread sec%,dr do mesmo tipo %sada ,a camada* S%m&t/re adOcreate I tamb*m po,teiro +e,*rico para o parKmetro $%e ser passado para essa f%,ão os atrib%tos da tread Gd8CreateF"a+sH e o po,teiro para o ide,tificador da tread. /ifere,te de &t/readOcreate podemos criar %ma tread s%spe,sa seta,do o bit CN)!)]66P)@/)/ ,os f"a+s de criaão. Criar %ma tread s%spe,sa em ptreads ,ão * poss
camadas a &t/readOAoin ,ecessrias para %,tar; mM"tip"as treads sec%,drias... 6e tivermos $%e esperar por 3 treads por e&emp"o podemos faer: $ZUJG4 tids[3] int trQs /* oloca tids[] tids[B] tids[L]
os handles das threads no arraQ. */ tidB tidL tid3
/* Denta es!erar !elo "im, de todas as threads, B ve6es. 4s!era 3 segundos (3 milissegundos) a cada ve6. */ trQs B hile (--trQs kaitKor+ulti!le2;`ects(3, tids, DHW4, 3) kZNDEDN+42WD) /* Finali6a, de alguma maneira, !ara as threads que elas !recisam terminar& */ i" (trQs < ) 9 trata erro aqui 9
-arar uma t"read !na marra# (uase sempre não 5 uma boa ideia )m ambos os casos ta,to ,o i,do8s $%a,to ,o P56?U * poss
Pode perma,ecer em "oop i,fi,ito eter,ame,te mesmo $%e %m &t/readOcancel sea %sado. ! t*c,ica mais %sada ,esse caso * %sar %ma syscall por e&emp"o a f%,ão slee& pedi,do $%e o processo d%rma; por ero se+%,dos: "or () slee!()
127
oda s#sca"" * %m po,to de ca,ce"ame,to. ?sso d a ca,ce de podermos ca,ce"ar a tread. em ai,da o efeito be,*fico de faer com $%e o sced%"er ,ão morra de fome. 6e ,ão camadas para o Der,e" via syscall e,tão o sced%"er s= * camado via i,terr%pão ca%sa,do %m pico de co,s%mo de processame,to. c"aro $%e %ma cam ada a slee& adicio,ar cic"os ao se% processo. 5 $%e * mais %m ar+%me,to co,tra o a%me,to de performa,ce a%tomtico ass%mido para processos m%"titreaded. )sse e&emp"o do "oop i,fi,ito * meio pobre. )&istem meios de co"ocarmos %ma tread para dormir sem recorrermos a %ma syscall. Por e&emp"o podemos %sar &t/readOsigait para esperar $%e %m si,a" sea e,viado para a tread. )m assemb"# e&iste a i,str%ão P!6) $%e a+e como se fosse %m @5P e&ceto $%e oferece %ma dica ao processador de $%e a tread at%a" e,co,tra-se em "oop. P!6) ,ão s%bstit%i %ma camada via s#sca "" mas * Mti" ,as roti,as de si,cro,ismo como s&in locks . 5 motivo da e&istJ,cia de P!6) ,ada tem aver com o sced%"er * c"aro. 5 processador tem " se%s prob"emas com m%ti processame,to tamb*mE
@"reads. nDcleos e cac"es m dos +ra,des prob"emas com as treads e ambie,tes com mM"tip"os processadores o% ,Mc"eos * $%e os estados dos caces serão comparti"ados em a"+%m mome,to G $%e treads criadas ,o se% pro+rama comparti"am o mesmo espao de e,dereame,toH. bom "embrar $%e o cace L1 e&iste separadame,te para cada processador "=+ico o% sea para cada ,Mc"eo de se% processador mas podemos estar %sa,do a"+%m sistema com mais de %m processador tamb*m. !ssim d%as treads podem ser atrasadas pe"o protoco"o de co,sistJ,cia de caces dos processadores Go% ,Mc"eosH. Co,sidere d%as treads G! e QH e&ec%ta,do de ma,eira sim*trica. 6e a tread ! escreve ,%ma varive" +"oba" Y&Y e a tread Q "J a a mesma varive" temos d%as treads acessa,do a mesma re+ião de mem=ria e como co,se$%J,cia disso a"+%ma coisa tem $%e ser feita para ma,ter a co,sistJ,cia dos caces. Co,sistJ,cia a$%i si+,ifica $%e todos os processadores verão a mesma coisa ,os caces sempre $%e poss
12'
dord [@],B dord [@=A],
6e o%ver %m caveame,to de tarefa e,tre as i,str%es !// e !/C o i,creme,to de &; ser feito pe"a metadeE ) esse ,ão * o M,ico caso es$%isito. @%m ce,rio seme"a,te s%po,a $%e %ma tread i,creme,te %ma varive" i,teira e o%tra tread escreva Y0Y ,a mesma varive". 5 $%e aco,teceB 5 a"+oritmo da primeira tread est espera,do %m va"or i,creme,tado Gmaior $%e eroBH mas $%a,do a tarefa for caveada de vo"ta para e"a a varive" co,ter ero co"ocado " pe"a o%tra treadE 6empre $%e %ma das treads $%er modificar %ma varive" %sada por o%tra tread pode aco,tecer esse mo,te de prob"emas $%e são camados de race conditions.
7vitando !race conditions# Para evitar esses prob"emas %sa-se o artif4. R%em di para o semforo ficar verme"o são as pr=prias treads. R%em acio,ar o botão $%e pede ate,ão primeiro passa a ser a do,a do semforo. 5% me"or $%em obt*m a trava; G lockH primeiro ,ão permite $%e as o%tras treads o travem at* $%e o semforo sea destravado G unlockH. Por e&emp"o se $%isermos a"terar %ma varive" +"oba" em ,ossas treads devemos faer a"+o assim: !threadEmute@Eloc(mt@) i" (==@ < +ZIEI) dosomething() !threadEmute@Eunloc(mt@)
A%te&es>> são %m tipo de obeto de si,cro,ism o de treads. )"es são travveis e destravvei s pe"a tread $%e os co,tro"a... 6e estiver travado e,tão a roti,a e,tra em "oop e co"oca a tread para dormir. 5 c=di+o e,tre o lock e o unlock * camado de critical section. @ão * S toa: )ssa * a parte cr4 6emforos tJm %m se,tido espe c> A%te& * %ma abreviaão de A%a""# )&c"%sive;.
129
processame,to sim*trico $%a,to ,o caveame,to de tarefas ,ão temos ideia da posião em $%e ,ossas treads se e,co,tram do po,to de vista da e&ec%ão... 5 si,cro,ismo pode ser feito ,%ma se$%J,cia $%e vocJ ,ão co,siderava poss
@"reads e bibliotecas @em toda f%,ão pode ser %sada imp%,eme,te ,%ma tread. Para $%e possa e"a tem $%e ser ree,tra,te o% sea ,ão %sar rec%rsos e&ter,os S f%,ão Gcomo variveis +"obais por e&emp"oH. @ão * o caso de m%itas f%,es da libc por e&emp"o. Para o Li,%& a libc * bem doc%me,tada pe"a Free (o.tare Foundation9 ! doc%me,taão comp"eta pode ser obtida ,o "i,D ttp:XX888.+,%.or+Xsoft8areX"ibcXma,%a"X. ) por " vocJ e,co,trar para $%a"$%er f%,ão a"+%mas dicas sobre o %so com ambie,tes m%"titreaded... oda f%,ão tem %ma dica depois do prot=tipo: si6eEt strlen (const char *s) F%,ctio,j : y A-6afe y !6-6afe y !C-6afe 8reliminar' e str"e, f%,ctio, ret%r,s te "e,+t of te ,%""-termi,ated stri,+ s i, b#tes. G?, oter 8ords it ret%r,s te offset of te termi,ati,+ ,%"" caracter 8iti, te arra#.H ...
)ste A-6afe; ,os di $%e podem os %sar strlen em c=di+os multit/readed sem medo. Aas ate,ãoE 5 fato de %ma f%,ão ser t/read sa.e ,ão si+,ifica $%e e"a sea athmica $%er dier $%e e"a sea e&ec%tada tota"me,te a,tes $%e %m caveame,to de co,te&to sea feito. amb*m ,ão si+,ifica $%e ,ão possa mos ter prob"emas com race conditions. Co,sidere o caso da f%,ão strc&y $%e t
6e d%as treads %sarem o mesmo po,teiro de desti,o para as camadas a strc&y provave"me,te teremos %ma race condition mesmo $%e strc&y ,ão %se ,e,%ma varive" +"oba" o% esttica "oca";. !ssim os prob"emas $%e "istei a,tes co,ti,%am va"e,do mesmo para as f%,es $%e são oD; para serem %sadas em treads. !s dicas !6-6afe; e !C-6afe; referem-se a si,ais. @o caso de !6-6afe a f%,ão pode ser %sada em respo,dem as ca%sadas por si,ais. @o caso de !C-6afe; a f%,ão * %m roti,as po,to de$%e ca,ce"ame,to de i,terr%pes; tread. m e&emp"o de f%,ão da "ibc $%e * tread unsa.e * strtok. )"a * e&p"icitame,te marcada como A-,safe;. )"a ma,t*m %m estado +"oba" para $%e a se+%,da camada a e"a f%,cio,e como deve. )&iste %ma versão tread safe: strtokOr $%e toma %m parKmetro adicio,a" o,de o pro+ramador deve armae,ar o estado da f%,ão.
130
@"reads e Jlo(ueios !"*m de t/read sa.ety e&iste a $%estão de b"o$%eios de ?X5. !"+%mas f%,es precisam ser comp"etadas a,tes $%e possam ser camadas ,ovame,te. F%,es como rite são syscalls $%e precisam ser comp"etad as. @o caso desta f%,ão ser camada por d%as treads a se+%,da tread a cam-"a parecer estar dormi,do; e,$%a,to a primeira est e&ec%ta,do a f%,ão. !"+%mas s#sca""s podem ser co,fi+%radas para serem ,o, b"ocDi,+; mas isso s= si+,ifica $%e a f%,ão retor,ar imediatame,te com a"+%m c=di+o de erro e,$%a,to e&ec%ta a re$%isião em bacD+ro%,d. o caso de f%,es de sockets. 5 fato de vocJ co,fi+%rar o descritor de ar$%ivo criado pe"a f%,ão socket como ,o, b"ocDi,+; ,ão si+,ifica $%e se%s pacotes serão dispacados em para"e"oE 6i+,ifica $%e e"es serão seria"iados pe"o Der,e" e co"ocados ,%ma fi"a e a f%,ão $%e o fe ira te dier isso Ge vocJ precisa tratar essa i,formaãoEH. Lembre-se $%e o comportame,to padrão para a maioria das s#stca""s * b"ocDi,+;.
O (ue signi'ica isso tudo, c"aro $%e m%"tiprocessame,to $%a,do imp"eme, tado com c%idado tem o pote,cia" de ace"erar a"+%,s processos mas te,a em me,te $%e a $%a,tidade de c%idados * +ra,de e e&i+e est%do i,te,so do $%e a tread deve faer. Por ca%sa da comp"e&idade o pote,cia" para atrapa"ar a boa performa,ce de s%as roti,as * m%ito +ra,de. 5 $%e temos at* a+oraB 0ask (itc/ing +rava e rec%pera o co,te&to de tarefas. )sses co,te&tos são caveados atrav*s de soft8are co,tido ,%m sc/eduler $%e * e&ec%tado provave"me,te pe"a roti,a de resposta de i,terr%pes de timers ate,didas pe"o processador. Cada tarefa pode ser e&ec%tada em re+ime de time slicing o,de %ma fatia de tempo * dada pe"o sced%"er para cada tarefa o% de forma sim*trica distrib%
/* threads.c */ #i" de"ined(EElinu@EE) #include #eli" de"ined(EEkNUUDEE) #include <indos.h> #eli" de"ined(EEKreeMFJEE) #include #include #endi" static int getEnum;erEo"Ecores(void) int getEnum;erEo"E!rocessors(void) #i" de"ined(EElinu@EE) return sQscon"(EFEUH24FF2HFE2UGU) #eli" de"ined(EEkNUUDEE) /* KNI+4 4ssa "unTOo s? e@iste no kin_ e kinLR-HL ou su!eriores. */ return Cet+a@imumrocessorount(ZGGEH24FF2HECH2WF) #eli" de"ined(EEKreeMFJEE) int numE!rocessors, r[L] si6eEt si6e /* ega sQsctl h.nc!u */ r[] DGE$k r[B] $kEUW i" (sQsctl(r, L, numE!rocessors, si6e, UWGG) -B) return getEnum;erEo"Ecores() return numE!rocessors #else return getEnum;erEo"Ecores() #endi" static int getEnum;erEo"Ecores(void) int cores EEasmEE EEvolatileEE ( Vmovl B,%%ea@'nX Vc!uid'nX V;X (cores) ) return (cores >> BS) @""
;sando o Open!"+%*m percebe% $%e a"+%mas roti,as podem aproveitar o para"e"ismo dispo,
Aas e se p%dessemos dier ao compi"ador $%e esse "oop pode ser divid ido em "oops me,ores distrib%
sar essa diretiva di ao compi"ador para i,etar c=di+o $%e $%ebrar o "oop em n "oops i,divid%ais 132
o,de n * o ,Mmero de processadores G$%e o 5pe,AP sabe soi,o $%a" *EH. como se tiv*ssesmos %m .ork para n processos e depois %m Aoin ao fi,a" do "oop. Crie %ma f%,ão simp"es co"o$%e o fra+me,to de c=di+o acima Gi,c"%i,do o eader om&9/H e crie a "ista+em em assemb"#... !o dar %ma o"ada ,a "ista+em vocJ ver %m c=di+o e,orme $%e fa %so de f%,es da libgom& G@ 5pe,APH. )sse,cia"me,te %sar &en'P * %ma $%estão de %sar %m pra+ma $%e * ap"icve" para %m b"oco: #!ragma om! !arallel [tipo] [cláusulas] 9 c?digo que ser8 !araleli6ado aqui 9
5s modificadores YtipoY e Yc"%s%"asY são opcio,ais e servem para otimiaão e para evitar a"+%,s prob"emas. @o ,osso e&emp"o %samos o tipo YforY para otimiar o para"e"ismo para "oops. Aas ,ão %samos $%ais$%er c"%s%"as. 5 e&emp"o abai&o mostra a ,ecessidade de %ma c"%s%"a: #!ragma om! !arallel "or !rivate(`) "or (i i < A i==) "or (` ` < B `==) matri@[i][`]
6em a c"%s%"a &rivate acima provave"me,te o compi"ador te,taria para"e"iar os dois "oops. !o dier $%e a varive" YY * privada ao b"oco diemos $%e o "oop i,ter,o ,ão deve ser para"e"iado. ?sto * s= o "oop e&ter,o ser dividido em treads. Podemos ser mais e&p"
)&istem o%tras diretivas a"*m de Ypara""e"Y e o%tras c"%s%"as a"*m de YsaredY e YprivateY ,a especificaão.
Open- não 5 mgico 6= %m "embrete: $%e estamos fa"a,do de para"e"ismo race conditions tamb*m podem aparecer ,o %so de &en'P. ! bib"ioteca tamb*m for,ece rec%rsos de si,cro,iaão para te,tar mi,imiar o prob"ema o $%e tamb*m pode acarretar em dead locks... )m res%mo os mesmos prob"emas $%e vocJ teria com treads ma,%a"me,te; co,str%
6em %sarmos Y-fope,mpY e "i,Darmos com a libgom& todos os pra+mas serão i,=$%os. Atenção: 5pe,AP ,ão s%bstit%i &t/reads. ) tamb*m ,ão * %ma pa,ac*iaE )"e e&iste como te,tativa de aproveitar o para"e"ismo sim!trico de a"+%mas ar$%itet%ras. /e fato se vocJ camar a f%,ão om&OgetOma4Ot/reads da "ib+omp ver $%e e"e devo"ve ape,as o ,Mmero de processadores "=+icos co,tidos ,o se% sistema. ! difere,a * $%e via &t/reads vocJ pode criar ta,tas treads $%a,to o
133
sistema operacio,a" permitir mas com 5pe,AP vocJ s= pode criar %m ,Mmero "imitado de"as... c"aro ,ão +ara,tias de $%e as treads criadas pe"a "ib+omp serão sim*tricas mas essa * a ideia...
OpenCL e nEidia C;4A 5 CL; em 5pe,CL si+ ,ifica "oncurrency *ibrary e C/! * Comp%te ,ified /evice !r$%itect%re;. ! primeira G5pe,CL H * %ma bib"ioteca +e,*rica %sada para abstrair as %,idades de processame,to em se% sistema a se+%,da * proprietria da ,Vidia e serve para %sar as %,idades de processame,to da s%a p"aca de v. 6e+%,do o site da ,Vidia essa p"aca tem 3'4 C/! cores;. Ae% processador * %m i7 com mais '. Com 5pe,CL posso em teoria criar pro+ramas $%e e&ec%tem 392 treads co,corre,tes. @%m ambie,te mais profissio,a" podemos mapear processadores remotos para %,tarem-se ao time... ?ma+i,e %m data center com 100 m$%i,as i+%ais a mi,a. Podemos ter o va"or te=rico de 39200 terads co,corre,tes e&ec%ta,do mesmo em m$%i,as difere,tes. @a prtica %sar ta,tas treads ca%sam m%itos prob"emas especia"me,te com re"aão S si,cro,iaão. ! "i,+%a+em %sada pe"o 5pe,CL Ge pe"o C/!H a%da %m bocado $%e * parecida com C mas tem a"+%mas caracter
134
Capítulo "!
-recisão versus 7xatidão @o ,osso dia a dia $%a,do se fa"a em precisão estamos fa"a,do de o $%ão pr=&imo da rea"idade %m va"or ca"c%"ado pode estar de %m va"or e&ato. ?sso imp"ica em a"+%m tipo de arredo,dame,to. )is %m e&emp"o simp"es: 5 va"or 2 * e&ato mas ,ão *. ! fraão * composta de dois va"ores e&atos mas se% res%"tado s= pode ser e&presso com a"+%ma apro&imaão. 5 termo precisão precisa ser me"or defi,ido: @o co,te&to da aritm*tica com po,to f"%t%a,te e"e si+,ifica a $%a,tidade de di+itos o% a"+arismos %sados ,a represe,taão do va"or. )"e não si+,ifica a $%a,tidade de di+itos o% a"+arismos depois da v
f"%t%a,te; "idarei ape,as com o tipo .loat da$%i por dia,te. Pode-se e&trapo"ar a e&p"icaão para double e long double a%me,ta,do o tama,o de se%s compo,e,tes como veremos S se+%ir. R%a,to maior o tipo maior * a $%a,tidade $%e pode ser armae,ada em se% i,terior. Veremos mais adia,te $%e .loat pode represe,tar va"ores com precisão de pe"o me,os 7 a"+arismos decimais. Para co,se+%ir %sar mais a"+arismos temos $%e recorr er a tipos maiores; como double e long double. 6e podemos %sar ape,as 7 a"+arismos ,%m tipo .loat va"ores como 3141>92( ,ão podem ser represe,tados de forma e&ata;. raas S "imitaão da precisão esse va"or tra,sforma-se em 3141>93. @ote $%e e"e tem $%e ser arredo,dado para $%e a precisão de 7 a"+arismos sea ate,dida. sa,do a precisão de 7 a"+arismos se m%"tip"icarmos 3141>93 por 10 a v93. Co,ti,%amos com a precisão de 7 a"+arismos mesmo $%e te,amos %ma $%a,tidade i,ferior de casas depois da v
7strutura de um 'loat Como todo tipo %sado em "i,+%a+e,s de pro+ramaão a atrib%ião da fai&a de va"ores v"idos em base decima" * %ma i"%são co,ve,ie,t e. 5s tipos "idam some,te com va"ores bi,rios. ! f=rm%"a abai&o ,os di como %m va"or do tipo .loat * armae,ado>(: >( Para o tipo double basta co,siderar YeY com 11 bits e a ma,tissa YmY com >3. 5 va"or 127 tor,a-se 1023.
13>
5s va"ores s; m;>7 e e; Gi,iciais de si,a"; ma,tissa; e e&poe,te;H são obtidos da estr%t%ra bi,ria do tipo:
Figura N: e&resentaJo de um .loat9
! ma,tissa correspo,de a parte fracio,ria do va"or em po,to f"%t%a,te. )mbora a pa"avra ma,tissa; ,ão sea %ma boacomo defi,ião a parte fracio,ria de %m ,Mmero rea"de %m $%etermo * defi,ida matematicame,te partepara fracio,ria; de %m "o+aritmo;. @a fa"ta me"or e por motivos ist=ricos %sarei esse termo mesmo. R%a,do di+o $%e a ma,tissa * some,te a parte fracio,ria $%ero dier $%e a parte i,teira do va"or armae,ado ,a estr%t%ra * imp"> fae,do com $%e a potJ,cia de dois %sada para esca"o,ar o va"or bi,rio Go% des"ocar a v
Analogia com !notação cient$'ica# 5 motivo de adicio,armos 1 a,tes do m pode ser e,te,dido por a,a"o+ia ao co,ceito de notação cientí#ica. )m f
potJ,cias de 10 Go% sea H e "imita,do a parte i,teira do va"or a ape,as %m a"+arismo difere,te de ero. Para escrever o va"or 10 bi"es * mais fci" escrever do $%e 10000000000. asta me,os espao. @%m va"or em po,to f"%t%a,te aco,tece a mesma coisa. 5 M,ico va"or difere,te de ero $%e a >7 ! ma,tissa m * represe,tada em bi,rio ,essa ,otaão. ) o e&poe,te e em decima". ?sso pode co,f%,dir mas * a ma,eira $%e te,o para compree, der o $%e aco,tece... Pe,se em e como o des"ocame ,to do po,to bi,rio; ao i,v*s de %ma potJ,cia de base 2...
13(
porão i,teira pode ass%mir * 1 por$%e em ,otaão cie,t pode ser escrito em bi,rio como . ?sso ser codificado ,%m .loat como s0 e12( Gpara E-1H e m0. 5 va"or i,teiro co,tido ,%ma varive" f"oat ser 0&3F000000 como mostro ,o e&emp"o abai&o: /* test.c */ #include void main(void) "loat @ ." !rint"(%#RI, *(unsigned int *)@) -----%<----- corte aqui -----%<---- gcc -o #es# #es# ./#es# @3K
Ealores especiais na estrutura de um 'loat> )&istem $%atro e&cees importa,tes ao es$%ema previame,te aprese,tado: 5 va"or 0.0 * %m dos casos especiais. 6e ,a estr%t%ra do .loat o e for ero e a ma,tissa tamb*m e,tão teremos %m va"or ero. ! se+%,da e&ceão aco,tece $%a,do e for ero e a ma,tissa ,ão for. @este caso temos %m va"or em po,to f"%t%a,te denormaliado o% subnormaliado. )ssa cate+oria de va"ores recebe esse ,ome por$%e ,ão se+%e S ,orma G$%e bem ass%me %m va"or 1.0 imp"icitoH. )sses va"ores especiais são %sados para represe,tar va"ores pr=&imos de i,teiro ero e se+%em a f=rm%"a: !s o%tras d%as e&cees aco,tecem $%a,do e for i+%a" a 2>> G0&ffH. @este caso se m for ero temos a represe,taão de i,fi,ito; mas se m for difere,te de ero temos a represe,taão de a"+o $%e não F um n"mero G@a@ o% ot 1 umberH. Va"or @a@ ocorre $%a,do por e&emp"o te,tamos e&trair a rai $%adrada de ,Mmeros ,e+ativos o% $%a,to te,tamos ca"c%"ar 0X0. )&istem dois tipos de @a@s: qas e sas. 5 q %sado como prefi&o ,a si+"a si+,ifica $%ieto;. )m casos como a e&traão de rai $%adrada de va"ores ,e+ativos o va"or obtido * %m qa. ! difere,a e,tra %m qa e %m sa se,do esse M"timo %m @a@ si,a"iado; * $%e este M"timo represe,ta %m erro... @ão $%e %m qa tamb*m ,ão sea mas co,s%mir %m sa pode ser %sado para disparar %ma roti,a de tratame,to de erros e,$%a,to %m qa * faci"me,te i+,orado. )is a"+%mas operaes $%e res%"tam em @a@:
137
-peração
)oti!o
0X0
Va"ori,determi,ado. Va"or i,determi,ado.
Va"ores i,dermi,ados.
a,+e,te desses arcos ,ão e&istem.
Lo+ar
arcse, arccos R%a"$%er operaão e,vo"ve,do @a@s.
@a@ ,ão * %m va"or;E
0abela V: "asos onde oco rrem as
5peraes como e são defi,idas como te,do res%"tado i+%a" a 10 e porta,to ,ão res%"tam em @a@s mas para va"ores difere,tes de 0 e a potJ,cia provave"me,te res%"tat em @a@.
-ra (ue os valores denormalizados existem, Pode parecer $%e $%e * o me,or ,Mmero ,orma"iado $%e pode ser represe,tado ,%m .loat sea pe$%e,o o s%ficie,te para $%a"$%er poss4 ac o% de criar under.los &rogressivos. 5% sea se o res%"tado de %ma operaão for de,orma"iado e"e ai,da * v"ido mas o dese,vo"vedor deve tomar c%idado... !bai&o de o me,or va"or $%e pode ser armae,ado ,%m ,Mmero de,orma"iado * . c"aro $%e a fai&a a%me,ta se estivermos fa"a,do de tipos como double e os under.los ficarão ai,da me,ores. )ntervalos entre valores Por ca%sa do ,Mmero "imitado de bits ,ão como represe,tar todos os va"ores ,o dom<,io dos ,Mmeros reais. @o caso de .loat o me,or i,creme,to e,tre va"ores $%e pode ser obtido Gdesco,sidera,do o esca"o,ame,toH * da ordem de o% sea se o L6Q da ma,tissa estiver setado. 6e a ma,tissa tem 23 bits de tama,o e o bit mais si+,ificativo correspo,de ao va"or e,tão o bit me,os si+,ificativo de"a correspo,de ao va"or . )sse va"or G H o,de desco,sideramos o esca"o,ame,to G EX0H * camado de e&silon e * represe,tado pe"a "etra +re+a e pe"a co,sta,te FL])P6?L5@ ,o eader .loat9/. )"e * defi,ido como o me,or i,creme,to poss
e,tre e e"e m%da para
e assim por
dia,te. Co,forme os i,terva"os vão fica,do maiores devido ao i,creme,to do e&poe,te maior vai fica,do o i,terva"o e,tre os va"ores represe,tveis;. ! fi+%ra abai&o i"%stra:
Figura 3: intervalo mnimo entre valores >e&silon)9
Nepare $%e a cada ve $%e +a,amos %m bit ,a parte i,teira perdemos %m ,a parte fracio,ria por isso o i,terva"o dobra. Para va"ores m%ito +ra,des por e&emp"o a me,or distK,cia e,tre va"ores adace,tes ser de apro&imadame,te 10. Lembre-se $%e ,%m .loat a precisão * de apro&imadame,te 7 a"+arismos decimais e como 10 mi"es tem 7 a"+arismos a me,or distK,cia ser de 1... 6e o va"or fosse a me,or distK,cia e,tre va"ores adace,tes ser da ordem de 1000. )sses são c"c%"os apro&imados $%e são me"or compree,didos em bi,rio %sa,do a estr%t%ra do f"oat... 5 va"or ser codificado como s0 e1(0 m0&1>02F9. 5 va"or de e des"oca a vir+%"a; para a direita em 33 bits G H e o va"or de m adicio,a,do o va"or 1.0 imp"icito tor,a-se 0b1.00101010000001011111001. /es"oca,do a v40Q)400 $%e d e&atame,te 10000000000 em decima". 6e adicio,armos 1 ao L6Q da ma,tissa teremos m0&1>02F! $%e ao somamos 1.0 e des"ocarmos a v40Q)'00 H $%e d e&atame,te 10000001024 em decima". ?sso tor,a os c"c%"os de va"ores mo,etrios de +ra,de mo,ta %m prob"ema. 5 $%e aco,tece se %m s%eito o% %ma empresa tem N` 10 mi"es em a"+%ma co,ta e %m re,dime,to de N` >0000B 5 res%"tado fi,a" co,ti,%ar se,do N` 10 mi"es e os N` >0000 $%e foram adicio,ados ser perdido pode ser armae,ado ,%m .loatE 5 i,terva"o e,tre va"ores adace,tes devem ser sempre $%e não "evados em co,sideraão com base ,o maior va"or %sado ,a operaãoE
;m problema de base !ssim como ,a ,ossa batida base 10 em base 2 e&istem va"ores $%e ,ão podem ser e&pressos e&atame,te. @a base 10 as fraes etc ,ão podem ser e&pressas e&atame,te. VocJ obter %ma d<ima peri=dica. 6e %sssemos o%tra base ,%m*rica como a base 3 por e&emp"o a fraão seria e&atame,te i+%a" a . Aas o processador traba"a com a base 2... )is o%tra s%rpresa: )m re"aão aos va"ores fracio,rios s= * poss ,a base 2E G0> por e&emp"o * e&atame,te H. Para e,te,der por$%J eis %m pro+rami,a $%e ,os mostra a estr%t%ra de .loats: #include /* .A, .S, .R e .f sOo mlti!los de .L e .3. UOo os coloquei aqui !ara nOo usarvalues[] muito es!aTo em mostrar os ., resultados. "loat .B, .L, .3, ._ */ #de"ine ZHHZEFN4 (si6eo"(values) / si6eo"(values[])) void main(void) int i "or (i i < ZHHZEFN4 i==) !rint"(%.B" @%RI'n, values[i], *((unsigned *)values[i])) -----%<----- corte aqui -----%<---- gcc -o imprecise imprecise.c
139
./imprecise .B @3JJ .L @34AJ .3 @34fffffZ . @3K ._ @3K333333
/ para perceber $%e em todos os casos e&ceto com 0.> o va"or da ma,tissa * %ma d<ima peri=dicaB 5 compi"ador s= reso"ve% arredo,dar a"+%,s va"ores para cima; para $%e esses fi$%em mais pr=&imos do va"or rea";. omemos 01 como e&emp"o: )m decima" e"e s= pode ser tra,sformado em . Faa as co,tas e ver $%e a"+o seme"a,te ocorre com os o%tros va"ores $%e citei... ! diima peri=dica s= pode i,dicar %ma coisa: !pro&imaão. @%,ca e&atidãoE Ve,do de o%tra forma cada bit da ma,tissa e$%iva"e a %ma potJ,cia de 2 com e&poe,te ,e+ativo. /epois do 10 imp"\ 02>\ 012>\ 00(2>\ 00312>\ _ 5s va"ores sempre termi,am em >E @a verdade e"es termi,am em 1 em bi,rio... !ssim ,a ora de arredo,dar o compi"ador somar %m > ,a M"tima casa decima". como a$%e"a re+ri,a de arredo,dame,to $%e %svamos ,a esco"a...
O conceito de valor !signi'icativo# R%a,tas vees d%ra,te o per92(>3>'979323'4(2(433'3279>02 vocJ ,ão %so% 314B /epe,de,do da +ra,dea do $%e vocJ teve $%e ca"c%"ar o va"or 314 ate,dia m%ito bem. /a< a precisão de 2 casas depois da v e depois i+,orava todas as cadas decimais; a"*m da se+%,da. 5%tro e&emp"o: R%a,do vai ca"c%"ar distK,cia percorrida por %m trem ,a$%e"es fami+erados prob"emi,as de F) por e&emp"o. m erro de devidame,te esca"o,ado em re"aão ao e&poe,te * o+ado fora. @ão tem si+,ificado; ,o c"c%"oE ?sso ,ão si+,ifica $%e o processador ,ão %se esse pe$%e,o erro para obter o va"or fi,a". ,a ora de mostr-"o $%e o erro * desco,siderado atrav*s de arredo,dame,to. )ste * %m deta"e m%ito importa,te ao "idarmos com po,to f"%t%a,te: 5s c"c%"os são feitos sempre com os va"ores como e"es estão e * ,a ora de mostr-"os $%e arredo,dametos são feitosE Aas arredo,dame,tos ,ão são tão simp"es assim. )&istem $%atro tipos difere,tes: •
Para cima; em direão ao |\ Para bai&o; em direão ao -|\
•
)m direão ao ero e\
•
5 mais pr=&imo poss
•
@orma"me,te o processador * co,fi+%ra,do para arredo,dar para o va"or mais pr=&imo poss
podem ser %sados em casos especiais basta,do reco,fi+%rar a %,idade aritm*tica. 5 arredo,dame,to reso"ve o prob"ema da "imitaão de bits da ma,tissa mas +era o%tros i,teressa,tes...
Fegras da matemtica elementar nem sempre são vlidas !"*m da impossibi"idade de obter %m va"or rea" a partir de %ma divisão por ero o% da e&traão de %ma rai $%adrada de %m ,Mmero ,e+ativo vocJ tamb*m deve ter apre,dido ,a esco"a $%e as operaes f%,dame,tais tJm as se+%i,tes propriedades: • Comutati!a: o% \ •
Associati!a:
•
istributi!a:
o%
5 $%e ,os fora a aceitar %m fato s%rpree,de,te sobre aritm*tica com po,to f"%t%a,te: /as trJs re+ras ape,as a com%tativa * sempre v"ida. !s propriedades associativa e distrib%tiva ,em sempre ocorrem. ) ,ão esto% fa"a,do de va"ores de +ra,deas difere,tes. )is %m e&emp"o: dou;le @ .B = (.L = .3) dou;le Q (.B = .L) = .3 /* Nm!rimir8 V@ 7 di"erente de QX& */ i" (@ Q) !uts(@ 7 igual a Q) else !uts(@ 7 di"erente de Q)
5 prob"ema ocorre por$%e +raas ao arredo,dame,to e&istem erros difere,tes para cada %ma das represe,taes de va"ores acima. 5 va"or 0.2 por e&emp"o pode ter %m erro de arredo,dame,to %m po%$%i,o maior do $%e a represe,taão do va"or 0.1 e 0.3 por e&emp"o. !ssim o va"or 0.> ca"c%"ado a partir dos va"ores apro&imados de 0.2 e 0.3 ,ão * e&ato * arredo,dado. 5 $%e $%ero dier * $%e vocJ ,ão est ve,do adies e&atas ,o e&emp"o ai de cima. 5 03 ca"c%"ado a partir da adião de 01 e 02 ,ão * o mesmo 03 $%e * adicio,ado em se+%ida ,o caso da varive" y. VocJ obter %m va"or %m po%co fora do 0( esperado. ! mesma coisa aco,tece com o c"c%"o da varive" 4 mas com %m erro %m po%co difere,te do 0( ca"c%"ado para y... !ssim os dois 0( serão difere,tesE Lembra-se $%e o va"or de * maior $%a,do o va"or estiver e,tre 0> e 10 do $%e $%a,do e"e est e,tre 02> e 0> e vai fica,do me,o r $%a,do a fai&a vai se, do esca"o,ada por %m fator de B !o somar 02 e 03 obtemos 0> soma,do a %m +ra,de;. ) ao somar 01 e 02 obtemos %m 03 com %m z me,or $%e o o%tro. R%ero dier:
!o somar os va"ores resta,tes teremos a adião de erros parecidos G $%e s%postame,te ter
5 $%e obviame,te far 4 e y serem difere,tesE )ssas ac%m%"aes de erros tamb*m ocorrem em m%"tip"icaes e divises. /a< a propriedade distrib%tiva tamb*m fa"a. 141
Veremos mais adia,te como "idar com comparaes de va"ores em po,to f"%t%a,te "eva,do esses pe$%e,os erros em co,sideraão.
Kue tal trabal"ar na base decimal. ao inv5s da binria, /esde a especificaão ?65 C99 Gpe"o $%e me "embroH a "i,+%a+em C poss%i mais 3 tipos de po,to f"%t%a,te; a"*m dos .loat double e long double . rata-se de tipos de po,to f"%t%a,te decimais: ODecimal2H ]Decimal36 e ODecimalH+. )sses trJs ,ovos tipos estão ,a especificaão ?))) 7>4 desde 200'. 5 ,Mmero $%e se+%e o tipo di o tama,o do mesmo em bits. Aas s%a represe,taão i,ter,a * e$%iva"e,te S decima" ,ão a bi,ria. !ssim o va"or armae,ado * mais o% me,os codificado como: 5,de YdY * %m d<+ito e,tre 0 e 9 YmY * a ma,tissa Gem decima"H e o resto * parecido com os formatos de po,to f"%t%a,te bi,rio mas em base 10. ?sso permite a represe,taão da$%e"es va"ores: 01\ 02\ ... Aas e&istem a"+%,s prob"emas ao "idar com esses tipos: 5 primeiro * $%e e"es são po%co performticos. I depe,dJ,cia de %so de f%,es especiais para "idar com e"es. 5 processador ,ão os s%porta ,ativame,te. ) a codificaão dos va"ores * %m ta,to comp"e&a. 5 se+%,do prob"ema * $%e f%,es da libc como &rint., ,ão tJm s%porte a esses tipos. Pe"o me,os ,ão a "ibc pr*-compi"ada pe"o ma,te,edor das distrib%ies mais famosas do Li,%&... ma ma,eira de verificar se a libc s%porta esses tipos * per+%,ta,do ao compi"ador: gcc -, 251 | grep --e%a$le-decimal-&loa#
Provave"me,te o gre& ,ão e,co,trar essa stri,+ ,a "ista de f"a+s %sados ,a co,fi+%raão do +cc >'. 5 fato de &rint. ,ão s%portar os tipos ODecimal ,ão si+,ifica $%e e"es ,ão possam ser %sados. Para mostr-"os teremos $%e co,vertJ-"os para .loat o% double e %sar a f%,ão &rint.. ! co,versão * feita atravpes de f%,es built5in do compi"ador. Co,s%"te a doc%me,taão do CC... 5%tra coisa: 5s va"ores "iterais tJm %m s%fi&o especia". Por e&emp"o: EJecimal3L d3L B.Ld" EJecimalSA dSA .Add EJecimalBLR dBLR .3dl
/* d" Vdecimal "loatX */ /* dd Vdecimal dou;leX */ /* dl Vdecimal lond dou;leX */
Lembre-se tamb*m $%e esses tipos ,ão reso"vem o prob"ema da precisão. @Mmeros como 2X3 co,ti,%am se,do irracio,ais... Ai,a opi,ião sobre os tipos po,to f"%t%a,te decimais * $%e e"es são i,Mteis por ca%sa do prob"ema da bai&a performa,ce em re"aão aos tipos em po,to f"%t%a,te bi,rios.
A precisão decimal de um tipo 'loat ou double !t* a+ora fa"amos da precisão de %m .loat sob o po,to de vista bi,ario. Para ca"c%"ar a precisão decima" +rosseira basta %sar %m "o+ar' 5s caracteres Y-Y ,o +rep foram escapados; para $%e e"e ,ão co,f%,da a re+%"ar e&pressio, com %m parKmetro.
142
&decimal'. Para o tipo double &decimal17.
! especificaão de C ,os di $%e a precisão do tipo .loat * de pe"o me,os ( di+itos. ) do tipo double 1>. ?sso * co,die,te com a f=rm%"a acima. @ote $%e mesmo $%e te,amos %m va"or do tipo 1234>(7}1033 isso ,ão * a mesma coisa $%e %m va"or i,teiro de 34 a"+arismos Gdes"oca,do a v
Comparando valores em ponto 'lutuante raas ,os c"c%"os va"ores em po,to precisamos %m eitoaos de pe$%e,os comparar arredo,dame,tos dois va"ores pr=&imos; como com se fossem i+%ais. Faerf"%t%a,te %ma comparaão do de tipo abai&o como vimos a,tes pode ser prob"emtica: i" (@ Q) 9
6e 4 e y forem seme"a,tes diferi,do em %m erro pe$%e,o e,tão e"as ,ão serão i+%ais. Por e&emp"o ao comparar %ma co,sta,te 01 com %m va"or ca"c%"ado $%e dJ 01 como res%"tado de %ma operaão aritm*tica teremos pe$%e,os erros $%e tor,am ambos difere,tes e,tre si. ) a comparaão acima vai fa"ar G4 y ser fa"soH. ma ma,eira me"or de +ara,tir $%e dois va"ores pr=&imos seam co,siderados como i+%ais * %sa,do %m fator de difere,a m<,ima. 5 va"or de Gepsi"o,H: 6e a difere,a e,tre 4 e y for me,or o% i+%a" a e,tão podemos co,sider-"os i+%ais. 5 motivo de termos $%e comparar o va"or abso"%to da difere,a com * por$%e ta,to 4 $%a,to y podem ser ,e+ativos. ?sso ,os d %m macro: #de"ine equal(a,;) ("a;s((a)-(;)) < KGDE4FNG2U)
Aas e&iste %m prob"ema... Lembre-se $%e o va"or de ser esca"o,ado por $%a,do . 5 va"or de pode ser pe$%e,o demais para a maioria das comparaesE ma so"%ão * obter o va"or de re"ativo ao maior va"or dos dois se,do comparados:
5 macro para o c"c%"o desse erro re"ativo; ficaria assim: inline int "loatEcm!("loat a, "loat ;) "loat Z "a;s(a), M "a;s(;) "loat di"" Z M return di"" < (KGDE4FNG2U * ma@(Z, M))
! especificaão ?65 C99 ,os d os se+%i,tes macros para comparar va"ores em po,to f"%t%a,te Gdefi,idos em mat/9/H: isgreater>) isgreaterequal>) isless>) islessequal>) e islessgreater>). 5 M"timo compara pe"a difere,a. )stra,ame,te e"e ,ão for,ece %m isequal>). sar para decidir como comparar va"ores parece ser %ma boa id*ia especia"me,te $%a,do %samos o erro re"ativo. !o s%btrair dois va"ores m%ito parecidos o res
se% pr=prio . !"is * recome,dve" $%e o faaE Por e&emp"o se mi,as co,tas ,ão precisam ter mais $%e 4 a"+arismos depois da v
*ão compare tipos de ponto 'lutuante di'erentes R%a,do vocJ "ida com co,sta,tes "iterais em C est atre"a,do a e"as %m tipo defi,ido de tipo. 6e escreve 1.1; este tipo * por defa%"t double. 6e escreve 1.1f; o% 1.1F; o tipo * .loat. Comparar 1.1 com 1.1f pode ser desastroso. !s precises são difer,tes e porta,to os erros de arredo,dame,to são difere,tes. @o c=di+o abai&o: "loat @ B.B i" (@ & B.B) !rint"(FOo di"erentes&)
Provave"me,te obter a stri,+ são difer,tesE; impressa. 5 deta"e * $%e o compi"ador co,verter o va"or double 1.1 para o tipo .loat fae,do os arredo,dame,tos ,ecessrios e o atrib%ir a 4 em tempo de compilação. Aas ,o YifY a co,versão ser feita em runtime e ,o se,tido co,trrio... Pe acordo com a especificaão da "i,+%a+em C sempre co,verte tipos co,f"ita,tes para a$%e"es de maior precisão. !,tes de comparar 4 com 1.1 a varive" ser co,vertida para double Gem runtimeH e %sa,do as re+ras de arredo,dame,to do processador ,ão do compi"adorE 5% sea vocẽ est compara,do "ara,as com maãs... Ne+ra +era": Aa,te,a se%s tipos em po,to f"%t%a,te sob co,tro"e... 6e tiver f"oats compare-os com f"oats... 6e forem do%b"es compare-os com do%b"es. !"+%mas ma,eiras de co,se+%ir isso: •
6e $%iser %sar f"oats %se o s%fi&o YfY ,os va"ores "iterais. 6)APN)E
•
se ty&e casting se ,ão p%der %sar o s%fi&o.
5 fra+me,to de c=di+o acima poderia ser escrito assim: "loat @ B.B" i" (@ & B.B") ...
7vite over'lows ma dica imp orta,te * sobre over.los. )specia"me,te se vocJ $%er %sar po,to f"%t%a,te para ca"c%"ar potJ,cias. 5 e&emp"o c"ssico * o do famoso teorema de Pit?goras: ! e$%aão parece i,ofe,siva mas se %m dos va"ores de a o% b esto%rarem por ca%sa da e"evaão da potJ,cia ao $%adrado vocJ ter %m va"or i,v"ido de,tro da rai $%adrada e o res%"tado provave"me,te ser %m a. Como evitar issoB @o caso de Pit?goras o m*todo tradicio,a" * e"evar ao $%adrado ape,as o me,or va"or retira,do o maior va"or da rai $%adrada assim:
144
6e ,ão ca%sa %m under.lo e,tão a e$%aão ,ão criar %m over.lo de forma a"+%ma... ) s= para satisfaer s%a c%riosidade essa ,ova i,terpretaão do teorema pode ser e,te,dida assim:
importa,te "embrar $%e os va"ores de,orma"iados e&istem para +ara,tir %m under.lo +rad%a" mas para over.los isso ,ão e&iste. !ssim * poss a) sa!(a, ;) i" (&a) return ; return a * sqrt"(B." = (;*;)/(a*a))
-onto 'ixo 6e vocJ precisa "idar com va"ores mo,etrios e ,ão $%er +astar m%ito tempo a,a"isa,do os efeitos de ac%m%"aão erros em po,to f"%t%a,te sempre pode %sar a t*c,ica do po,to fi&o. /ifere,te do po,to f"%t%a,te essa t*c,ica permite $%e operaes f%,dame,tais seam feitas em inteiros como se co,tivessem va"ores em po,to f"%t%a,te. !ritm*tica com i,teiros * bem mais ve"o e mais simp"es. @o caso de va"ores mo,etrios precisamos ape,as de d%as casas depois da v #de"ine +WGB(@) ((@) * B) #de"ine JNB(@) ((@) / B) /* Hotinas de conversOo */ long "loatEtoEmoneQ("loat @) return (long)"loor"(@ * B.") "loat moneQEtoE"loat(long @) return ("loat)@ / B." /* 2!eraT\es elementares */ // long moneQEadd(long @, long // long moneQEsu;(long @, long long moneQEmul(long @, long Q) long moneQEdiv(long @, long Q)
Q) return @ = Q Q) return @ Q return JNB(@ * Q) return +WGB(@) / Q
Com essa t*c,ica todo va"or em po,to f"%t%a,te * m%"tip"icado por 100. m va"or 1> tor,a-se 1>0. m va"or 3.141> tor,a-se 314. 6e vocJ $%iser %m arredo,dame,to para cima; basta s%bstit%ir a f%,ão de co,versão .loatOtoOmoney por: long "loatEtoEmoneQL("loat @) return (long)ceil"(@ * B.")
!dies e s%btraes podem ser feitas diretame,te o% se preferir via f%,es moneyOadd e moneyOsub Gcome,tadasH. 5 deta"e todo est ,as m%"tip"icaão e divisão: $%e m%"tip"icamos o va"or ori+i,a" di+amos Y&Y por 100 o $%e temos * . !o m%"tip"icar & por # temos o% e,tão . Fica c"aro $%e temos %ma m%"tip"icaão por 100 14>
adicio,a" ,essa operaão da< a ,ecessidade de dividir o va"or fi,a" por 100. Com a divisão o prob"ema * seme"a,te... !o dividir dois va"ores esca"o,ado s por 100 acabamos sem esca"o,ame,to a"+%m. !fi,a" ,os d . /a< a ,ecessidade de m%"tip"icar o divide,do por 100 a,tes de rea"iar a divisão. Para %sar as f%,es basta faer a"+o assim: long @, Q, r @ "loatEtoEmoneQ(B.") Q "loatEtoEmoneQ(33.L") r moneQEmul(@, Q) !rint"(B. * 33.L %.L"'n, moneQEtoE"loat(r))
!s operaes serão feitas com i,teiros $%e são e&atos e as M,icas co,verses ocorrem para obte,ão dos va"ores. ) $%e estamos "ida,do com va"ores e&atos comparaes tamb*m ,ão ca%sam prob"emas... 5%tra ve,ta+em: 5 tipo long s%porta armae,ar va"ores at* w9}10 1'. A%"tip"ica,do por 100 "imitamos esse va"or para . ?sso * %m 9 se+%ido de 1( eros o% 90 $%i,ti"es com d%as casas decimais;. 6%ficie,te para $%a"$%er ap"icaão $%e "ida com di,eiro ,ãoB
odo x12&23 e ponto 'lutuante R%a,do fa"ei sobre mist%rar C com assemb"# fa"ei sobre a co,ve,ão de camada e mostrei $%e os va"ores em po,to f"%t%a,te são passados atrav*s dos re+istradores UAA0 at* UAA7. ?sso $%er dier $%e a ar$%itet%ra &'(-(4 %sa 66). !co,tece $%e po,to f"%t%a,te =bviame,te e&istia a,tes dessa ar$%itet%ra e %m co-processador matemtico Gi,corporado ,a ar$%itet%ra ?,te" desde os 4'(H era ,ecessrio. ! forma como o co-processador matemtico f%,cio,a * %m po%co difere,te do 66). )"e poss%i %ma pi"a de ' ,
O tipo long double 5 padrão ?))) 7>4 $%e dita as re+ras para os ,Mmeros em po,to f"%t%a,te bi,rios especifica $%atro tipos em s%a M"tima revisão G200'H: single &recision double &recision e4tended &recision e /al. &recision. ! precisão este, dida * co,ecida por long double e foi ado tada pe"a ?))) depois $%e a ?,te" i,corporo% em se% co-processador matemtico '0'7 o armae,ame,to de '0 bits. )sse ,ão * %m tipo " m%ito ami+ve" mas a ma,tissa tem (4 bits Gco,tra os >4 do tipo double e dos 24 do tipo .loatH e o e&poe,te * maior tamb*m G1> bitsH. 5 a"+arismo 1 imp"
e&emp"o e"es terão $%e ser ,ecessariame,te co,vertidos para long double pe"o processador e para isso precisarão ser arredo,dados antes da operaão ser feita. /a< temos trip"o arredo,d ame,to: 5 arredo,dame,to de cada opera,do tra,sform ado para long double se+%ido do arredo,dame,to da operaão e por fim o arredo,dame,to do res%"tado de vo"ta ao tipo ori+i,a". ?sso não ocorre com 66). Qem... ocorrer se vocJ te,tar tra,sformar %m .loat ,%m double o% viceversa mas a car+a de .loats e doubles * direta se vocJ %sa 66) o% 66)2. 5pereraes %sa,do 66) mesmo ,o modo i3'( te,dem a ser mais precisas do $%e $%a,do %samos o '0'7 Go defa%"t ,o modo i3'(H... Fe"ime,te ,o modo &'(-(4 66) e 66)2 são os defa%"ts.
147
14'
Capítulo %! Instruç1es >stendidas )m 199( a ?,te" a,%,cio% %ma e&te,são para a s%a "i,a de processadores camada AAU. ! coisa ca%so% %m a"voroo por$ %e AAU * %ma si+"a propriet ria $%e si+,ifica 'ulti'edia etension. ! ideia era $%e os ,ovos processadores "idariam com m%"timedia; Go% sea v e i7H te,dem a s%port-"o. Aostrarei as difere,as mais adia,te. !"*m das e&te,ses AAV 66) e !VU o%tras foram i,corporadas aos processadores: QA? GQit Aa,ip%"atio, ?,str%ctio,sH FA! GF"oati,+ poi,t A%"t#p"# a,d !ddH e F1(C GF"oati,+ poi,t 1( bit Co,versio,H.
SS7 Para processar vrios dados ao mesmo tempo 6?A/ %sa re+istradores especiais $%e co,t*m co,%,tos de dados. @o caso da p"ataforma &'(-(4 temos 1( re+istradores $%e podem co,ter at* 1( b#tes Go% ' YsortsY o% 4 Yi,tsY o% Yf"oatsY o% 2 Ydo%b"esY e at* %m +ra,de ,Mmero i,teiro de 12' bits de tama,oH. 6ão os re+istradores UAA0 at* UAA1>:
Figura R: "a&acidade dos registradores '' >((E)9
66) vem em diversos sabores. 66) 66)2 666)3 Gsim são trJs Y6YH 66)4.1 e 66)4.2. Cada %m adicio,a ao a,terior %m co,%,to de i,str%es especia"iadas.
149
8unç6es !intrinsecas# para SS7> ! ma,eira de acessar esses re+istradores especiais; em C * atrav*s de tipos especiais de c"asses de armae,ame,to. 5 tipo OOmH+ Gcom dois Y%,derscoresYH e$%iva"e a %m re+istrador 66) o% a 1( b#tes depe,de,do de o,de o compi"ador esco"er armae,-"o. )ste tipo divide %m re+istrador UAA em 4 f"oats. emos ai,da o tipo OOmH+i e OOmH+d. 5 primeiro * %sado para "idar com os re+istradores UAA como se co,tivessem va"ores i,teiros Gi,c"%sive de 12' bitsH e o o%tro * %sado para "idar dividir os re+istradores UAA em 2 doubles. 5%tra va,ta+em de %sar o tipo * $%e e"e * a%tomaticame,te a"i,ado em 1( b#tes. )sse a"i,ame,to * importa,te $%e a car+a de %m re+istrador 66) atrav*s de %m co,%,to de dados desa"i,ados ,a mem=ria co,some pe"o me,os 1 cic"o de m$%i,a adicio,a". 5 a"i,ame,to tamb*m * importa,te com re"aão aos caces. @%m cace com b"oco de (4 b#tes podemos ter a car+a de at* 4 re+istradores 66) atrav*s de %m M,ico b"oco de cace. Para e&emp"ificar a m%"tip"icaão de matries de 4 "i,as e 4 co"%,as o,de cada e"eme,to * %m Yf"oatY cabe comp"etame,te em dois b"ocos de cace G$%e estão ,a mesma "i,aEH. 6e vocJ obter o e,dereo de %ma varive" do tipo OOmH+ vai sempre ter os 4 bits me,os si+,ificativos do e,dereo "i,ar erados: 9 EEmBLR @ 9 !rint"(@%BSlI'n, (unsigned long)@) 9
5 fra+me,to de c=di+o acima imprimir a"+o como 0&0000000000(010>0. @ão importa o,de o tipo OOmH+ estea esse Y0Y ,os bits me,os si+,ificativos do e,dereo sempre estarão erados. 5 prob"ema com o tipo OOmH+ * $%e operaes simp"es ,ão devem ser feitas diretame,te. @o CC temos e&ter,ses $%e possibi"itam %sar operaes bsicas com o tipo Ov6si c%o ape"ido * OOmH+. Aas isso ,ão * v"ido para o%tros compi"adores. VocJ pode faer a"+o assim por e&emp"o: EEmBLR @, Q, 6 9 /* carrga Q e 6 de alguma "orma... */ /* Kunciona no C, mas 7 o `eito errado& */ @ Q = 6
Pode at* mesmo adicio,ar o% s%btrair Go% m%"tip"icar o% dividirH co,sta,tes: EEmBLR Q, @ B, L, 3, A 9 Q @ = B /* Ka6 Q @ = B,B,B,B */
/a ma,eira tradicio,a" para rea"iar opera es precisamos faer %so de f%,es intrinsecas. ma f%,ão i,tri,seca ,o caso do 66) * a$%e"a $%e * trad%ida diretame,te para %ma i,str%ão em assemb"#. ! operaão de adião acima ficaria assim: @ EmmEaddE!s(Q, 6) /* +esma coisa que @ Q = 6 */
6e vocJ s%por $%e o compi"ador esco"a Y&Y se,do &mm0 Y#Y se,do &mm1 e YY se,do &mm2 a "i,a acima ser trad%ida diretame,te para: mova!s @mm, @mmB add!s @mm, @mmL
5 motivo para essa comp"icaão est %stame,te ,a fa"ta de i,fomaes $%e o compi"ador tem com re"aão a como os re+istradores UAA serão divididos ao %sar o tipo. )ssa i,formaão * codificada ,o pr=prio ,ome da f%,ão i,tr<,seca Go% ,a i,str%ão em assemb"#H. @o caso acima YpsY si+,ifica 1>0
&acked singles; o $%e di ao processador $%e dividiremos o re+istrador UAA em $%atro .loats. 6e %sssemos o s%fi&o YpdY estar9.
7xemplo do produto escalar )is %m e&emp"o simp"es: m prod%to esca"ar * a m%"tip"icaão corde,ada por coorde,ada de %m vetor. @%ma ap"icaão matemtica o% ,%m gra&/ics engine tridime,sio,a" poder
?sso pode ser trad%ido ,%ma f%,ão de ma,eira bem simp"es: struct vectorEs "loat @, Q, 6 "loat dot(struct vectorEs *a, struct vectorEs *;) return (a->@ * ;->@) = (a->Q * ;->Q) = (a->6 * ;->6)
Compi"a,do e verifica,do o c=di+o assemb"# +erao com a m&ima otimiaão temos: dot movss movss mulss mulss addss movss mulss addss ret
@mm, @mmB, @mm, @mmB, @mm, @mmB, @mmB, @mm,
dord dord dord dord @mmB dord dord @mmB
!tr !tr !tr !tr
[rdi] [rdi=A] [rsi] [rsi=A]
!tr [rdi=R] !tr [rsi=R]
! primeira imp"eme,taão %sa,do 66) $%e poder union @mmEu struct "loat @, Q, 6 /* 4stou ignorando o A elemento aqui& */ s EEmBLR @ "loat dotEsse(EEmBLR a, EEmBLR ;) union @mmEu u u.@ EmmEmulE!s(a, ;) return u.s.@ = u.s.Q = u.s.6
>9 ma e&ce"e,te referJ,cia para as f%,es i,tr<,secas ttps:XXsoft8are.i,te".comXsitesX"a,di,+pa+eX?,tri,sics%ideX
pode
ser
e,co,trada
o,"i,e
em
1>1
5 $%e me"ora %m po%co as coisas: dotEsse mul!s @mm, @mmB mova!s @mmord !tr movss @mm, dord addss @mm, dord addss @mm, dord ret
[rs!-LA], @mm !tr [rs!-LA] !tr [rs!-L] !tr [rs!-BS]
)&istem a"+%,s a%stes fi,os $%e podemos faer para me"orar isso mas o i,teressa,te mesmo * saber $%e e&iste %ma i,str%ão 66) $%e fa %stame,te %m prod%to vetoria" se se% processador tiver s%porte ao 66) 4.1: "loat dotEsseAB(EEmBLR a, EEmBLR ;) return EmmEcvtssE"3L(EmmEd!E!s(a, ;, @_B))
! f%,ão i,tri,seca OmmOd&O&s m%"tip"ica cada parte de re+istradores 66) re"acio,ados com a mscara dos 4 bits s%periores do terceiro parKmetro e os soma. /epois armae,a o res%"tado ,as posies dos 4 bits i,feriores da mscara. Por isso o va"or 0&71 G7 * a mscara para os 3 f"oats i,feriores de YaY e YbY\ e 1 * a mscara para co"car o res%"tado ,a posião 0 do re+istrador res%"ta,teH. ! f%,ão i,stri,seca OmmOcvtssO.2H pe+a o f"oat ,a posião 0 do tipo ]]m12' e retor,a %m Yf"oatY. ?sso * e"imi,ado ,o c=di+o fi,a" como pode ser visto abai&o mas * ,ecessrio se $%isermos "idar com o res%"tado como %m tipo Yf"oatY simp"es em C: dotEsseAB d!!s @mm, @mmB, BB3 ret
@ada ma" %B /e ' i,str%es ca e fi,a"me,te me"oramos para %ma s=. ?sso po%pa %m bocado de espao mas essa otimiaão fi,a" * esse,cia"me,te o mesmo $%e a f%,ão a,terior T ta"ve po%pa,do %m M,ico cic"o de m$%i,a... !s d%as M"timas f%,es são bem me"ores $%e a primeira. ),$%a,to a primeira toma e,tre 2> e 30 cic"os as d%as M"timas tomam cerca de 14 de acordo com a doc%me,taão da ?,te". 5% sea as d%as M"timas f%,es tiveram %m a%me,to de performa,ce de cerca de 100q em re"aão S primeira.
;ma !otimização# (ue 'al"ou M o produto vetorial @%m es$%ema ,orma" de processame,to para ca"c%"ar o prod%to vetoria" de dois vetores tridime,sio,ais G&#H ter@ (vB->Q * vL->6) vout->Q (vB->6 * vL->@) vout->6 (vB->@ * vL->Q)
*vout, const struct vectorEs *vB, const struct vectorEs *vL) - (vB->6 * vL->Q) - (vB->@ * vL->6) - (vB->Q * vL->@)
5 c=di+o +erado mesmo com otimiaão * mais o% me,os este:
1>2
cross movss @mm3, dord !tr [rd@=R] movss @mmB, dord !tr [rsi=R] movss @mm, dord !tr [rsi=A] movss @mmL, dord !tr [rd@=A] mulss @mm, @mm3 mulss @mmL, @mmB su;ss @mm, @mmL movss dord !tr [rdi],@mm movss @mmL, dord !tr [rd@] movss @mm, dord !tr [rsi] mulss @mmB, @mmL mulss @mm3, @mm su;ss @mmB, @mm3 movss Jk2HJ DH [rdi=A],@mmB mulss @mm, dord !tr [rd@=A] mulss @mm, @mmL, @mmL dord !tr [rsi=A] su;ss movss dord !tr [rdi=R],@mm ret
) a$%i %saremos a m+ica do 66). Nepare $%e cada compo,e,te * m%"tip"ado com o%tro difere,te. emos: ( y 1 z1 4 1)⋅( z2 4 2 y 2 ) [ ( z 1 4 1 y1 )⋅( y2 z2 42)
),tão t%do o $%e temos $%e faer * embara"ar; as coorde,adas m%"tip"ic-"as e depois s%btra<"as. ! roti,a fica assim: #include <@RSintrin.h> EEmBLR crossEsse(EEmBLR vB, EEmBLR vL) return EmmEsu;E!s( EmmEmulE!s( EmmEshu""leE!s(vB, vB, E++EF$WKKG4(3,B,L,)), EmmEshu""leE!s(vL, vL, E++EF$WKKG4(3,L,,B)) ), EmmEmulE!s( EmmEshu""leE!s(vB, vB, E++EF$WKKG4(3,L,,B)), EmmEshu""leE!s(vL, vL, E++EF$WKKG4(3,B,L,)) ) )
Compi"cado ,ãoB Aas e"a parece ser mais rpida $%e a f%,ão cross: crossEsse
mova!s mova!s shu"!s shu"!s shu"!s shu"!s mul!s mul!s su;!s
@mm3, @mmL, @mm3, @mmL, @mmB, @mm, @mmL, @mm, @mm,
@mmB @mm @mmB, @mm, @mmB, @mm, @mm3 @mmB @mmL
LBS LL LL LBS
ret
Podemos ai,da me"orar a roti,a %m po%co mais e"imi,a,do %m s%ff"e;:
1>3
EEmBLR crossLEsse(EEmBLR vB, EEmBLR vL) EEmBLR r r EmmEsu;E!s( EmmEmulE!s(vB, EmmEshu""leE!s(vL, vL, E++EF$WKKG4(3,,L,B))), EmmEmulE!s(vL, EmmEshu""leE!s(vB, vB, E++EF$WKKG4(3,,L,B))) ) return EmmEshu""leE!s(r, r, E++EF$WKKG4(3,,L,B))
) o res%"tado parece ai,da mais promissor: crossLEsse mova!s @mmL,@mm shu"!s @mmL,@mm,LB mul!s @mmL,@mmB shu"!s @mmB,@mmB,LB mul!s @mmB,@mm su;!s @mmB,@mmL shu"!s @mmB,@mmB,LB mova!s @mm,@mmB ret
)is a per+%,ta de 1 mi"ão de d="ares: 6er $%e a f%,ão crossHOsse * mais rpida $%e crossOsseB ) $%a,to a primeira roti,aB Por i,crqEH dada a comp"e&idade apare,te das f%,es $%e %sam 66)E )% ma,teria a M"tima some,te pe"o fato de"a ser me,or.
;ma otimização bem sucedida: ultiplicação de matrizes /adas d%as matries de 4 "i,as e 4 co"%,as Gco"%m, maor ao esti"o 5pe,LH a m%"tip"icaão de"as prod%ir %ma terceira matri. 6e i,formarmos essas matries em forma de vetores de 1( f"oats a roti,a c"ssica para a m%"tip"icaão * a descrita ,a f%,ão 'atri4646'ulti&ly e a versão 66) otimiada est "istada em 'atri4646'ulti&ly((E: /* Zo inv7s de usar arraQs ;idimensionais, uso arraQs de BS "loats... */ void +atri@A@A+ulti!lQ("loat *out, const "loat *a, const "loat *;) int ro, col, "or (ro ro < A ro==) "or (col col < A col==) out[A*ro=col] ." "or ( < A ==) out[A*ro=col] = a[A*=col] = ;[A*ro=]
1>4
/* Wsando um !ouco de criatividade !ara lidar com os registradores de BLR ;its do FF4, essa "unTOo "a6 a mesma coisa que a anterior& */ void +atri@A@A+ulti!lQFF4("loat *out, const "loat *a, const "loat *;) int i, ` EEmBLR aEcolumn, ;Ecolumn, rEcolumn "or (i ;Ecolumn aEcolumn rEcolumn
i < BS i = A) EmmEsetBE!s(;[i]) EmmEloaduE!s(a) EmmEmulE!s(aEcolumn, ;Ecolumn)
"or (` B, ` < A `==) ;Ecolumn EmmEsetBE!s(;[i=`]) aEcolumn rEcolumn EmmEloaduE!s(a[`*A]) EmmEaddE!s( EmmEmulE!s(aEcolumn, ;Ecolumn), rEcolumn ) EmmEstoreuE!s(out[i], rEcolumn)
! difere,a de performa,ce das d%as f%,es ce+a a ser de $%ase 1000 cic"os de c"ocD o,de a se+%,da * mais rpida. )m mi,as medies a primeira +asta cerca de 2'00 cic"os e,$%a,to a se+%,da 1'00. 5% sea %m a%me,to de performa,ce de >>qE
7 (uando ao AEN, !VU G1dvanced ector etensionH * em essJ,cia a mesma coisa $%e 66) com re+istradores maiores... @o !VU os re+istradores UAA são este,didos de 12' bits de tama,o para 2>( bits e são re,omeados para WAA. ),$%a,to escrevo a ?,te" prete,de "a,ar ,ova ar$%itet%ra de processadores $%e poss%em s%porte ao !VU->12... ! mesma coisa $%e 66) e !VU mas com re+istradores de >12 bits camados a+ora de OAA. Para !VU e !VU2 e&istem os tipos i,tr<,secos OOmHN3 OOmHN3i e OOmHN3d. )"es f%,cio,am da mesma ma,eira $%e os tipos OOmH+ e se%s derivados ,o caso do 66) s= $%e s%portam o dobro de compo,e,tes e * c"aro tJm o dobro de tama,o. @o !VU->12 temos o tipo OOmNH e os mesmos derivados. Outras extens6es Dteis: J) e 8A a,to a ?,te" $%a,to a !A/ estão de tempos em tempos adicio,a,do ,ovas i,str%es em se%s processadores e fae,do disso %m padrão da i,dMstria. ! e&te,são QA? "ida com ma,ip%"aão de bits G Bit 'ani&ulation InstructionsH e a FA! fa %m mist%reba de operaes em po,to f"%t%a,te GFused 'ulti&ly and 1dd InstructionsH. ! primeira e&te,são QA? for criada para a+"%ti,ar em %ma M,ica i,str%ão coisas $%e podem ser feitas com co,%,tos de i,str%es como !@/ 5N e 6IL Go% 6INH. Por e&emp"o se $%isermos erar todos os bits a partir da posião 31 de N/? sem a"terar se% va"or e co"oca,do o res%"tado em N!U podemos faer: mov and
ra@,rdi ra@,@3"""""""
usando ZUJ com uma m8scara
! mscara * co,f%sa $%e temos $%e co,tar as posies dos bits a partir de ero. ! i,str%ão 1>>
QOI? tor,a isso mais fci" mas ,ão mais performtico: mov rd@,3 ;6hi ra@,rd@,rd@
HJN ter8 seus ;its a !artir de HJI 6erados e tudo co!iado !ara HZI.
Fiemos esse,cia"me,te a mesma coisa $%e o !@/ fa mas QOI? * mais "e,ta $%e e"a %sa o %m prefi&o. ?sso ,ão $%er dier $%e QA? sea i,Mti". Co,sidere essa o%tra ,ecesssidade: 6%po,a $%e vocJ $%eira co,tar $%a,tos bits esteam setados ,%m re+istrador. Com i,str%es tradicio,ais poder
! e&te,são QA? vem a ca"ar ,este caso por$%e podemos faer isso com ape,as %ma i,str%ão e sem a"terarmos o co,teMdo de NCUN/U e N/?: !o!cnt ra@,rdi ret
QA? tamb*m poss%i i,str%es i,teressa,tes para e&traão de bits e ma,ip%"aes "=+icas f%,didas; Gcomo !@/@ o,de * feito %m !@/ se+%ido de %m @5H... Para abi"itar o %so de QA? ,o CC se se% processador s%portar %se as opes -mbmi o% -mbmi2. ! e&te,são FA! adicio,a e&te,ses ao 66) e ao !VU para "idar com e$%aes "i,eares do tipo: y = a⋅4 + b
!o i,v*s de %sarmos d%as i,str%es %ma para m%"tip"icar e o%tra para somar as d%as estão f%,didas; Gf%sedH ,%ma mesma i,str%ão. 6e vocJ abi"itar FA! ,o +cc via opes -mfma o% -mfma4 sempre $%e compi"ador topar com %ma e$%aão "i,ear em po,to f"%t%a,te e"e te,tar %sar a e&te,são +era,do c=di+os me,ores e possive"me,te mais rpidos. 6e tivermos %ma f%,ão do tipo: "loat ma("loat a, "loat @, "loat ;) return a*@ = ;
! difere,a das d%as verses Gcom e sem FA!H seria assim: versOo B ma mulss @mm,@mmB addss @mm,@mmL ret -----%<----- corte aqui -----%<---- versOo L ("ma) ma v"maddss @mm, @mm, @mmB, @mmL ret
6%speito $%e a difere,a rea" sea ape,as %ma pressão me,or ,os caces $%e a se+%,da versão +era c=di+o me,or:
1>(
o$6d7mp -d -M i%#el-m%mo%ic #es#1.o testB.o "ile "ormat el"SA-@RS-SA Jisassem;lQ o" section .te@t "3 " f cB mulss @mm,@mmB A "3 " R cL addss @mm,@mmL R c3 ret o$6d7mp -d -M i%#el-m%mo%ic #es#2.o testB.o "ile "ormat el"SA-@RS-SA Jisassem;lQ o" section .te@t cA e3 "f Sa cL B v"maddss @mm,@mm,@mmB,@mmL S c3 ret
C"aro $%e para f%,es mais comp"icadas te,do %ma f%,ão especia"iada para ca"c%"ar e$%aes "i,eares evita m%itas movime,taes de re+istradores UAA para temporrios. Pote,cia"me,te a%me,ta,do a performa,ce do c=di+o fi,a".
1>7
1>'
Capítulo 4! Dicas e macetes )ste cap
Ealores booleanos: Algumas dicas interessantes em C @%ma comparaão ,a "i,+%a+em C %m va"or ero * sempre co,siderado fa"so. %m va"or difere,te de ero * sempre verdad eiro. ) ao mesmo tempo o tipo int * o tipo padrão para a ava"iaão de e&presses boo"ea,as ,o e,ta,to a re+ra do ero e do ,ão-ero va"e para $%a"$%er tipo i,c"%i,do po,teiros. 5 s
?sso imprimir os va"ores 1 e 0 ,esta ordem. 5 compi"ador pode i+,orar a ava"iaão e se ater ape,as S primeira re+ra e comparar ape,as co,tra o va"or ero se isso criar c=di+o mais performtico mas se vocJ $%iser %sar o res%"tado de %ma e&pressão boo"ea,a os va"ores 1 e 0 são como disse +ara,tidos. Por e&emp"o as i,str%es abai&o são e$%iva"e,tes: i" (@ < L) Q==
/* adiciona B a Q se @ < L. */
Q = (@ < L)
/* adiciona B a Q se @ < L& */
5%tra dica "e+a" * o %so do operador boo"ea,o E d%as vees. 5 operador E serve para i,verter o va"or bo"ea,o $%e o se+%e se a e&pressão S direita da e&c"amaão for 0 o res%"tado ser 1 e vice-versa. !o %sar EE ma,teremos o va"or boo"ea,o ori+i,a" Gmas se tivermos ori+i,a"me,te %m va"or difere,te de ero mas $%e ,ão sea 1 e,tão o res%"tado =bvio ser 1H... !ssim para evitar $%e o compi"ador emita avisos em co,str%es como: /* 4quivale a i" ((" "o!en(...)) & UWGG) 9 */ i" (" "o!en("ile.dat, r)) 9
@este caso o compi"ador avisa $%e %ma atrib%ião Gv"idaEH foi co"ocada ,o crit*rio do i.... )sse * %m erro; com%m e,tão o +cc avisa... mas se for isso mesmo $%e vocJ $%er faer basta co"ocar dois EE assim: i" (&&(" "o!en("ile.dat, r))) 9
6e . for @LL o operador EE ava"iar a e&pressão para 0 Gfa"soH se,ão para 1 GverdadeiroH. ) ,e,%m aviso * dado. ! mesma coisa pode ser feita com o e&emp"o a,terior Ga$%e"e ai em cima o,de i,creme,tamos yH mas se $%isermos comparar 4 com true por e&emp"o: i" (@) Q== /* Nncrementa Q se @ "or verdadeiro. */ Q = &&@ /* Ka6 a mesma coisa& */
1>9
Kuanto mais as coisas mudam>>> @ão fi$%e s%rpreso em co,statar $%e as d%as i,str%es abai&o são e&ec%tadas em %m ,Mmero difere,te de cic"os de m$%i,a: add add
ra@,[var] [var],ra@ 4ssa 7 duas ve6es mais lenta que a anterior.
! se+%,da i,str%ão efet%a %ma "eit%ra do e,dereo da varive" YvarY fa a adião e +rava o res%"tado de vo"ta ,a posião de YvarY. ! primeira fa ape,as %ma "eit%ra. 5 comportame,to do primeiro caso * co,ecido como leitura5modi.icaJo5escrita. ?sso sempre adicio,a cic"os de m$%i,a ao processame,to da i,str%ão e * %m comportame,to $%e deve ser evitado. 5%tra coisa i,teressa,te * $%e das se$%J,cias: cm! qord [var], -----%<----- corte aqui -----%<----@or ra@,ra@ cm! [var],ra@
! se$%J,cia U5NXCAP * mais rpida. 5 motivo * $%e a i,str%ão de comparaão com %m va"or imediato do tama,o de %m R5N/ * m%ito +ra,de. R%a,to maior a i,str%ão mais "e,ta e"a *. 5 par de i,str%es U5NXCAP o,de CAP ,ão est %sa,do %m va"or imediato oc%pa me,os espao.
)*C e 47C são lerdas 5 $%e s%pree,de * $%e a"+%mas i,str %es tJm comportame,to de leitura5modi.icaJo5escrita mesmo $%e se% opera,do ,ão sera %ma referJ,cia S mem=ria. o caso de ?@C e /)C. )ssas i,str%es faem a"teraes parciais ,o re+istrador )FL!6 Ge"as ,ão afetam o f"a+ de Carr#H e isso ca%sa %ma "eit%ra de )FL!6 modificaão e escrita adicio,a,do cic"os. por esse motivo $%e %m bom compi"ador C prefere %sar as i,str%es !// e 6Q $%e escrevem sobre os f"a+s diretame,te(0. )&iste o% o%tro prob"ema com /)C Ge provave"me,te ?@CH. @o modo &'(-(4 ,ão * poss
@ão e&istem ,esse modoE ?sso aco,tece por$%e o micro-c=di+o %sado para a i,str%ão * %sado para o%tra coisaE VocJ pode %sar /)C com re+istradores como CL e NCU mas ,ão as o%tras varia,tes.
*ão 'aça isso ! ?,te" recome,da $%e toda i,str%ão N) sea empare"ada; com %ma f%,ão C!LL correspo,de,te. 5 $%e e"a $%er dier com isso * $%e para %ma camada feita com C!LL dever e&istir %ma i,str%ão N) $%e retor,e da camada. ?sso aco,tece ,at%ra"me,te $%a,do criamos ,ossas f%,es em C mas em certos casos a coisa pode ,ão parecer tão =bvia: int 6eromem(void *dest, si6eEt si6e) return memset(dest, , si6e)
6e% compi"ador provave"me,te criar o se+%i,te c=di+o: 6eromem mov rd@,rsi @or esi,esi `m! memset
(0 )sto% fa"a,do ape,as dos f"a+s "i+ados a operaes aritm*ticas. F"a+s / e ? por e&emp"o são ma,tidos ,%m o%tro cirt%ito mesmo $%e seam mapeados em )FL!6.
1(0
! i,str%ão N) $%e est empare"ada com o C!LL $%e camo% essa roti,a est ,a f%,ão memset. ?sso est oD... Aas se vocJ fier %ma coisa es$%isita dessas para camar %ma f%,ão: mov ra@,6eromem !ush ra@ ret VHetornar8X !ara a "unTOo 6eromem&
VocJ ,ão ter %m N) empare"ado com o %m C!LL mas sim dois N)s Go $%e est "istado acima e o $%e est ,a f%,ão zeromemH. )ssa t*c,ica f%,cio,a mas ca%sar vrios cic"os de m$%i,a de pe,a"idade em +ra,de parte do se% c=di+o $%e dei&ar o branc/ &rediction co,f%so. !"*m do $%e a i,str%ão N) * mais "e,ta $%e a i,str%ão C!LL... 5%tra t*c,ica com%m $%a,do se $%er obter o va"or de N?P * esta: call here here !o! ra@ 9
ega o HN arma6enado na !ilha&
Como s%mimos com o N) $%e era esperado $%e o e"imi,amos para obter o co,teMdo de N?P $%e estava ,a pi"a o branc/ &rediction sofrer com isso. 6e vocJ rea"me,te precisar faer a"+o desse tipo eis %m c=di+o me"or: call here Ueste !onto HZI conter8 o valor de HN. 9 here mov ra@,[rs!] ret H4D, em!arelhado com o ZGG.
Aritm5tica inteira de multipla precisão ma veme%mdesafia,do +ra,de ami+o c=di+o a faere,t%siasmado o mesmo em com C: a "i,+%a+em L?6P me provoco% com o se+%i,te Nm!rime o valor de ALALALAL. (e@!t ALAL ALAL)
)sse c=di+o simp"es; em C * imposs390 a"+arismos e com (4 bits o va"or m&imo $%e podemos obter sem overf"o8 * a"+o como 1'}10 19. 5% sea cerca de 20 a"+arismos. !co,tece $%e em assemb"# o f"a+ CF e a"+%mas i,str%es aritm*ticas ,os permitem "idar com aritmFtica de multipla precisão . Por e&emp"o: 6e tiv*ssemos dois va"ores de 12' bits e $%is*ssemos som-"os poder
coloca em HJIHZI os BLR ;its de VvalorBX.
add ra@,[valorL] adc rd@,[valorL=R] com Uote que HJI 7 adicionado com a !arte su!erior de VvalorLX e o carrQ, vindo da adiTOo anterior.
sa,do o f"a+ CF para obter os overf"o8s das adies parciais i,feriores podemos rea"iar adies com a $%a,tidade de bits $%e $%isermos. 5 mesmo aco,tece com s%btraes: )&iste %ma i,str%ão 6QQ G(ubtract it/ BorroH o,de o f"a+ CF * %sado como empr*stimo;. ) com %m po%$%i,o de traba"o podemos e&trapo"ar a"+o seme"a,te para m%"tip"icaes e divises. @o e,ta,to esse artif
com mM"tip"a precisão... ma de"as * a libgm& GAP * acrh,imo de 7U 'ulti&le PrecisionH. ! roti,a em L?6P poderia ser escrita em C assim: /* alcula e@!(ALAL,ALAL), como em lis!. */ #include #include int main(void) m!6Et r, s m!6Einit(r) m!6Einit(s) m!6EsetEui(s, ALAL) m!6E!oEui(r, s, ALAL) m!6Eclear(s)
/* s ALAL */ /* r !o(s, ALAL) */ /* nOo !recisamos mais do s */
/* !rint"() nOo su!orta o ti!o m!6Et. or isso usamos um !rint" es!eciali6ado. */ gm!E!rint"(%d'n,r) m!6Eclear(r)
/* nOo !recisamos mais do r */
return
Aas ate,ãoE ! bib"ioteca libgm& provave"me,te ,ão %sa aritm*tica i,teira em se% i,terior. L?6P * provve" tamb*m ,ãoE )sse tipo de bib"ioteca cost%ma %sar strings como co,tai,ers para os va"ores $%e serão ma,ip%"ados. /essa forma as variveis do tipo m&zOt são "imita das ape,as pe"a $%a,tidade de mem=ria dispo,
Eoc I não est cansado disso, Provave"me,te vocJ vi% %m c=di+o parecido com o abai&o: KNG4 *" void *!tr i" ((" "o!en("ilename, rt)) & UWGG) i" ((!tr malloc(si6e)) UWGG) "close(") return B 9 i" (erro) "ree(!tr) "close(") return L
1(2
9 "ree(!tr) "close(") return
@ão aca $%e e&istem m%itas camadas para .closeB c"aro $%e podemos red%ir isso com %m goto bem posicio,ado: KNG4 *" void *!tr int retcode i" ((" "o!en("ilename, rt)) & UWGG)
i" ((!tr malloc(si6e)) UWGG) recode B goto end2"Kunction 9 i" (erro) "ree(!tr) retcode L goto end2"Kunction 9
"ree(!tr) end2"Kunction "close(") return retcode
Aas se vocJ * %m da$%e"es catos $%e co,sideram goto a pior coisa desde a i,ve,ão da a&* m%sic e,tão eis %ma o%tra ma,eira. Podemos co"ocar %m tratador de erros ,o comeo de ,ossas f%,es e simp"esme,te sa"tar para e"a mas sem %sar goto: KNG4 *" void *!tr `m!E;u" `; int retcode /* onto de salto, em caso de erro. */ i" (retcode set`m!(`;)) i" (retcode L) "ree(!tr) "close(") return retcode i" ((" "o!en("ilename, rt)) & UWGG) i" ((!tr malloc(si6e)) UWGG) long`m!(`;, B) 9 i" (erro) long`m!(`;, L) 9
1(3
"ree(!tr) "close(") return
5D longAm& * %m +oto disfarado mas o c=di+o fica mais e"e+a,te ,ãoB como se re+istrssemos %ma roti,a de erros e depois co"o$%emos o c=di+o para f%,cio,ar Ge ,ão foi isso $%e fiBEH.
Otimização de preenc"imento de arras s vees a"+%mas roti,as c"ssicas aprese,tam prob"emas i,teressa,tes. m desses prob"emas *: Como pree,cer %m arra# da ma,eira mais rpida poss
6= $%e $%eremos faer ,ossa roti,a o mais f"e& tamb*m... ! roti,a =bvia * essa: void 6ero"ill(void *!tr, si6eEt si6e) char *!c int i !c !tr "or (i i < si6e i==) *!c== -----%<----corte aqui -----%<---- ?digo gerado !elo com!ilador. 6ero"ill lea ra@,[rdi=rsi] HZI cont7m agora o !onteiro al7m do "inal do arraQ. test rsi,rsi Fe si6e , sai da "unTOo. `e .GB .GL add rdi,B !tr== mov ;Qte !tr [rdi-B], *(!tr B) cm! rdi,ra@ hegamos ao "inal do arraQ `ne .GL 9 se nOo chegamos, volta ao loo!. .GB ret
)sse c=di+o ai em cima * +erado com a opão -52 do compi"ador. !o compi"armos com m&ima otimiaão temos %ma s%rpresa: 6ero"ill test rsi,rsi `e .GB mov rd@,rsi @or esi,esi `m! memset .GB ret
/escobrimos $%e memset * %ma da$%e"as f%,es i,tri,secas do compi"ador. !o perceber o pree,cime,to de %m arra# e"e simp"esme,te s%bstit%i% todo o ,osso c=di+o por %ma camada do tipo: i" (si6e & ) memset(!tr, , si6e)
1(4
Vamos i+,orar essa vio"aão de ,ossa vo,tade e ,os co,ce,trar ,a roti,a ori+i,a"... 5 prob"ema com e"a * $%e pree,ce %m M,ico b#te de cada ve. ma i,str%ão A5V * e&ec%tada em %m c si6eo"(unsigned int)) *(unsigned int *)!tr !tr = si6eo"(unsigned int) si6e - si6eo"(unsigned int) i" (si6e > si6eo"(unsigned short)) *(unsigned short *)!tr !tr = si6eo"(unsigned short) si6e - si6eo"(unsigned short) i" (si6e > ) *(unsigned char *)!tr
5 c=di+o acima * m%ito bom para arra#s com tama,os maiores $%e '. Aas eis %m c=di+o me"or: 6"ill.asm ;its SA section .te@t HJN !tr, HFN si6e glo;al 6ero"ill3"unction align BS 6ero"ill3 @or ea@,ea@ mov rc@,rsi re! stos; !reenche ;Qte !or ;Qte&& ret
) esse * %m e&emp"o de %ma coisa $%e era boa passo% a ser r%im por m%ito tempo e vo"to% a ser boa de ,ovoE ! i,str%ão 656Q foi feita para armae,ar o va"or do re+istrador !L ,o e,dereo apo,tado por N/?. !o acresce,tar o prefi&o N)P a i,str%ão armae,a !L ,o b"oco de mem=ria c%o e,dereo base * dado por N/? e tem NCU b#tes de tama,o. Com %ma pe+adi,a: @as ar$%itet%ras moder,as G@ea"em e s%perioresH o processador proc%rar %sar o macete; de armae,ar o maior tama,o poss
1(>
+unção
Ciclos
Bano
erofi"" erofi""2 erofi""3
231>23 20910 >219
1007q 433(q
0abela G: Per.ormances das versKes de zero.ill9
6= modifica,do o eito de pree,cer %m arra# Gde b"oco em b"ocoH me"oramos a performa,ce em mais de 11 vees. sa,do %m rec%rso do processador me"oramos em 44E A!iso: ma ma,eira de verificar se se% processador s%porta L5/6QX656QXA5V6Q rpidos *
com essa pe$%e,a roti,a: rot?ti!o int testE"astE;locEo!erations(void) KunTOo equivalente, em int testE"astE;locEo!erations(void) int a,;,c,d Ec!uid(_, a, ;, c, d) return (; @L) & testE"astE;locEo!erations !ush r;@ mov ea@,_ c!uid @or ea@,ea@ test e;@,;BEE ;it f de 4MI indica essa "eature. set6 al !o! r;@ ret
@entando otimizar o F8C PQ c"ec9 sum> 7 'al"ando>>> )m %m proeto e,vo"ve,do socDets precisei %sar a roti,a de c"c%"o de c/eck sum estabe"ecida pe"a NFC 1071. 5 $%e * me,os comp"icado do $%e ca"c%"ar c/eck sumsB; vocJ deve estar pe,sa,do. Qem eis a f%,ão como imp"eme,tada pe"a NFC: unsigned short csum(void *addr, si6eEt count) unsigned int sum unsigned short *! /* ondiTOo em que a rotina "unciona ;em. */ assert(count < B3B_L) sum ! addr hile ( count > B ) sum = *!== count - si6eo"(unsigned short) i" ( count > ) sum = *(unsigned char *)! hile (sum>>BS) sum (sum @"""") = (sum >> BS) return sum
! roti,a %sa %ma varive" de 32 bits para ,o primeiro "oop ac%m%"ar poroes de 1( bits de tama,o obtidas do b%ffer. 6e sobrar %m b#te $%e ai,da ,ão foi ac%m%"ado e,tão a roti,a o fa. ) como passo fi,a" os tra,sportes Ga parte dos 1( bits s%periores do ac%m%"adorH são acresce,tados a 1((
e"e para $%e obte,amos ape,as os 1( bits i,feriores. %do f%,cio,a m%ito bem se obtivermos at* (>>3> tra,sportes; Gtodos os 1( bits s%periores do ac%m%"ador setadosH. R%a"$% er ,Mmero de tra,sportes adicio, ais e a roti,a devo"ver o c/eck sum errado. /essa forma a roti,a aceita "idar com b%ffers de at* 12' ^iQ de tama,o G(>>3> tra,sportes vees 2 b#tesH. ! "i,a com a assertiva est " para d%ra,te o deb%++i,+ verificarmos se essa co,dião foi vio"ada. ma ma,eira de ace"erar as coisas e reso"ver a "imitaão do tama,o do b%ffer em teoria * %sar os rec%rsos $%e temos em mãos. @o caso re+istradores de (4 bits. ! roti,a abai&o s= tem %m M,ico "oop $%e "J unsigned longYs de cada ve "eva,do em co,ta os tra,sportes parciais. )"a %sa %m artif> 3 count - ulcount << 3 hile (ulcount--) sum = *! i" (sum < *!) sum== !== i" (count) shi"t (R - count) * R tm! *! (@""""""""""""""""WG >> shi"t) sum = tm! i" (sum < tm!) sum== uB uL uB i"
sum sum >> 3L = uL (uB < uL) uB==
sB sL sB i"
uB uB >> BS = sL (sB < sL) sB==
/* !erigoso, mas "unciona& */
return sB
)ra de se esperar $%e cksumH fosse pe"o me,os d%as vees mais rpida $%e a roti,a ori+i,a" $%e estamos "e,do d%as mais rpido; ,o "oop pri,cipa". Aas ,ão * isso o $%e aco,tece. )is a medião dos cic"os +astos %sa,do %m b%ffer de 3277> b#tes(1:
(1 Como co,dião de testes o b%ffer deve ter 7 b#tes a mais do $%e o mM"tip "o de '. !ssim teremos $%e "er G, 1H %,si+,ed "o,+;s. 5,de o M"timo co,t*m os 7 b#tes resta,tes...
1(7
+unção
Ciclos
cDs%m cDs%m2
((9( '(4'Gperdade29qEH 0abela : "onsumo de ciclos de cksum e cksumH9
)ssa * %ma da$%e"as f%,es o,de criar %m c=di+o assemb"# ,ão adia,ta m%ita coisa... e,tei criar %ma roti,a %sa,do a"+%,s macetes Gcomo ac%m%"ar 32 b#tes de cada ve ,a iteraão do "oop i,icia"H e o $%e co,se+%i foi %ma performa,ce "i+eirame,te s%perior S cksumH Gsome,te cerca de 1q de +a,oEH. @a ar$%itet%ra &'(-(4 o bom e ve"o cksum da NFC 1071 ai,da * m%ito bomE
-revisão de saltos e um arra de valores aleat%rios )sse prob"ema i,teressa,te me foi i,dicado por %m ami+o: ! roti,a abai&o pree,ce %m arra# de 327(' ints com va"ores a"eat=ri os e,tre 0 e 2>>. /epois todos os va"ores do arra# são somados. ! soma dos ite,s do arra# * feita 100 mi" vees para faci"itar a medião do tempo. 5 c=di+o ori+i,a " %sa a f%,ão clock para medir a performa,ce em se+%,dos: #include #include #include #de"ine +ZIEND4HZDN2UF B #de"ine +ZIEMWKK4HEFN4 3L_SR int ;u""er[+ZIEMWKK4HEFN4] /* reenche arraQ com valores aleat?rios entre e L. */ void randomE"illE;u""er(void) int i /* UOo alimento o seed aqui !ara o;ter a mesma sequ5ncia Valeat?riaX toda ve6& */ "or (i i < +ZIEMWKK4HEFN4 i==) ;u""er[i] rand() % LS /* Wsada !or qsort. */ int com!are(const void *@, const void *Q) return *(int *)@ < *(int *)Q int main(void) int i, ` long sum clocEt clstart dou;le clela!sed randomE"illE;u""er() // Hetire isso daqui !ara testar com o arraQ "ora de ordem. qsort(;u""er, +ZIEMWKK4HEFN4, si6eo"(int), com!are) clstart cloc() "or (i i < +ZIEND4HZDN2UF i==) "or (` ` < +ZIEMWKK4HEFN4 `==) i" (;u""er[`] > BLR) sum = ;u""er[`] clela!sed (dou;le)(cloc() - clstart) / G2jFE4HEF4 !rint"(sum %ld.'n Dem!o decorrido %.3" segundos.'n, sum, clela!sed) return
1('
)is a tabe"a com o tempo de e&ec%ão medido com a orde,aão do arra# e sem orde,aão do arra# bem como com ,
-1
-2
-3
(.49 se+%,dos 1.7( se+%,dos 1.74 se+%,dos 2.(2 se+%,dos Arra' não ordenado 17.34 se+%,dos 10.(1 se+%,dos 10.2( se+%,dos 2.(2 se+%,dos Arra' ordenado
0abela H: 0em&os de e4ecuJo na varredura em (orted1rray0est9
5s , BLR) sum = data[i]
m YifY sempre e&ec%ta %m sa"to co,dicio,a". @o e&emp"o o co,%,to de i,str%es $%e obt*m o va"or de YdataijY e somam com o co,teMdo de Ys%mY co"oca,do de vo"ta em Ys%mY * omitido se YdataijY for me,or $%e 12'. ! versão do c=di+o deste YifY +erado pe"a otimiaão de ,
e;@,ec@
6empre $%e YdataijY for me,or o% i+%a" a 127 %m sa"to * feito evita,do a ac%m%"aão. !co,tece $%e desde os 4'(s os processadores da ar$%itet%ra '0&'( decidific am as i,str%es bem a,tes de"as serem e&ec%tadas. @o caso de sa"tos co,dicio,ais o processador tem $%e adivi,ar; se o sa"to ser tomado o% ,ão antes de saber o estado dos f"a+s. ?sso * feito por %ma roti,a; i,ter,a do processador camada branc/ &rediction. 5 processador ma,t*m %ma estat
1(9
onsidere HJI data[i] 4MI sum HR tm!Esum 9 mov ec@,[rd@] movs@ rR,ec@ add rR,r;@ cm! ec@,BLR cmovge r;@,rR 9
5 compi"ador fe %m traba"o i,teressa,te a$%i. N' s= ser movido para NQU se e some,te se )CU for maior o% i+%a" a 12'. ! i,str%ão CA5Vcc +asta sempre 1 cic"o de m$%i,a mesmo $%a,do a co,dião ,ão * satisfeita. ) ,ote $%e o sa"to co,dicio,a" s%mi%E ! dica a$%i *: )"imi,e os sa"tos co,dicio,ais ta,to $%a,to poss
;sar raiz (uadrada. via SS7. parece estran"o>>> )specia"me,te ,o modo &'(-(4 o compi"ador C %sar 66) para "idar com aritm*tica em po,to f"%t%a,te. ?sso foi disc%tido a,teriorm,te. VocJ topar com %m c=di+o bem estra,o ,o caso do %so de rai $%adrada: /* Fim!les e@em!lo de c?digo em */ #include "loat getEsqrt("loat @) return sqrt"(@) ----- cortar aqui ---- ?digo equivalente, em assem;lQ getEsqrt sqrtss @mmB,@mm ucomiss @mmB,@mmB `! .GB mova!s @mm,@mmB ret .GB !ush ra@ call sqrt" !o! rd@ ret
! primeira estra,ea; * por $%e o compi"ador i,c"%i% essa comparaão e %ma camada S f%,ão sqrt. da "ibcB 5 prob"ema est em a"+%,s va"ores %sados ,os operadores da i,str%ão 6RN66.
!s re+ras para "idarmos com res%"tados @a@s e i,fi,itos ,o processador são difere,tes das re+ras tradicio,ais da f%,ão sqrt. e por isso o compi"ador co"oca esse c=di+o adicio,a" (2. )"e testa pe"o res%"tado de 6RN66 e se o f"a+ de paridade PF estiver setado si+,ifica $%e o%ve %m prob"ema. /a< o c=di+o ir %sar a f%,ão sqrt. para obter a rai $%adrada. 5 $%e me ca%sa o%tra estra,ea * a ,ecessidade do compi"ador sa"var ra4 e rec%per-"o em rd4 $%e amos os re+istradores ,ão precisam ser preservados ,a co,ve,ão de camada &'(-(4. )m revises f%t%tas deste "ivro se e% acar %ma e&p"icaão para esse fato come,tarei sobre o ass%,to. Por e,$%a,to essa ,ecessidade para mim ai,da * %m mist*rio. Poder
(2 5 processador %sa tiops; difere,tes de @a@s: 6@a@s e R@a@s. 5,de o primeiro * mais drstico; $%e o se+%,do.
170
#include <@RSintrin.h> "loat getEsqrt("loat @) return EmmEcvtssE"3L(EmmEsqrtEss(EmmEsetEss(@))) -----%<----- corte aqui -----%<---- ?digo equivalente em assem;lQ getEsqrt movss [rs!-BL],@mm kDK& movss @mm,[rs!-BL] sqrtss @mm,@mm ret
)mbora a roti,a fi,a" fi$%e me,or e pote,cia"me,te mais rpida Gmas ,em ta,toEH essa ,ecessidade de +ara,tir $%e os .loats s%periores esteam erados me parece preciosismo do compi"ador. ) em C ,ão m%ito o $%e faer para evitar isso.
Herando nDmeros aleat%rios s vees precisamos obter va"ores a"eat=rios em ,ossas ap"icaes. ! ma,eira mais simp"es de faJ"o * %sa,do %ma f%,ão da libc: rand>). )"a * dec"arada em stdlib9/ como: int rand(void)
) a doc%me,taão ,os di $%e a f%,ão retor,a %m va"or e,tre 0 e N!@/]A!U $%e * t) ,o c=di+o da +"ibc $%e te,o em mãos: return (seed (seed * BB3BLA = BL3A) % @_""""""")
5 va"or de YseedY i,icia" * tamb*m esco"ido S dedo para parecer $%e ra,dGH sea a"eat=rio se %ma seme,te; ,ão for for,ecida mas * sempre o mesmo. ! f%,ão srand>) $%e for,ece a seme,te para o +erador de co,+r%J,cia "i,ear some,te at%a"ia essa varive" esttica. !ssim a f%,ão rand>) * pse%do-a"eat=ria;. Fe"ime,te a ar$%itet%ra 8asell imp"eme,ta %m +erador a"eat=rio de verdade; %sa,do %m fe,hme,o $%K,tico como fo,te de e,tropia... ?sso t%do de,tro do se% processadorE !trav*s de %ma M,ica i,str%ão podemos obter o ,Mmero a"eat=rio $%e $%isermos $%e * garantido ser a"eat=rio. rata-se da f%,ão N/N!@/: random.asm ;its SA section .te@t rot?ti!o unsigned long getrandom(void) glo;al getrandom"unction getrandom rdrand ra@ `nc getrandom ret
! i,str%ão N/N!@/ $%a,do fa"a retor,a com o f"a+ Carr# erado. %do o $%e temos $%e faer 171
* e&ec%tar N/N!@/ ,ovame,te. ! desva,ta+em * $%e N/N!@/ pode ser "e,ta... ! doc%me,taão da ?,te" ,os di $%e e"a pode fa"ar se "eit%ras forem feitas em i,terva"os me,ores $%e 10 mi"isse+%,dos o $%e ,os co"ocaria ,%m "oop por cerca de %,s > mi"es de cic"os de m$%i,a mas a coisa ,ão * tão cr
!o obter o resto da divisão por ( estamos aproveita,do ape,as os 3 bits i,feriores do res%"tado de rand>). Podemos obter mais faces vo"tadas para o 3 ,o dado do $%e as demais facesE ma poss) * obtermos os 4 bits s%periores do res%"tado G $%e o bit 31 sempre estar
eradoEH: value ((rand() >> LR) % S) = B
! so"%ão =bvia se se% processador poss%ir a i,str%ão N/N!@/ * %sar ,ossa f%,ão getrandom>) ao i,v*s de rand>). Aas fi$%e ate,do $%e ao obter o resto da divisão por ( o va"or a"eat=rio obtido ai,da * %m po%co sofr
/* 2;tem um valor aleat?rio entre e BL_ */
! i,str%ão N/N!@/ vem em 3 sabores: 1( 32 o% (4 bits depe,de,do do re+istrador %sado como opera,do. Poder
5 compi"ador esco"er a variaão de N/N!@/ apropriada depe,de,do do tama,o da varive" passada para o macro...
(3 e,o $%e a+radecer a @e"so, Qrito por me i,dica r esse deta"e... @%m proeto e"aborado pe"o @e"so, e"e %sa va %m macro com va"ores em po,to f"%t%a,te para "idar com esse prob"ema. @o mome,to em $%e o e,te,di p%de otimiar a"+%mas roti,as para %so e&c"%sivame,te de va"ores i,teiros. (4 ma e&p"icaão sobre o sa"to co,dic io,a" ,o assemb"# i,"i,e: Labe"s ,%m*ricos devem ser refere,c iados com %m s%fi&o YbY o% YfY Gde bacD; e for8ard;H. !o %sar YbY o sa"to * feito para o "abe" a,terior Gpara trsH.
172
Capítulo +! ,isturando ?a'a e C Aist%rar ava e C * %ma coisa m%ito simp"es de ser feita. 5 \ava Develo&ment Mit G/^H poss%i bib"iotecas e /eaders para $%e o dese,vo"vedor possa %sar roti,as e&ter,as S VA. 5 padrão cama-se @? G\ava ative Inter.aceH. )% disse simp"es;B ava tem " s%as idiossi,crasias... )mbora %sar a @? sea simp"es * preciso e,te,der como ava f%,cio,a para %s-"a corretame,te. 5 %so i,correto acarreta s*rios prob"emas para a ap"icaão $%e a VA G \ava irtual 'ac/ineH * respo,sve" por +ere,ciar todo o ambie,te do se% pr=prio eito $%e * i,compat
-or(ue não 5 uma boa ideia misturar C com ambientes !gerenciados# Por ambie,tes +ere,ciados; $%ero dier "i,+%a+e,s como ava e C[ e $%a"$%er o%tra $%e %se o co,ceito de 7arbage "ollection. @esses ambie,tes ap"icaes são e&ec%tadas sob o $%e camamos m$%i,as virt%ais;. Jm esse ,ome por$%e e"as em%"am %ma m$%i,a fict@ -----%<----- corte aqui -----%<----/* +Qlass.c */ struct +Qlass struct +QlassEvt;l int (*getI)(struct +Qlass *this) static +QlassEvt;l mQclassEvt;l
173
struct +Qlass int @ struct +QlassEvt;l *vt;l int +QlassEgetI(struct +Qlass *this) return this->@ void +QlassEctor(struct +Qlass *!) !->vt;l mQclassEvt;l !->vt;l->getI +QlassEgetI
)m C toda camada a %ma f%,ão virt%a" * feita atrav*s de po,teiro s co,tidos ,a tabe"a virt%a" mais o% me,os como * descrito ,o c=di+o em C acima... m obeto tem atre"ado a si %m po,teiro para %ma estr%t%ra co,te,do os po,teiros para as f%,es virt%ais da c"asse. !o camar a f%,ão esse po,teiro * a%tomaticame,te %sado Gem CH. Aais o% me,os assim: /* teste.cc */ +Qlass o;` 9 int Q o;`.getI() -----%<----- corte aqui -----%<----/* teste.c */ struct +Qlass o;` +QlassEctor(o;`) 9 int Q o;`.vt;l->getI(o;`)
fci" perceber $%e toda camada a f%,es virt%ais são feitas de forma i,direta pe"a tabe"a virt%a". ?sso e&iste para $%e d%ra,te a era,a o po"imorfismo possa ser faci"me,te imp"eme,tado. Vo% dei&ar esse deta"e de fora por a$%i... @o por *defa%"t Go%tro ,ome $%epo,teiros ava d Sstoda f%,es-membroH * virt%a". ) %sarava obetos sempretodo feitom*todo por referJ,cia %sa,do camada de m*todo * feita por$%e %ma i,direão d%p"a... emos o po,teiro disfarado; sob o ,ome do obeto e temos o po,teiro esco,dido; da tabe"a virt%a". ma comparaão s%perficia" de camadas %sa,do c=di+os em ava e C seria assim: // 4m `ava o;`."() -----%<----- corte aqui ----%<----/* 4m */ o;`->vt;l->"() /* o;` 7 um !onteiro& */
,ecessrio e,te,der isso se vocJ for %sar a @?...
Harbage Collection. no Rava 5%tra coisa $%e * preciso e,te,der * como ava %sa a mem=ria. ! VA pr*-a"oca e divide o /ea& em basicame,te 3 b"ocos. 5 primeiro b"oco * camado Eden o% ^oung 7eneration $%e co,t*m Elder 7eneration9 obetos e de vidasobreviver; c%rta. 5 se+%,do * camada )"e 7eneration co,t*m obetos maiores pe$%e,os e $%e co,se+%iram ao 7arbage "ollector vi,dos da ^oung . o terceiro b"oco * camado Permanent 7eneration.
5betos co,tidos ,as re+ies Eden e Elder são movidas o tempo todo pe"o co"etor de "i&o. !$%e"es obetos $%e ,ão estão mais em %so precisam ser "iberados e os $%e ai,da estão se,do %sado precisam ser movidos para evitar a fra+me,taão dessas re+ies. Como esses obetos são movidos se%s po,teiros são a"terados com fre$%J,cia. para ma,ter %m re+istro da ,ova posião do obeto $%e e&iste a re+ião Permanent. Po,teiros para os obetos ,as +eraes sob a i,f"%J,cia do 7arbage 174
"ollector são ma,tidos ,a re+ião Permanent e $%a,do o co"etor move a"+%m b"oco t%do o $%e e"e
tem $%e faer * a"terar o po,teiro da referJ,cia ,o "ado perma,e,te. !ssim o c=di+o em ava sabe o,de o obeto est o tempo todo:
Figura +: 7arbage "ollector movimentando um _nico obAeto9
%,ta,do o co,ceito das +eraes com as f%,es virt%ais ava ma,t*m o po,teiro para as estr%t%ras do obeto ,a re+ião perma,e,te e esse po,teiro apo,ta para a tabe"a virt%a" ,%ma das re+ies sob i,f"%J,cia do arba+e Co""ector e a tabe"a virt%a" co,t*m %m po,teiro para %ma o%tra +eraão esco,dida; $%e co,t*m o b#tecode da f%,ão...
isturando com um exemplo simples>>> ! primeira coisa a ser feita $%a,do for mist%rar se%s c=di+os em C com o ambie,te ava * criar %ma c"asse $%e carre+%e %ma s/ared library defi,ida por vocJ $%e co,te,a as s%as f%,es: // $ellokorld.`ava // // 4ssa classe 7 um Vstu;X. 4la cont7m as declaraT\es das "unT\es VnativasX. // !u;lic class $ellokorld // Nniciali6ador carrega a shared li;rarQ li;$ello.so. static FQstem.loadGi;rarQ($elloX) // Z "unTOo VnativaX em void sho+essage(void) !u;lic static native void sho+essage()
5 obeto da c"asse 8ello%orld, atrav*s do i,icia"iador vai carre+ar o s/ared obAect "ibIe""o.so; e e"a tamb*m dec"ara a f%,ão s/o'essage $%e se "oca"ia ,essa bib"ioteca... 6e o c=di+o for e&ec%tar ,o i,do8s provave"me,te a /^ vai proc%rar por /ello9dll ,os diret=rios i,dicados pe"a varive" de ambie,te P!I. /epois de compi"ar a c"asse vocJ poder %sar o %ti"itrio YavaY para obter o eader com as dec"araes das f%,es da c"asse G"istada abai&o sob o ,ome Ie""oor"d.H: 6a,ac :elloorld.6a,a 6a,ah -o :elloorld.h :elloorld ls -l -r-r--r-- B user user BL an LB BS_ -r-r--r-- B user user B3 an LB BSBS -r-r--r-- B user user 3RR an LB BSLf -r-r--r-- B user user BL an LB BSA -r-r--r-- B user user AAR an LB BSR -----%<----- corte aqui -----%<-----
li;$ello.c $ello.`ava $ellokorld.h $ellokorld.`ava +ae"ile
17>
/* $ellokorld.h (criado !or `avah) */ /* J2 U2D 4JND D$NF KNG4 - it is machine generated */ #include <`ni.h> /* $eader "or class $ellokorld */ #i"nde" ENncludedE$ellokorld #de"ine ENncludedE$ellokorld #i"de" EEc!lus!lus e@tern #endi" /* * lass * +ethod
$ellokorld sho+essage
* Fignature () */ UN4I2HD void UNZGG avaE$ellokorldEsho+essage (UN4nv *, `class) #i"de" EEc!lus!lus #endi" #endi"
)is a roti,a em C $%e compor a s/ared library. )"a deve i,c"%ir o eader +erado acima: /* li;$ello.c */ #include #include $ellokorld.h. UN4I2HD void UNZGG avaE$ellokorldEsho+essage(UN4nv *env, `class o;`) !uts($ello, orld&) -----%<----- corte aqui -----%<---- gcc -03 -I /7sr/li$/6,m/de&a7l#-6a,a/i%cl7de -march%a#i,e -&;I< -o li$:ello.o li$:ello.c gcc -o li$:ello.so -shared li$:ello.o
?mporta,te reparar $%e o ,ome da ,ossa f%,ão obedece o ,ome co,tido ,o eader. 5 ava %sa %m es$%ema de ,ome,c"at%ra especia" Go e&emp"o acima * s= %m caso simp"es T e&istem ,omes mais co,f%sosH. !$%i s%r+e o primeiro prob"ema. ,ecessrio dier ao CC o,de * $%e podemos e,co,trar o eader Ani9/ $%e acompa,a o /^. ! co,c"%são =bvia $%e se+%e desse fato * $%e s%a s/ared obAect * depe,de,te da versão do /^ %sado. %do o $%e precisamos faer a+ora * criar %ma c"asse ava $%e vai i,sta,ciar ,ossa c"asse 8ello%orld $%e co,t*m as dec"araes ,ativas e e&ec%tar o c=di+o: // $ellokorld.`ava !u;lic class $ello !u;lic static void main(Ftring[] args) $ellokorld h ne $ellokorld() h.sho+essage() -----%<----- corte aqui -----%<---- 6a,ac -classpa#h . :ello.6a,a "=*"I>R?R@*;?T:. 6a,a :ello $ello, orld&
Nepare $%e YavacY precisa sabe r o,de a c"asse 8ello%orld est por isso de fi,i o class&at/ apo,ta,do para o diret=rio corre,te. !i,da YavaY precisa saber o,de o ,osso lib8ello9so est. Por isso forcei a barra e defi,i L/]L?QN!NW]P!I apo,ta,do para o diret=rio corre,te. @a prtica vocJ poder co"ocar s%a s/ared library em usrlib por e&emp"o. /e ,ovo ,o i,do8s isso ,ão * 17(
,ecessrio: /LLs são proc%radas pe"o sistema operacio,a" ,os diret=rios co,tidos ,a varive" de ambie,te P!I e ,o diret=rio corre,te. )is %m make.ile para t%do isso: # +ae"ile # # Wse mae # mae run # mae clean
(!ara com!ilar) (!ara e@ecutar $ello.class) (!ara a!agar arquivos dei@ando a!enas os "ontes)
JjEGNMZD$/usr/li;/`vm/de"ault-`ava/include .$2U all run clean all $ello.class $ellokorld.class li;$ello.so li;$ello.so li;$ello.o gcc -o 0 -shared 1 li;$ello.o li;$ello.c $ellokorld.h gcc -N (JjEGNMZD$) -c -"N -23 -marchnative 0 li;$ello.c # `avah !recisa rece;er a!enas o nome da classe. $ellokorld.h $ellokorld.class class"ile< ' `avah -o 0 class"ile%.class %.class %.`ava `avac -class!ath . < run GJEGNMHZHEZD$.GJEGNMHZHEZD$ `ava $ello clean rm *.o *.so *.class *.h
Vo"ta,do ao c=di+o em C os tipos %sados pe"o ava são difere,tes. 6ão ,omeados com %m YY ,a fre,te:
Tipo0Ja!an=s
Tipo0C
boo"ea, b#te car sort i,t
%,si+,ed car car %,si+,ed sort sort i,t
"o,+ f"oat do%b"e c"ass
"o,+ f"oat do%b"e B
stri,+ obect !rra# void
B B j void 0abela 2: 0i&os usados no \I
@a tabe"a acima o * %m tipo primitivo o% obect; do ava e o tipo e$%iva"e,te do C. m arra# 177
do tipo i,t!rra# * mapeado para Yi,t jY em C por e&emp"o. 5s tipos Aclass Astring e AobAect são tipos especiais. odos os tipos ,ão primitivos são obetos em ava. Para acess-"os temos $%e %sar a"+%mas f%,es dispo,ibi"iadas pe"a VA acess
;sando strings !"*m tipos primitivos car f"oat...H o%tros sãopodem obetosseremmovidos ava e são para ados ,ossa f%,ão como Gi,t ta". 6e,do obetostodos essesosparKmetros ,%mpassados dos eaps +ere,ciados pe"o ava. /a< temos $%e tomar preca%es especiais com re"aão a e"es. e,o boas ,ot2 o% ?65-''>9-1 o compi"ador co,verter s%as stri,+s para F-'. ! m ,ot
@este caso para evitar avisos do compi"ador vocJ dever faer coverses de tipos ,o se% c=di+o ao camar %ma das f%,es da VA: `string s (*env)->UeFtring(env, (const `char *)mQstring, cslen(mQstring))
5% faer o ty&e casting para co,st 8car]t k;. C"aro $%e esse casting pode ,ão ser ,ecessrio. 5 tipo Ac/ar * defi,ido como s/ort e porta,to tem 1( bits de tama,o. Para obter acesso ao co,teMdo do obeto 6tri,+ temos $%e obter %ma referJ,cia trav-"a para $%e o 7arbage "ollector ,ão ba+%,ce t%do move,do os dados de %m "%+ar para o%tro e depois de %sar os dados do b%ffer apo,tado pe"a referJ,cia "iberar a trava. Para ta,to e&istem pares de roti,as $%e devem sempre ser %sadas para "idar com stri,+s: 7et(tringQ e elease(tringQ. ! se+%ir eis %m e&emp"o de %so: 6%po,a $%e a ,ossa f%,ão s/o'essage ,o e&emp"o a,terior em ava sea assim: 17'
!u;lic static native void sho+essage(Ftring str)
!o e&ec%tar Aava/ em 8ello%orld9class obtemos %m ar$%ivo 8ello%orld9/ com %m prot=tipo e mapeamos esse prot=tipo para a f%,ão abai&o: UN4I2HD void UNZGG avaE$ellokorldEsho+essage(4nv *env, `class this, `string str) const char *s /* 2;t7m o !onteiro da string em WDK-R. */ i" ((s (*env)->CetFtringWDKhars(env, str, UWGG)) & UWGG) !uts(s)
/* Gi;eramos o !onteiro da string em WDK-R. */ (*env)->HeleaseFtringWDKhars(env, str, s)
samos Ye,vY para camar as f%,es da VA. @ote $%e o po,teiro Ye,vY co,t*m %m po,teiro $%e apo,ta para %ma tabe"a virt%a". Por isso em C temos $%e %s-"o como YGke,vHY. 6e estiv*ssemos %sa,do C e o tipo \Env fosse dec"arado como %ma c"asse co,te,do f%,es virt%ais Ge&iste %ma em Ani9/H e,tão poderCetFtringWDKhars(str, UWGG)
5 po,teiro YtisY e a i,direão da tabe"a virt%a" * ass%mida por defa%"t em C $%a,do dec"araão de camadas de f%,es de c"asses $%e seam virt%ais... Aas estamos "ida,do com C a$%i... @o e&emp"o 7et(tringU0F"/ars obt*m %m po,teiro para o b%ffer co,te,do a stri,+ passada como parKmetro. 5 terceiro parKmetro @LL passado para 7et(tringU0F"/ars di S VA $%e e"a ,ão tem $%e faer %ma c=pia da stri,+ ori+i,a". )ste parKmetro * %m po,teiro para o tipo Aboolean $%e se apo,tar para %m va"or @?]N) i,dica para a VA $%e vamos traba"a r com %ma c=pia ,ão com o b%ffer ori+i,a": `;oolean co!Q UNEDHW4 s (*env)->CetFtringWDKhars(env, str, co!Q)
C=pias podem ser a"teradas o $%a,to $%isermos. raba"ar com o b%ffer ori+i,a" ,ão * " %ma boa ideia $%e e"e deveria ser +ere,ciado ape,as pe"a VA. @ada impede $%e o me% pr=prio c=di+o crie %ma c=pia da stri,+ ori+i,a". Por isso cost%mo passar @LL o% ero todas as vees: const char *s char *sL s (*env)->CetFtringWDKhars(env, str, UWGG) sL strdu!(s) ... "ree(sL) (*env)->HeleaseFtringWDKhars(env, str, s)
bom verificar o res%"tado da camada a 7et(tringQ. )"a pode retor,ar %m po,teiro @LL ,os die,do $%e o%ve %m erro ,a VA Gut.'emoryBEH. ! camada a elease(tringU0F"/ars * ,ecessria para faer o destravame,to do obeto. !+ora s%po,a $%e a f%,ão em ava devo"va %ma stri,+:
179
... !u;lic static native Ftring get+essage() ... -----%<----- corte aqui -----%<----static const char mQFtring[] Deste UN4I2HD `string UNZGG avaE$ellokorldEget+essage(4nv *env, `class this) return (*env)->UeFtringWDK(env, mQFtring)
! f%,ão e(tringU0F criar %m obeto (tring em a"+%m "%+ar do eap da VA Gpossive"me,te ,a +eraão ^oungH obter a stri,+ do b%ffer apo,tado por my(tring Gcria,do a s%a pr=pria c=piaH e devo"ver a referJ,cia dada pe"o tipo Astring para a VA. Aas * +ara,tido $%e essa referJ,cia sea %ma referJ,cia do* respo,sabi"idade po,to de vista do da ava... ?sso si+,ifica $%eS VA se ,e,%ma f%,ão fora da ,ossa for %sar alocal stri,+ ,ossa f%,ão i,dicar $%e essa referJ,cia poder ser co"etada e co"ocada ,o "i&o... @o e&emp"o acima retor,amos a referJ,cia Go tipo stri,+ * %m po,teiroEH para o m*todo camador e dei&amos $%e e"e "ide com a referJ,cia. Aais adia,te mostrarei %m caso o,de teremos $%e "idar com a referJ,cia por ,=s mesmos...
;sando arras unidimensionais !rra#s tamb*m são obetos e comportam-se de forma m%ito parecida com stri,+s. Pe"o me,os para "eit%ra. 5 tama,o de %ma stri,+ ta,to em C $%a,to em ava pode ser co,ecido pe"o caracter Y0Y ,o fi,a" do b%ffer. @o caso de arra#s o tama,o o% * co,ecido de a,temão o% pode ser obtido atrav*s de %ma camada S f%,ão 7et1rray*engt/ da VA. ! "eit%ra de %m arra# pode ser feita %sa,do 7et`01rrayElements e elease`01rrayElements o,de correspo,de a %m tipo primitivo o% 5bect;: int *!arraQ /* ega o arraQ... */ !arraQ (*env)->CetNntZrraQ4lements(env, `avaZrraQar, UWGG) i" (!arraQ) /* +ani!ula o arraQ, em , aqui... ... /* Kinalmente, li;era o arraQ */ (*env)->HeleaseNntZrraQ4lements(env, `avaZrraQ, !arraQ, )
7et`01rrayElements f%,cio,a i+%a"i,o a 7et(tring. elease`01rrayElements tem %m
parKmetro adicio,a" $%e especifica o $%e deve ser feito do b%ffer. )"e aceita 3 va"ores: )odo
>igni#icado
0
Copiadevo"taparaoarra#avae"iberaob%ffer.
@?]C5AA? @?]!Q5N
Copiadevo"tae,ão"iberaob%ffer. @ãocopiadevo"ta. 0abela 6: 'odos aceitos &or elease`01rrayElements9
Para criar ,ovos arra#s e&istem as f%,es e`01rray $%e tomam o ,Mmero de e"eme,tos como parKmetro. )ssa f%,ão some,te a"oca espao ,a VA para %m arra#. Para pree,cJ-"o precisamos %sar a f%,ão (et`01rrayegion $%e toma o obeto da c"asse do arra# devo"vido por 1'0
e`01rray o <,dice i,icia" a $%a,tidade de e"eme,tos e o po,teiro para o ,osso arra# em C.
?sso copiar ,osso arra# para o espao previame,te a"ocado pe"a VA: int mQZrraQ[3] B, L, 3 `intZrraQ `avaZrraQ i" ((`avaZrraQ (*env)->UeNntZrraQ(env, 3)) & UWGG) (*env)->FetNntZrraQHegion(env, `avaZrraQ, , 3, mQZrraQ) 9
! coisa comea a comp"icar se tivermos arra#s com mais de %ma dime,são. Para compree,der essa comp"icaão precisamos primeiro e,te,der como "idar com o tipo obAect...
;sando obIetos 5 tipo obAect * %ma esp*cie de cori,+a ,o bara"o dos tipos do ava. Com esse tipo podemos %sar $%a"$%er tipo de re#er=ncias a o%tras c"asses de armae,ame,to i,c"%i,do arra#s c"asses obetos tipos primitivos f%,es e i,terfaces. como se obAect fosse %m po,teiro void em C. VocJ deve ter reparado $%e ,as f%,es ,ativas o se+%,do parKmetro * do tipo Aclass3N. ?sso aco,tece por$%e podemos $%erer saber de $%a" obeto a f%,ão foi camada. ),tão ,ossa f%,ão ,ativa recebe a referJ,cia t/is por esse parKmetro. ome c%idado $%e embora esse parKmetro sea dec"arado como Aclass e"e ,ão recebe %ma referJ,cia para %ma c"asse ava. )"e recebe a referJ,cia para a i,stK,cia do obeto a $%a" a f%,ão ,ative perce,ce. Para mim isso sempre foi meio estra,o: )m ava c"asses e obetos são ambos obetos;E ava tem obetos dos mais variadas. !t* mesmo arra#s são obetos. ) para "idar com obetos precisamos saber $%a" * aterKindlass(env, G+Qlass) `o;`ect o;` (*env)->Zlloc2;`ect(env, oclass)
! stri,+ passada para a f%,ão Find"lass * %ma assinatura $%e descreve a c"asse de armae,ame,to. %ma forma abreviada de descrever o obeto e a tabe"a abai&o mostra os descritores %sados.
(> Pode ser s%bstit%
1'1
Classe
Assinatura
b#te car do%b"e f"oat i,t "o,+ sort
Q C / F ? 6
void boo"ea, 0j C"assedeobeto
V O 0 L class&at/\
A*todo
GargsH0
>igni#icado
!rra# to tipo 0 c"asse ! (tring por e&emp"o * descrita como LavaX"a,+X6tri,+\; Gos po,tos são s%btit%
0abela N: *ista de assinaturas que descrevem ti&os, em \ava9
@ossa c"asse 8ello por e&emp"o poss%i as se+%i,tes assi,at%ras: 6a,ap -s :ello !u;lic class $ello !u;lic $ello() Fignature () !u;lic static void main(`ava.lang.Ftring[]) Fignature ([G`ava/lang/Ftring)
5 %ti"irio Aava& $%e acompa,a o /^ * %m pr*-processador e disassemb"er. )"e te permite ver o b#tecode +erado pe"o compi"ador Aavac bem como o%tras i,formaes... ! opão Y-sY "ista ape,as as assi,at%ras Gsi+,at%resH da c"asse. @o caso de main a assi,at%ra GLavaX"a,+.6tri,+\HV; ,os di $%e este obeto * %ma f%,ão $%e retor,a void Gos parJ,teses e o YVY ,o fi,a"H e poss%i %m M,ico ar+%me,to $%e * %m arra# para %ma stri,+ LavaX"a,+X6tri,+\;. 6%po,a $%e te,amos %ma c"asse com %m membro de dados e %m m*todo assim: !rivate Ftring[] slist !u;lic int[][] getZrraQ(int si6e, Ftring str)
!s assi,at%ras serão respectivame,te: Lava."a,+.6tri,+\; e G?\Lava."a,+.6tri,+\H?;. Aesmo f%,es são obetos ,o ava por isso poss%em assi,at%ras descritivas.
C"amando m5todos do pr%prio obIeto 6e ,ossa f%,ão ,ativa precisar camar %m m*todo do pr=prio obeto o,de foi dec"arada podemos faer a"+o assim: 1'2
// $ellokorld.`ava !u;lic class $ellokorld static FQstem.loadGi;rarQ($ello) !u;lic static native void call() !rivate void call;ac() FQstem.out.!rintln(chamada !or .) -----%<----- corte aqui -----%<----... /* de"inida como V!u;lic static void call()X na classe $ellokorld. */ UN4I2HD void UNZGG avaE$ellokorldEcall(4nv *env, `class this) `class cls `methodNJ mid /* 2;t7m a classe da re"er5ncia ao o;`eto this. */ cls (*env)->Cet2;`ectlass(env, this) /* 2;t7m o Pndice da ta;ela virtual da classe. Fe retornar UWGG signi"ica que nOo achou o m7todo. */ i" ((mid (*env)->Cet+ethodNJ(env, cls, call;ac, ())) & UWGG) /* 4@ecuta o m7todo da entrada n mid da ta;ela virtual do o;`eto. */ (*env)->alloid+ethod(env, this, mid)
5 fato de $%e 7et'et/odID precisa %sar o ,ome da f%,ão para obter s%a posião ,a tabe"a virt%a" ,os di $%e o c=di+o compi"ado via ? G \ust In 0ime com&ilerH $%e s%postame,te +era o c=di+o em assemb"# e$%iva"e,te ao b#tecode vai %sar ,ecessariame,te 00I Gun0ime 0y&e In.ormationH. ?sso $%er dier $%e o c=di+o fi,a" nunca ser tão performtico $%a,to %m c=di+o em C o% assemb" $%e aver m%ita comparaão com stri,+sE @o caso da f%,ão a ser camada precisar de parKmetros precisamos prepar-"os. ) a f%,ão "all`0'et/od aceita mM"tip"os parKmetros do mesmo eito $%e f%,es como pri,tf; o faem: / $ellokorld.`ava !u;lic class $ellokorld static FQstem.loadGi;rarQ($ello) // mem;ro de dados... usado mais adiante. !u;lic int mQKield !u;lic static native void call() !rivate void call;ac(Ftring str) FQstem.out.!rintln(str) -----%<----- corte aqui -----%<----9 UN4I2HD void UNZGG avaE$ellokorldEcall;ac(4nv *env, `class this) static char s[] hamada !elo c?digo nativo& `string str `class cls `methodNJ mid i" ((str (*env)->UeFtringWDK(env, s)) & UWGG) /* 2;t7m a classe da re"er5ncia do o;`eto this. */ cls (*env)->Cet2;`ectlass(env, this) /* 2;t7m o Pndice da ta;ela virtual da classe. Fe retornar UWGG signi"ica que nOo achou o m7todo. */ i" ((mid (*env)->Cet+ethodNJ(env, cls, call;ac, ())) & UWGG) /* 4@ecuta o m7todo da entrada n mid, do o;`eto !assando um !ar^metro adicional. */ (*env)->alloid+ethod(env, this, mid, str)
1'3
/* Givra-se da re"er5ncia. */ (*env)->JeleteGocalHe"(env, str)
! stri,+ passada para o ca""bacD; precisa ser criada e s%a referJ,cia * sempre "oca". $%e ,ão vamos devo"vJ-"a para a"+%ma f%,ão camadora temos $%e marc-"a como descartve"; %sa,do a f%,ão Delete*ocale.. 6em isso ter
Acessando membros de dados do pr%prio obIeto !cessar %m membro de dados * feito do mesmo eito $%e fiemos para co,ecer o ?/ do m*todo. 6= $%e o ?/ obtido * do membro de dados camado ,o ava de .ield: `class cls (*env)->Cet2;`ectlass(env, this) `"ieldNJ "ieldNJ (*env)->CetKieldNJ(env, cls, mQ"ield, N) int mQNntKield i" ("ieldNJ & UWGG) mQNntKield (*env)->CetNntKield(env, this, "ieldNJ) /* 9 "a6 algo com mQKield aqui. 9 */
@ão ,ecessidade de ,os "ivrarmos da referJ,cia $%e e"a perte,ce ao pr=prio obeto. @ote $%e ao obter o FieldID temos $%e passar a"*m do ,ome do campo a assi,at%ra do mesmo. /e ,ovo ava parece ser forteme,te "i+ado ao 00I. 7etFieldID pode retor,ar @LL i,dica,do $%e o membro de dados ,ão phde ser e,co,trado ,o
obeto. 5miti a verificaão de erros por p%ra pre+%ia...
4e volta aos arras: ;sando mais de uma dimensão !rra#s com mais de %ma dime,são são ,a verdade arra#s de arra#s. 5 primeiro ,
5 $%e a f%,ão em C de fato retor,a * %ma referJ,cia a %m arra# do tipo AobAect1rray. Para criar esse arra# ,o se% c=di+o vocJ %sar ebAect1rray obter os po,teiros com 7etbAect1rrayElements para cada e"eme,to do arra# %sar eInt1rray Gcomo descrito a,teriorme,teH e %sar (etInt1rrayegion para pree,cJ-"os. $%e o $%e estamos retor,a,do ao camador * %ma referJ,cia a AobAect1rray vocJ dever i,formar S VA depois de "iberar o arra# de i,teiros com eleaseInt1rrayElements $%e esses devem ser marcados como descatveis; %sa,do Delete*ocale.. 5 m*todo camador "idar comdescartveis a referJ,ciapara ao ,ão arra#ca%sa de robAects . Aas osleak arra#s maisoi,ter,os deverão estar marcad os como %m memory $%e m*todo camador ,ão foi o respo,sve" pe"a criaão destesE 5 acesso a arra#s de mM"tip"as dime,ses * feito de ma,eira seme"a,te: // 4m ava !u;lic static native int doFomething(int[][] arraQ)
! ,ossa f%,ão ,ativa recebe %m arra# de obAects e vocJ deve obter os arra#s mais i,ter,os a partir 1'4
dos e"eme,tos do arra# mais e&ter,o Gde obAectsH. Lembre-se $%e arra#s são obetos em si. )"es tJm f%,es membro atre"adas. ma de"as * 7et1rray*engt/ $%e devo"ve o ,Mmero de e"eme,tos do arra#. )ssa f%,ão pode ser %sada para co,ecer o tama,o das dime,ses: 9 /* ega elementos do !rimeiro nPvel. */ int o;`Eelements (*env)->CetZrraQGength(env, arraQ) int i "or (i i < o;`Eelements i==) /* ega elementos do segundo nPvel. */ `o;`ect o (*env)->Cet2;`ectZrraQ4lement(env, arraQ, i) int *iarr (*env)->CetNntZrraQ4lements(env, o, ) int iarrEelements (*env)->CetZrraQGength(env, o) int ` "or (` ` < iarrEelements i==) /* 9 "a6 algo com os elementos dos arraQ inteiro (!onteiro iarr). 9 */ (*env)->HeleaseNntZrraQ4lements(env, o, iarr, ) 9
) $%e recebemos o arra# do camador ,ão somos respo,sveis por "iberar $%ais$%er referJ,cias "ocais.
1'>
1'(
Capítulo 6! @sando
Contagem de re'erncias !ssim como ava o i,terpretador P#to, tamb*m tem %m garbage collector. )"e f%,cio,a de %ma ma,eira m%ito simp"es: odo obeto tem %m co,tador i,ter,o $%e comea em 1 $%a,do * i,sta,ciado e esse * co,tador * i,creme,tado a cada ve $%e * criada %ma ,ova referJ,cia ao obeto por e&emp"o se e"e * passado como parKmetro para %ma f%,ão. 6empre $%e essa referJ,cia sai do escopo o co,tador * decreme,tado. R%a,do o co,tador ce+a a ero o garbage collector; "ivra-se do obeto. 5 i,terpretador fa isso a%tomaticame,te mas ,osso c=di+o ao %sar obetos do p#to, ,ão tem esse "%&o. emos $%e %sar os macros PyOI"EF e PyODE"EF. Narame,te precisaremos %sar PyOI"EF mas devemos %sar PyODE"EF se prete,dermos marcar o obeto como descartve"; assim como faemos ,o ava com a f%,ão Delete*ocale.. PyODE"EF tem %m prob"ema. 6e a referJ,cia ce+a a ero o obeto * "iberado e tamb*m * setado para @LL. ) %sar po,teiros ,%"os ca%sa segmentation .aults. ?sso pode ser reso"vido com o %so de PyODE"EF $%e fa a mesma coisa $%e o macro a,terior mas i+,ora referJ,cias ,%"as... 5 prob"ema * $%e ao %sar PyODE"EF ,ão saberemos se ,osso pro+rama tem %m b%+ o% ,ão. bom restri,+ir se% %so para os casos o,de vocJ sabe $%e a referJ,cia pode ser @LL. )nstanciando o pt"on !bai&o temos %m es$%e"eto de pro+rama $%e %sa o i,terpretador p#to,. @osso ,osso pro+rama ospedeiro G/ostH: #include <Qthon.h> int main(int argc, char *argv[]) QENnitiali6e() i" (&QENsNnitiali6ed()) "!rint"(stderr, UOo "oi !ossPvel carregar o Qthon.'n) return B /* Wsar as "unT\es da li;!QthonI.I aqui. */ QEKinali6e() return
1'7
bem simp"es %B
Carregando um m%dulo !ssim como ,a "i,+%a+em C %m ar$%ivo com e&te,são Y.p#Y $%e co,t*m c=di+o p#to, * camado de m=d%"o;. Precisamos saber como carre+ar %m m=d%"o co,te,do ,ossas f%,es e c"asses. bem simp"es mas tem %m deta"e. P#to, carre+a se%s m=d%"os a partir de %m co,%,to de diret=rios pr*-defi,idos. Podemos saber $%ais são com esse c=di+o: #&/usr/;in/!Qthon # shosQs!ath.!Q im!ort sQs !rint sQs.!ath -----%<----- corte aqui -----%<---- ./sho)s+spa#h.p+ [/home/user/or/;oo-srcs/!Qthon, /usr/li;/!QthonL._, /usr/li;/!QthonL._/!lat-@RSESA-linu@-gnu, /usr/li;/!QthonL._/li;-t, /usr/li;/!QthonL._/li;-old, /usr/li;/!QthonL._/li;-dQnload, /usr/local/li;/!QthonL._/dist-!acages, /usr/li;/!QthonL._/dist-!acages, /usr/li;/!QthonL._/dist-!acages/NGcom!at, /usr/li;/!QthonL._/dist-!acages/gt-L., /usr/li;/!Qmodules/!QthonL._, /usr/li;/!QthonL._/dist-!acages/u;untu-sso-client]
5 primeiro diret=rio de b%sca dos m=d%"os * o diret=rio at%a". Aas isso ,ão f%,cio,a bem com m=d%"os carre+ados a partir de ,ossos pro+ramas em C. !o i,icia"iar o i,terpretador com PyOInitialize a "ista dos diret=rios estar em sys9&at/ eGceto o diret=rio at%a". Por isso temos $%e i,c"%ir o diret=rio o,de o m=d%"o se e,co,tra se ,ão for %m dos diret=rios defa%"t. ! "ista+em se+%i,te mostra como o m=d%"o mymodule9&y * carre+ado a partir do diret=rio o,de ,osso pro+rama ser camado: #include <Qthon.h> #de"ine +2JWG4EUZ+4 mQmodule void e@ecute+odule(QE2;`ect *) int main(int argc, char *argv[]) QE2;`ect *sQs, *!ath QE+odule *module QENnitiali6e() i" (&QENsNnitiali6ed()) "!rint"(stderr, UOo "oi !ossPvel carregar o Qthon.'n) return B /* Nm!orta o m?dulo sQs */ i" ((sQs QNm!ortENm!ort+odule(sQs)) & UWGG) /* sQs 7 um o;`eto que cont7m o atri;uto !ath */ i" ((!ath Q2;`ectECetZttrFtring(sQs, !ath)) UWGG) "!rint"(stderr, 4rro ao o;ter o atri;uto sQs.!ath.'n) goto end2"rogram /* Zdiciona o diret?rio corrente em sQs.!ath */ /* QGistEZ!!end() Vca!turaX a re"er5ncia do o;`eto& */ QGistEZ!!end(!ath, QFtringEKromFtring(.))
1''
module QNm!ortENm!ort+odule(+2JWG4EUZ+4) i" (module & UWGG) /* Wsar as "unT\es da li;!QthonI.I aqui. */ e@ecute+odule(module) /* UOo !recisamos mais do m?dulo. */ QEJ4H4K(module) end2"rogram QEJ4H4K(sQs) else "!rint"(stderr, 4rro ao carregar o m?dulo sQs.'n) QEKinali6e() return B QEKinali6e() return
bem verdade $%e ao camarmos PyOFinalize todas as referJ,cias serão "iberadas $%e o i,terpretador tamb*m ser descarre+ado. 5 c=di+o acima * "itera" com re"aão ao decreme,tar das referJ,cias e para isso fao %so de %m goto e de %m "abe"... Co,siderados como crias do i,fer,o por a"+%,s p%ristas... ! M,ica coisa estra,a * $%e ,ão precisamos "iberar o obeto YpatY. 5 motivo * $%e obetos co,tai,ers do tipo "istas t%p"as pi"a fi"as capt%ram; a referJ,cia de %m obeto para si. R%a,do o co,tai,er some; devido ao decreme,to de referJ,cias "eva co,si+o se%s ite,s.
7xecutando um m%dulo simples 6eparei a e&ec%ão do m=d%"o ,a f%,ão e4ecute'odule acima para faci"itar a "eit%ra do c=di+o e ,ão ser repetitivo. Para e&ec%tar %ma f%,ão simp"es em p#to, temos ape,as $%e camar a f%,ão PybAectO"allbAect passa,do o obeto a ser camado Ga f%,ãoH e se%s parKmetros. 6%po,a $%e te,amos o se+%i,te m=d%"o em p#to,: # mQmodule.!Q de" multi!lQ(a,;) !rint V+ulti!licandoX,a,!or,; return a*;
@ossa f%,ão e4ecute'odule ficaria: void e@ecute+odule(Q2;`ect *!+odule) Q2;`ect *!Kunc, *!Zrgs, *!alue /* 2;tem o o;`eto da "unTOo e veri"ica se o o;`eto 7, de "ato, uma "unTOo. */ !Kunc Q2;`ectECetZttrFtring(!+odule, multi!lQ) i" (!Kunc & UWGG Qalla;leEhec(!Kunc)) /* re!ara L !ar^metros !ara serem !assados !ara a "unTOo. */ i" ((!Zrgs QDu!leEUe(L)) & UWGG) /* 2s !arametros 3 e L sOo colocados na !osiTOo e B de uma tu!la. */ Du!leEFetNtem(!Zrgs, , Q2;`ectEKromGong(3)) tu!leEFetNtem(!Zrgs, B, Q2;`ectEKromGong(L)) /* Kinalmente, chama a "unTOo. */ !alue Q2;`ectEall2;`ect(!Kunc, !Zrgs)
1'9
/* Jei@a o nosso c?digo a!resentar o resultado. */ !rint"(alor retornado do !Qthon %ld.'n, QNntEZsGong(!alue)) /* Givra-se das re"ere5ncias */ QEJ4H4K(!alue) QEJ4H4K(!Zrgs) QEJ4H4K(!Kunc)
190
Apndice A! Bystem calls ! tabe"a de system calls abai&o * %sada pe"a i,str%ão 6W6C!LL do processador ,os sistemas Li,%& para a ar$%itet%ra &'(-(4 Gamd(4H. Nepare $%e todas as system calls estão dispo,
>igni#icado
N!U N11
@Mmero da f%,ão da s#sca"" de acordo com a tabe"a abai&o... NFL!6 * +%ardado em N11 a,tes Gse ,ecessrioH e ,o retor,o da i,str%ão 6W6C!LL. /o primeiro ao se&to parKmetro da f%,ão.
N/? N6? N/U N10 N' N9
0abela 3: Uso dos registradores numa syscall9
@ote $%e a ,ão ser pe"o re+istrador N!U N10 e N11 a i,st%ão 6W6C!LL se+%e a co,ve,ão de camada da "i,+%a+em C para o modo &'(-(4. !ssim e&ec%tar a f%,ão e4it fica assim: mov ea@,S mov edi,4INDE2J4 sQscall
"unTOo e@it. chama e@it(4INDE2J4)
5%tro e&emp"o. Para escrever %ma stri,+ ,a te"a em C %sa,do a f%,ão rite precisamos passar o .ile descri&tor o F?L)@5]6/5 o po,teiro para a stri,+ e o tama,o de"a: char *msg $ello, orld&'n rite(KNG4U2EFDJ2WD, msg, strlen(msg))
)ste descritor tem o va"or 1. !ssim a camada em assemb"# %sa,do 6W6C!LL fica: ;its SA section .data msg d; $ello, orld,@a G4UCD$ equ - msg KNG4U2EFDJ2WD equ B section .te@t 9 rite tem o !rot?ti!o ssi6eEt rite(int "d, void *;u""er, si6eEt count) mov ea@,B sQscall rite mov edi,KNG4U2EFDJ2WD mov rsi,msg mov ed@,G4UCD$ sQscall rite(KNG4U2EFDJ2WD, msg, G4UCD$) 9
Consideraç6es sobre o uso da instrução SSCALL Lembre-se $%e 6W6C!LL * %sada como i,terface e,tre o users&ace e o kernels&ace. odos os po,teiros passados atrav*s da co,ve,ão de camada e os po,teiros recebidos ,o retor,o da f%,ão Gvia re+istrador N!UH são e,dereos "i,eares v"idos para %so ,o users&ace. o caso por e&emp"o de mmap:
191
4quivalente a "a6er i" ((! mma!(UWGG, RBfL, H2DEH4ZJ b H2DEkHND4, +ZEZU2U+2WF, -B, )) UWGG) 9 error 9 mov ea@,f mma! sQscall @or edi,edi addr UWGG mov esi,RBfL length RBfL mov ed@,3 !rot H2DEH4ZJ b H2DEkHND4 mov rBd,3L "lags +ZEZU2U+2WF mov rRd,-B "d -B @or rf,rf o""set sQscall mov [!],ra@
HZI cont7m o endereTo linear do !onteiro de retorno de mma!.
or .GB ra@,ra@ 9 HZI UWGG `n6 se7nOo "or, salta a rotina de erro. 9 error 9 .GB 9
5%tra co,sideraão importa,te * a de $%e se% processador pode ,ão s%portar as i,str%es 6W6C!LLX6W6N) e as verses a,teriores 6W6)@)NX6W6)U? G,ão %se essasEH. Para verificar se se% processador s%porta este modo basta verifiacar via CP?/: mov ea@,B c!uid test ed@,@R Desta o ;it BB de 4JI. Ueste !onto, se K, FFZGG 7 su!ortada.
R%a,do o processador ,ão s%porta 6W6C!LL temos $%e %sar %m m*todo $%e em%"a as syscalls do mesmo eito $%e o modo i3'( fa. @este caso o Li,%& &'(-(4 s%porta syscalls via i,terr%pão 0&'0. 5s re+istradores $%e são %sados como parKmetros serão )!U NQU NCU N/U N6? N/? e NQP ,essa ordem. Camamos i,t 0&'0; e o va"or de retor,o * co"ocado em N!U. )sse acesso Ss syscalls *,os %ma em%"aão do $%e * feito i3'(. ! difere,a * $%e po,teiros tJm $%e ser i,formados re+istradores este,didos de ,o (4 modo bits. 5%tros tipos de parKmetros se+%em as mesmas re+ras de tipos para o %so de re+istradores. /eve-se "eva r em co,ta $%e os ,Mmeros dos servios co"oca dos em )!U são di#erentes dos %sados com a i,str%ão 6W6C!LL. Por e&emp"o a roti,a $%e imprime %ma stri,+ ficaria assim: ;its SA section .data msg d; $ello, orld,@a G4UCD$ equ - msg KNG4U2EFDJ2WD equ B section .te@t 9 rite tem o !rot?ti!o ssi6eEt rite(int "d, void *;u""er, si6eEt count) mov ea@,A sQscall rite (modo em7lado) mov edi,KNG4U2EFDJ2WD mov rsi,msg mov ed@,G4UCD$ int @R rite(KNG4U2EFDJ2WD, msg, G4UCD$) 9
Nepare $%e o ,Mmero da f%,ão syscallOrite * 4. R%a,do %samos 6W6C!LL e"e * 1. ! mesma coisa aco,tece com syscallOe4it. sa,do 6W6C!LL a f%,ão tem ,Mmero (0 com a i,t 0&'0; o va"or * 1.
Onde obter a lista de sscalls do Linux, @o c=di+o fo,te do Der,e" do Li,%& vocJ pode obter %ma "ista de s#sca""s em 192
arc/4+3entrysyscalls. )&istem dois ar$%ivos: syscallsO2H9tbl e syscallsO369tbl para camadas via
i,t 0&'0; e 6W6C!LL respectivame,te. Aais i,formaes sobre %ma s#sca"" em partic%"ar pode ser obtida ,a ma,pa+e syscalls o% ,as ma,pa+es da f%,ão da "ibc correspo,de,te. @ovame,te a co,ve,ão de camada para a i,str%ão 6W6C!LL * a mesma do P56?U &'(-(4 !Q? e&ceto pe"o re+istrador N10 e N11 GNFL!6 * retor,ado em N11EH.
;sar sscalls no Windows não 5 uma boa id5ia !ssim como ,o Li,%& o i,do8s tamb*m tem f%,es dispo,ibi "iadas pe"o Der,e" para %so ,o users&ace. @a i,(4 !P? a i,str%ão 6W6C!LL tamb*m pode ser %sada mas o co,%,to de
re+istradores de e,trada e de sa
193
Apndice ! Desen'ol'endo para indoEs usando FCC ma boa ferrame,ta para dese,vo"vime,to em C para i,do8s * o proeto 'in7% G'inimalist 7U .or %indosH. Com e"e vocJ pode %sar o gcc e o g-- e a"+%mas ferrame,tas como obAdum& stri& ar e gas. ! o%tra va,ta+em em %sar 'in7% * $%e vocJ pode dese,vo"ver para i,do8s sem sair do Li,%&...
;sando o inHW no Linux )&istem dois sabores do proeto: 'in7%2H e 'in7%36.5 procedime,to ,ão pode ser mais simp"es: ?,sta"e os pacotes ming2H e ming36: sudo a!t-get install ming3L mingSA
Com isso os compi"adores e %ti"itsios G"i,Der assemb"er arciver etcH serão i,sta"ados e ,omeados com os prefi&os iN+35ming2Hmsvc5; e 4+3O365365ming2H5;. )is %m simp"es e&emp"o de c=di+o compi"ado com o Ai,(4: /* hello.c */ #include <indos.h> int ZGGMZj kin+ain($NUFDZU4 hNnstance, $NUFDZU4 hrevNnstance, GFDH l!s6mdGine, int nmdFho) +essageMo@(UWGG, V$ello, orld&X, V$elloX, +MEN2UNUK2H+ZDN2U b +ME2j) return -----%<----- corte aqui -----%<---- A8'*'(-)'(-mi%g)32-gcc -03 -march%a#i,e -s -o #es#.eAe #es#.c -l4--s7$s+s#em4)i%do)s
! opão Y--s%bs#stem8i,do8sY tem $%e ser repassada para o "i,Der se,ão vocJ acaba com %ma ap"icaão para /56.
;sando o inHW no Windows Qai&e o Ai, de s%a preferJ,cia G32 o% (4H de %m desses sites: • )inB@32: ttp:XX888.mi,+8.or+X •
)inB@*&: ttp:XXmi,+8-8(4.so%rcefor+e.,etX
Para i,sta"ar $%a"$%er %m dos dois o procedime,to * tamb*m bem simp"es. Qasta bai&ar o i,sta"ador e e&ec%t-"o. 5 pro+rama criar %ma rvore de diret=rios por e&emp"o em ":='in7% e t%do o $%e vocJ ter $%e faer * co"ocar o s%bdiret=rio ":='in7%=bin ,a varive" de ambie,te P!I. ! partir dai poder %sar o gcc e o%tros %ti"itrios. !t%a"me,te o Ai,32 tem %m i,sta"ador ao esti"o a&t5get mas +rfico. bem Mti" ,a se"eão de pacotes; do Ai,...
19>
As bibliotecas mingwmP>dll e msvcrt>dll ! Aicrosoft dispo,ibi"ia ,o diret=rio ":=indos=system2H %ma bib"ioteca di,Kmica cmada msvcrt9dll G'icroso.t isual "-- un0imeH $%e co,t*m +a,cos; para camadas S !P? do i,do8s. )ssa bib"ioteca f%,cio,a como se fosse a libc. 'in7% precisa de o%tra bib"ioteca camada mingmG9dll $%e * %ma surrogate library para a msvcrt9dll. 6em e"a se% e&ec%tve" compi"ado com o +cc provave"me,te ,ão f%,cio,ar. ! /LL mingmG9dll * distrib%
formato compactado com o +ip porta,to * ,ecessrio $%e vocJ o descompacte a,tes de copi-"o para o i,do8s: g7%Bip /7sr/share/doc/mi%g)32-r7%#ime/mi%g)m1.dll.gB cp #es#.eAe mi%g)m1.dll C/M+*i%do)s*Dir#7al*Machi%e*Shared*=irec#or+/
!pare,teme,te isso ,ão * ,ecessrio se vocJ est "ida,do com o 'in7%36...
Limitaç6es do inHW Como era de se esperar o 'in7% ,ão distrib%i a maioria das s/ared libraries dispo,0 bib"iotecas estticas re"acio,adas S !P? do i,do8s. )ssas bib"iotecas são estticas por$%e ,a verdade são surrogates para msvcrt9dll e o%tras /LLs da !P? do i,do8s. @o e,ta,to ,o site vocJ pode e,co,trar a"+%mas bib"iotecas adicio,ais como zlib &t/reads iconv e 7'P. ! "ibc %sada ,o Ai, tamb*m ,ão * comp"eta. Por e&emp"o e"a ,ão co,t*m a f%,ão as&rint.. ) fi,a"me,te "embre-se $%e i,do8s %sa %ma co,ve,ão difere,te ,a ar$%itet%ra &'(-(4 ,o $%e co,cer,e o tama,,o de tipos i,teiros "o,+os. i,do8s %sa o padrão ?L32P(4. 5% sea Yi,tY e Y"o,+Y tJm o mesmo tama,o. 6e $%iser %sar i,teiros de (4 bits ter $%e obri+at=riame,te %sar o tipo Y"o,+ "o,+Y o% %m dos ty&ede.s defi,idos em stdint9/.
Assembl com o inHW e *AS Lembre-se $%e a co,ve,ão de camada %sada ,o i,(4 * difere,te da %sada ,o padrão P56?UE !"*m de se "embrar disso po%ca coisa m%da com re"aão ao @!6A. !pe,as o formato do ar$%ivo obeto ter $%e ser i,formado como 8i,(4; ao i,v*s de e"f(4; e ,o caso da dec"araão de e&portaão de s
/essa forma cada caracter da stri,+ oc%pa 2 b#tes ao i,v*s de %m s=: Sd Sf Se SR BS _L Sf Se S_
19(
SB L _3 _A bm.i.n.h.a. .s.t.b br.i.g... b
)m teoria isso permite o %so de (>>3> caracteres ,o co,%,to. Para %sar as f%,es do i,do8s da ma,eira mais performtica poss
/i+o isso por$%e provave"me,te vocJ ,ão ver o tipo padrão c/arOt se,do %sado em c=di+os do i,do8s... Aas * a mesma coisa $%e LP6N. ai,da mais provve" $%e vocJ e,co,tre %m tipo camao LP6N o,de o ; si+,ifica $%e o tipo ser esco"ido com base em s
5%tros tipos $%e vocJ pode e,co,trar são LPC6N e LPC6N Ge acredito o LPC6NH o,de C; si+,fica co,st;. )sses tipos são defi,idos como: tQ!ede" char * const GFDH tQ!ede" charEt * const GkFDH
)ssas defi,ies tJm a prete,são de ma,ter os c=di+os fo,te escritos em C compat
Eale a pena desenvolver aplicaç6es inteiras em assembl para Windows, )&istem d%as ma,eiras de %sarmos f%,es defi,idas em /LLs i,c"%sive as defi,idas ,a i,(4 !P?. ! primeira * faer %ma importaão esttica; dei&a,do o i,do8s carre+ar a /LL para ,=s. ! o%tra * carre+-"a di,amicame,te atrav*s das f%, es *oad*ibrary% 7etProc1ddress% e Free*ibrary%. @o primeiro caso o 'in7%36 dispo,ibi"ia %m %ti"itrio camado dlltool $%e cria %ma bib"ioteca esttica G$%e co,t*m %m ar$%ivo obetoH co,te,do os s int kNUZN kin+ain($NUFDZU4 hNnstance, $NUFDZU4 hrevNnstance, GFDH l!s6mdGine, int nmdFho) +essageMo@k(UWGG, G+inha Ftring, GZviso, +ME2j b +MEN2U4IGZ+ZDN2U) return -----%<----- corte aqui -----%<---- A8'*'(-)'(-mi%g)32-gcc -03 -S -masmi%#el msg$oA.c
197
-----%<----- corte aqui -----%<---- ?digo equivalente, em asm ;its SA section .rodata +inhaFtring Zviso
d EEut"BSleEE(+inha Ftring), d EEut"BSleEE(Zviso),
section .te@t e@tern EEim!E+essageMo@k glo;al kin+ain align BS Estart @or ec@,ec@ lea ed@,[+inhaFtring] lea rR,[Zviso] +ME2j b +MEN2UNUK2H+ZDN2U mov rfd,@A call [EEim!E+essageMo@k] 4ssas chamadas sOo sem!re indiretas& @or ea@,ea@ ret
! camada para 'essageBo4 * feita sempre de ma,eira i,direta. 5 pro+rama tem $%e saber o e,dero da roti,a $%e não est "oca"iada ,o se% pro+rama mas em U(E2H9D** Gmesmo ,o modo &'(-(4 o ar$%ivo tem esse ,omeEH. ! difere,a do c=di+o em assemb"# e o c=di+o em C * $%e o CC e,te,de +raas ao eader indos9/ $%e o po,to de e,trada do pro+rama * i,Aai,GH. @o caso do c=di+o em assemb"# o po,to de e,trada $%a,do "i,Dado %sa,do o @ Li,Der co,ti,%a se,do Ostart. Fora esse fato todo
o resto se+%e e&atame,te o mesmo m*todo %sado por pro+ramas em C: ,ecessrio "i,Dar o se% obeto co,tra a bib"ioteca importadaE $%e ,ão difere,as e syscalls são i,viveis por ca%sa da fa"ta de padro,iaão ,ão va"e " m%ito a pe,a codificar pro+ramas i,teiros em assemb"# para i,do8s. 5%tra coisa: @%m pro+rama C a *&seudo f%,ão i,Aai, 4 parKmetros Go,de opara se+%,do e&iste por motivos ist=ricosem e ,ão %sado ,a i,(4 !P?H. 5aceita compi"ador i,sere c=di+o i,icia"iar esses parKmetros atrav*s de camadas discretas a f%,es da !P?. ?sso $%er dier $%e o compi"ador C prepara o terre,o para vocJ coisa $%e ,ão aco,tece em assemb"#.
)mportando 4LLs no inHW&w23 5 Ai,(4 tem %m %ti"itrio importa,te para a importaão de f%,es co,tidas em /LLs. ratase do dlltool. )"e cria e,tre o%tras coisas %ma bib"ioteca esttica co,te,do as referJ,cias para a /LL deseada: A8'*'(-)'(-mi%g)32-dll#ool -= m+dll.dll -B m+dll.dll.de& -l m+dll.dll.a
/""too" cria dois ar$%ivos: m com e&te,são ./)F co,te,do a "ista+em dos s
9
)"e * Mti" para $%e vocJ saiba $%ais são os s
,osso pro+rama. @ote $%e ,o e&em p"o em C a,terior o sdllim&ort). @o caso das f%,es 8raper; a camada pode ser feita diretame,te mas o $%e vocJ estar cama,do * a f%,ão co,tida ,a bib"ioteca esttica ,ão a f%,ão da !P?. sar bib" iotecas estti cas para acessar f%, es de /LLs * %m m*todo co,ecido como early late binding
binding o% %,tar mais cedo; ,%ma trad%ão "itera". Podemos %,tar mais tarde;
*oad*ibrary% 7etProc1ddress% e Free*ibrary. @este caso ,ão %sa,do as f%,es da i,(4 !P?%ma precisamos ,os preoc%par obter bib"ioteca esttica e&ter,a: #include <indos.h> int EEattri;uteEE((stdcall)) (*mQ"unc)(int) 9 /* Denta carregar mQli;.dll */ i" ((h+odule GoadGi;rarQk(GmQli;.dll)) UWGG) return KZGF4 /* Denta !egar o endereTo de mQ"unc() */ i" ((mQ"unc CetrocZddressk(h+odule, GmQ"unc)) UWGG) KreeGi;rarQ(h+odule) return KZGF4 /* Kinalmente, chama mQ"unc. */ @ mQ"unc(B) KreeGi;rarQ(h+odule)
199
Apndice C! uilt-ins do FCC 5 CC poss%i diversas f%,es pro,ti,as para %so $%e permitem acesso a rec%rsos do processador. A%itas de"as são espec
escrição
]]b%i"ti,]cp%]is
Netor,a %m boo"ea,o se a s%a CP * a i,formada ,a stri,+: i" (&EE;uiltinEc!uEis(intel)) !uts(W nOo 7 Nntel&) e@it(B)
]]b%i"ti,]cp%]s%pports
/e,tre as stri,+s v"idas estão: i,te"; amd; atom; core2; corei7; ,ea"em; sa,d#brid+e; de,tre a"+%mas o%tras. Netor,a %m boo"ea,o se s%a CP s%porta a feat%re i,formada ,a stri,+. 5 %so * simi"ar S f%,ão OObuiltinOc&uOis e&ceto $%e a stri,+ pode ser: cmov; mm&; popc,t; sse; sse2; sse3; ssse3; sse4.1; sse4.2; av&; o% av&2;.
]]b%i"ti,]e&pect
sada para dar %ma dica ao brac/ &rediction do processador. 5 va"or 0 o% 1 ,o se+%,do parKmetro i,dica se o va"or esperado pe"a e&pressão * verdadeiro o% fa"so: /* Nndica que, na maioria das ve6es, a e@!ressOo ser8 verdadeira. */ i" (EE;uiitinEe@!ect(@ , B)) 9
]]b%i"ti,]c"ear]cace
/eve ser %sada com ca%te"a ape,as ,os casos mais cr !B. */ EE;uiltinEclearEcache(!B, !L)
201
]]b%i"ti,]prefetc
/eve ser evitada para ,ão ba+%,ar m%ito o a"+or
/e ,ovo evitar %sar para ,ão ba+%,ar o a"+or
or,a %ma represetaão little5endian em big5 endian o% vice-versa mas com (4 bits. F%,es como ,to" e to," fa o mesmo mas com 32 bits Ge tamb*m e&iste ]]b%i"ti,]bs8ap32H: /* 2nde @ e Q sOo do ti!o long (ou Vlong longX). */ Q EE;uiltin
@o caso das f%,es ]]b%i"ti,]cp%]is e ]]b%i"ti,]cp%]s%pport * ,ecessrio passar %ma stri,+ para testar %m rec%rso. )mbora esse sea %m m*todo fci" as stri,+s terão $%e ser a"ocadas ,o se+me,to de dados G.rodata o% .dataH. ?sso * a"+o $%e e% ,ão aprecio... !co prefer
202
/* c!u.c */ #include #include EEattri;uteEE((noinline)) static const char *getEc!uEid(void) static char c!uZu@[BL] int *!, a, ;, c, d EEc!uid(, a, ;, c, d) ! (int *)c!uZu@ *!== ; *!== d *! c return c!uZu@ int c!uEisEintel(void) return memcm!(CenuineNntel, getEc!uEid(), BL) int c!uEisEamd(void) return memcm!(ZuthenticZ+J, getEc!uEid(), BL) /* Wso * i" (getEc!uE"eatures() ;itEFF4L) 9 */ int getEsimdE"eatures(void) int a, ;, c, d, Etm! EEc!uid(B,a,;,c,d) /* 2s ;its nOo se so;re!\em, entOo 7 seguro "a6er um 2H com os valores mascarados. */ c ;itEFF43 b ;itEFFF43 b ;itEK+Z b ;itEFF4AEB b ;itEFF4AEL b ;itEZI b ;itEKBS d ;itEFF4 b ;itEFF4L b ;itE++I Etm! c b d EEc!uidEcount(_,,a,;,c,d) /* 2s ;its ainda nOo se so;re!\em e continua seguro "a6er um 2H. */ ; ;itEM+N b ;itEZIL b ;itEM+NL return Etm! b ; -----%<----- corte aqui -----%<----/* test.c */ #include #include /* de"inidas em c!u.c */ e@tern int c!uEisEintel(void) e@tern int getEsimdE"eatures(void) void main(void) !rint"(W ) i" (&c!uEisEintel()) !rint"( nOo) !rint"( 7 Nntel.'n W ) i" (&(getEsimdE"eatures() ;itEFF4L)) !rint"( nOo) !uts( su!orta FF4L.) -----%<----- corte aqui -----%<----# +ae"ile test test.o c!u.o gcc -23 -o 0 1 %.o %.c gcc -23 -marchnative -c -o 0 <
203
Apndice D! ,dulos do Gernel @a maioria das vees estamos i,teressados em dese,vo"ver pro+ramas $%e e&ec%tam ,o users&ace. Aas a"+%,s rec%rsos s= estão dispo,
Anatomia de um m%dulo simples )is o c=di+o fo,te de %m m=d%"o bem simp"es. !s macros moduleOinit e moduleOe4it re+istram as f%,es de i,icia"iaão e t*rmido do m=d%"o. )ssas f%,es devem ser marcadas com os modificadores OOinit e OOe4it respectivame,te. !s o%tras macros GA5/]L?C)@6) A5/]!I5N A5/]/)6CN?P?5@H são %sadas ape,as para doc%me,taão: #include #include #include static int EEinit initEhello(void) !rint(j4HUENUK2 2l8, ernels!ace&'n) return static void EEe@it e@itEhello(void) !rint(j4HUENUK2 Zdeus, ernels!ace&'n) moduleEinit(initEhello) moduleEe@it(e@itEhello) +2JWG4EGN4UF4(CG) +2JWG4EZWD$2H(Krederico Gam;erti issarra) +2JWG4EJ4FHNDN2U($ello module)
!"+%,s deta"es importa,tes: m m=d%"o do Der,e" pode %sar a libc mas não deve faJ-"o... preciso ter m%ito c%idado em %sar f%,es ree,tra,tes Gmarcadas com A-6afe ,a doc%me,taão da "ibcH e tomar c%idado com co,dies $%e possam ca%sar prob"emas com treads. @ote por e&emp"o $%e a f%,ão &rintk foi %sada ao i,v*s de &rint..
20>