| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874 |
- ==================== PAGE 1 ====================
- § LE CODE COMPILE 5 ; LE CODE COMPILE 5
- 5.5 read et write 5 4 { 5 read et write on
- + =
- 4 2D8C BF6202 mov di, $0262
- 0 (* 001 fileof *) 4 2D8F 1E push ds
- 1 (*11avr87*) i 2D90 E857FC call TU_DEB_RW_FICH
- ? t a 2D93 BFAE02 mov di, $02AE
- 3 (*$r+*) ; 1 2D96 1E push ds
- 4 PROGRAM desassemble_file_of; ‘4 2D97 E86DFC call TU_READ_FICHIE
- ' 5 VAR fichier: FILE OF INTEGER; i 2D9A E836E2 call TU_IO_CHECK
- 6 fiche: INTEGER; 1 | }
- i nom_fichier: STRING/$20]; a) 2D9D BF6202 mov di, $0262
- 8 BEGIN i” 2DA0 IE push ds
- 9 ASSIGN(fichier, nom_fichier); % 2DA1 E846FC call TU_DEB_RW_FICH
- 10 REWRITE(fichier); À — )DA4 BFAEO2 mov di, $02AE
- 11 READ(fichier, fiche); 4 2DA7 1E push ds
- 12 WRITE(fichier, fiche); (1 2DA8 E864FC call TU_WRITE_FICHI
- 13 CLOSE(fichier); 19 2DAB E825E2 call TU_1O_CHECK
- 14 END. Mg
- (4 —_ 2DAE is sit di, $0262
- | Fig. 5.107 Le programme desassemble_file_of. \ 2DB1 1 pus ds
- 8 progr: _file_of. À —…. 2pB2 E823FC call TU_CLOSE
- if 2DB5 E81BE2 call TU_IO_CHECK
- fl
- Voici le code généré: ‘M 2DB8 E90000 jmp FIN
- | \ de 2DBB 33C0 FIN xor ax, ax
- | 2D4D E849DD call TU_PARAGRAPHS À 2DBD E880DE call TU_HALT
- | 2D50 0600 hex 0600 ; options ‘4 2DC0 0000 hex 0000
- | k 2D52 780B hex 780B ; cs 1 |
- 4 2D54 3C15 hex SOUS iis as ‘ 7 Fig. 5.108 fichier de fiches
- | 2D56 DDO2 hex DD02 ; code
- 2D58 2E00 hex 2E00 ; globales 4
- | 2D5A 0004 hex 0004 ; min piles |
- 2D5C 00A0 hex OOAO ; max piles © Notez que:
- 2DS5E 1000 hex 1000 ; fichiers | k FMI }
- 2D60 0000 hex 0000 ; input + — toutes les primitives de traitement de fichier invoquent des routines de la librairie, en ayant
- 2D62 0000 hex 0000 ; output ; auparavant poussé sur la pile le segment correspondant au fichier et placé dans DI son décalage
- — Si la procédure utilise d’autres paramètres (nom du fichier pour ASSIGN, taille de la fiche pour
- 2D64 8BEC mov bp, sp À REWRITE, adresse de la fiche courante utilisée pour READ et WRITE...), ceux-ci sont soit
- 2D66 E814DF call TU_TAILLE_CODE | placés dans des registres soit poussés sur la pile.
- 2D69 5700 hex 570015 tarlle i
- | 2D6B 6D2D adr SAUT_PRINCI PAL 1
- 2D6D E90000 SAUT_PRINCIPAL jmp PRINCIPAL h La gestion du fichier est en fait effectuée en utilisant en mémoire un bloc de contrôle (FCB ou FIB)
- À qui contient, entre autres:
- 2D70 BF6202 PRINCIPAL mov di, $0262 i : \ l
- 2D74 LE push ds . - le nom du fichier (avec le lecteur et la table des matières utilisée)
- 2D74 57 push di } ~ la position de la prochaine lecture ou écriture
- 2D75 BFB002 mov di, $02B0 ‘M — la taille totale du fichier...
- 2D78 1E push ds il : HN
- 2D79 E806E4 call TU_POUSSE_STRING "M Le Compilateur se contente donc d’indiquer aux routines de la librairie l’adresse en mémoire de ce
- 2D7C E80FFC call TU_ASSIGN_FILE Dy B. Ces routines utiliseront les paramétres contenus dans ce bloc de contréle pour invoquer les
- q ? ons «dl fonctions DOS adéquates.
- D 2D7F BF6202 mov di, $0262 \
- | 2D82 IE push ds L
- 2D83 B90200 mov cx, $0002 {|
- | 2D86 E80EFC call TU_REWRITE !
- i} | 2D89 E847E2 call TU_10_CHECK 4
- } k
- 14 | 4
- AU COEUR DE TURBO PASCAL 304 AU COEUR DE TURBO PASCA 4 AU COEUR DE TURBO PASCAL 305 AU COEUR DE TURBO PASCAL
- ==================== PAGE 2 ====================
- 5 LE CODE COMPILE Ss LE CODE COMPILE 5 |
- 5.5 read et write 53 read et write 5.5 |
- |
- affiche_memoire(SEG (fichier), OFS(fichier)- 16,
- §.5.3.2 LE BLOC DE CONTROLE D’UN FICHIER OFS(fichier)+ SIZEOF(fichier)+ 16- 1); |
- ‘ ‘ \ ry WITH fiche_courante DO
- Alors que la version 2'de TURBO gérait directement les fichiers (nombre d’octets, position du BEGIN
- pointeur de la fiche courante etc.), la version 3 se fie entièrement à MS-DOS. WRITE(’nom <JOE> ?’); READLN(nom); |
- 1 SANS a 95 WRITE(‘age <41> ?’); READLN(age);
- M La zone réservée à la variable fichier contient donc un bloc de contrôle réduit de 76 octets qui 96 END;
- contiennent: | a WRITE (fichier, fiche_courante); |
- "il — dans les deux premiers octets $FFFF si le fichier est fermé ou le numéro de fichier s’il est q 99 affiche_memoire(SEG (fichier), OFS(fichier)- 16, |
- | | ouvert : i J 100 OFS(fichier)+ SIZEOF(fichier)+ 16- 1); |
- à | — dans les 2 octets suivants, la taille de la fiche q 101
- a RNAI { 102 CLOSE(fichier);
- a Le code généré fournit aux routines de la librairie: q 103 i
- i , ; f 104 affiche_memoire(SEG (fichier), OF S(fichier)- 16,
- ! — l’adresse du feb TURBO (qui contient le numéro du fichier et la taille de la fiche) y 105 OFS(fichier)+ SIZEOF(fichier)+ 16- 1); |
- \ | — l'adresse de la fiche courante } 106 |
- / | 107 END; (* affiche_entier *) |
- Les routines de la librairie utilisent ces informations pour effectuer les appels à MS-DOS. 108 x
- 1 109 PROCEDURE initialise;
- ti q 110 BEGIN |
- | 111 avant:= ’AAAAAAAAAAAAAAAA'’ ; |
- a | Voici un programme qui affiche le contenu du fcb actuel de TURBO: j 112 apres:= 'BBBBBBBBBBBBBBBB’ ; |
- ‘(fl | 113 END; (* initialise *) |
- i 4 114 I
- ij 0 (* 001 febtfo *) À 115 BEGIN (* principal *)
- ‘a 1 (* 28 avr 87 *) 4 116 - initialise;
- Di 2 | 117 REPEAT
- | ; PROGRAM _fcb_turbo_file_of, He Waren:
- 1 teste_fcb_turbo_file_of; È 119 WRITE('{cb, q(uitte ?');
- | | | 5 TYPE tr _array_16 caracteres= ARRAY/0..15] OF CHAR; i 120 READIKED henge WRITELN(choix);
- | 6 t fiche= RECORD \ 121 CASE choix OF
- À 7 nom: STRING[3]; 122 f : affiche fcb_turbo_file_of:
- | 8 age: INTEGER; } 123 END; Ti
- | 9 END; | 124 UNTIL choix= 'q';
- 10 VAR choix: CHAR; | 125 END. (* principal *)
- J 11 avant: t_array_16_caracteres; | |
- it 12 fichier: FILE OF r fiche; | Fig. 5.109 Le programme teste_fcb_turbo_file_of. |
- i i | 13 fiche_courante: t fiche; a - al, |
- 14 apres: t_array_16_caracteres; À | |
- | 15 |
- ij | 16 PROCEDURE affiche_memoire(p_segment, p_decalage_debut, q et voici un exemple d’exécution: |
- | | 76 END; (* affiche_memoire *) |
- i 77 |
- i 78 PROCEDURE affiche feb turbo file_of; f(cb, q(uitte ? f
- | 79 VAR ! ligne: STRING/255]; } taille fcb: 76
- | 80 BEGIN À
- | 81 WRITELN(‘raille fcb: ’, SIZEOF(fichier)); WRITELN; i $09B6: $0260 $41 $41 $41 $41 $41 : AAAAA
- || 82 À \ À $09B6:$0268 $41 $41 $41 $41 $41 $41 $41 $41 :AAAAAAAA
- | 83 affiche_memoire(SEG(fichier), OFS(fichier)- 16, | $09B6:$0270 $41 $41 $41 : AAA
- 84 OFS(fichier)+ SIZEOF(fichier)+ 16- 1);
- | 85 à
- i 86 ASSIGN(fichier, 'FILEOF DTA’ ); À
- | 87 REWRITE(fichier); |
- D. + 88 |
- il i, | ‘à |
- | | |
- i AU COEUR DE TURBO PASCAL 306 AU COEUR DE TURBO PASCAL ~ AU |
- COEUR DE TURBO PASCAL 307 AU COEUR DE TURBO PASCAL
- 1 ih
- ==================== PAGE 3 ====================
- LE CODE COMPILE
- read et write
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $O9B6:
- $O9B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $0270
- $0278
- $0280
- $0288
- $0290
- $0298
- $02A0
- $02A8
- $02B0
- $02B8
- $02B8
- $02C0
- $02C0
- $02C8
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $42
- nom <JOE> ? JOE
- age <41> ?$77
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $O9B6:
- $09B6:
- $09B6:
- $09B6:
- $O9B6:
- $09B6:
- $O9B6:
- $O9B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $0260
- $0268
- $0270
- $0270
- $0278
- $0280
- $0288
- $0290
- $0298
- $02A0
- $02A8
- $02B0
- $02B8
- $02B8
- $02C0
- $02C0
- $02C8
- $0260
- $0268
- $0270
- $0270
- $0278
- $0280
- $0288
- $0290
- $0298
- $02A0
- $02A8
- $02B0
- $02B8
- $02B8
- $02C0
- $02C0
- $02C8
- $0260
- $0268
- $0270
- $41
- $41
- $00
- $49
- $41
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $42
- $41
- $41
- $00
- $49
- $41
- $00
- $00
- $00
- $00
- $00
- $00
- $4A
- $42
- $41
- $41
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $42
- $41
- $41
- $00
- $00
- $00
- $42
- $41
- $41
- $00
- $4C
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $4F
- $42
- $41
- $41
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $42
- $41
- $41
- $00
- $00
- $00
- $41
- $41
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $42
- $41
- $41
- $06
- $00
- $00
- $00
- $42
- $41
- $41
- $06
- $00
- $4F
- $00
- $00
- $00
- $00
- $00
- $00
- $77
- $42
- $41
- $41
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $42
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $42
- $42
- $00
- $00
- $42
- $42
- $42
- $42
- $41
- $41
- $00
- $00
- $44
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $42
- $42
- $41
- $41
- $41
- $41
- BBB
- : BBBBBBB
- AU COEUR DE TURBO
- Sie
- PASCAL
- 308
- AU
- COEUR DE TURBO PASCAL
- LE CODE COMPILE
- read et write
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $09B6:
- $0270
- $0278
- $0280
- $0288
- $0290
- $0298
- $02A0
- $02A8
- $02B0
- $02B8
- $02B8
- $02C0
- $02C0
- $02C8
- f(cb, q(uitte ? q
- $00
- $49
- $41
- $00
- $00
- $00
- $00
- $00
- $00
- $4A
- $42
- $00
- $4C
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $4F
- $42
- $00
- $45
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $45
- $42
- $42
- $42
- $00
- $00
- $44
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $42
- $42
- Fig. 5.110 Le contenu du feb TURBO
- En plus de ce bloc de contrôle, la mémoire contient:
- — le véritable FCB du DOS (ici situé en $00C0:$0242, donc dans les données globales du DOS,
- parce que notre fichier est parmi les 8 premiers ouverts)
- — des tables gérées par le DOS, dont l’une est située dans le PSP de notre programme en train de
- s’exécuter
- — une table de conversion entre nos variables et les numéros de fichiers, située dans la zone des
- données globales de TURBO (en DS:$0242)'
- Compte tenu de cette floraison de tables gérées par MS-DOS et par TURBO, nous recommandons:
- — soit de n’utiliser que les procédures standard (RESET, READ...)
- — soit de gérer tout directement, en utilisant le DOS ou même le BIOS.
- 5.5.3.3 LES AUTRES PROCEDURES STANDARD
- Les autres procédures utilisables avec les fichiers de fiches (RESET, SEEK, CHAIN, ERASE,
- EXECUTE, FLUSH, RENAME, LONGSEEK, EOF, FILEPOS, LONFILEPOS, FILESIZE,
- LONGFILESIZE) sont compilées de façon similaire aux routines que nous avons présentées.
- Signalons que nous ne pouvons pas utiliser avec un fichier de fiches les fonctions EOLN,
- SEEKEOF et SEEKEOLN, qui sont réservées aux fichiers de type TEXT, ni BLOCKREAD et
- BLOCKWRITE réservées aux fichiers de blocs.
- AU COEUR DE TURBO PASCAL
- 309
- AU COEUR DE TURBO PASCAL
- ==================== PAGE 4 ====================
- LE CODE COMPILE
- read et write
- {5.5.4 LES FICHIERS DE BLOCS
- | 5.5.4.1 TRAITEMENT D’UN FICHIER DE BLOCS
- Voici un programme utilisant un fichier de blocs (FILE;):
- 0 (* 00] FILE *)
- | 1 (* 11 avr 87 *)
- 2
- M 3. (*$r+*)
- : 4 PROGRAM desassemble_fichier_de_blocs;
- 5 VAR fichier: FILE;
- | 6 tampon: ARRAY/0..$FF] OF BYTE;
- 7 nom_fichier: STRING/$20];
- 8 taille_bloc: INTEGER;
- 9 nombre_blocs, nombre_lus: INTEGER;
- : 10 BEGIN
- | | qi ASSIGN(fichier, nom_fichier);
- | 12 REWRITE(fichier, taille_bloc);
- | 13 BLOCKREAD(fichier, tampon, bre_blocs, bre_lus);
- i 14 CLOSE(fichier);
- q 15 END.
- ij | Fig. 5.111 Le programme desassemble file.
- |
- i Voici le code généré:
- | | 2D4D E849DD call TU_PARAGRAPHS
- { 2D50 0600 hex 0600 ; options
- 4 2D52 780B hex 71808 >. :cS
- iM 2D54 3C15 hex 3015 ; ds
- | 2D56 DCO2 hex DCO2 ; code
- | 2D58 3E00 hex 3E00 ; globales
- | 2DSA 0004 hex 0004 ; min piles
- i 2D5C 00A0 hex OOAO ; max piles
- 2DSE 1000 hex 1000 ; fichiers
- | 2D60 0000 hex 0000 ; input
- À | 2D62 0000 hex 0000 ; output
- 2D64 8BEC mov bp, sp
- 4 2D66 E814DF call © TU_TAILLE_CODE
- | 2D69 4E00 hex 4E00 ; taille
- | 2D6B 6D2D adr SAUT_PRINCIPAL
- ' 2D6D E90000 SAUT_PRINCIPAL jmp PRINCI PAL
- a!
- i) à
- AU COEUR DE TURBO PASCAL 310 AU COEUR DE TURBO PASCAL ~
- 5 LE CODE COMPILE §
- 55 read et write 55
- 2D70 BF6202 PRINCI PAL mov di, $0262
- 2D73 IE push ds
- 2D74 57 push di
- 2D75 BFAE03 mov di, $03AE
- 2D78 1E push ds
- 2D79 E806E4 call TU_POUSSE_STRING
- 2D7C E80FFC call TU_ASSIGN_FILE
- 2D7F BF6202 mov di, $0262
- 2D82 1E push ds |
- 2D83 57 push di |
- 2D84 AICF03 mov ax, [$03CF]
- 2D87 E8C3FD call TU_REWRITE_FIL
- 2D8A E846E2 call TU_10_CHECK
- 2D8D BF6202 mov di, $0262
- 2D90 1E push ds
- 2D91 57 push di
- 2D92 BFAE02 mov di, $02AE
- 2D95 1E push ds
- 2D96 57 push di
- 2D97 A1D103 mov ax, [$03D1]
- 2D9A 50 push ax
- 2D9B BFD303 mov di, $03D3
- 2D9E 1E push ds |
- 2D9F E8E2FD call TU_BLOCKREAD |
- 2DA2 E82EE2 call TU_IO_CHECK
- 2DAS BF6202 mov di, $0262 |
- 2DA8 1E push ds
- 2DA9 E82CFC call TU_CLOSE |
- 2DAC E824E2 call TU_10_CHECK |
- 2DAF E90000 jmp FIN
- 2DB2 33C0 FIN xor Ax soe
- 2DB4 E889DE call TU_HALT
- 2DB7. 0000 hex 0000
- Fig. 5.112 fichier de blocs.
- Notez que:
- — toutes les primitives de traitement de fichier invoquent des routines de la librairie, en ayant
- auparavant poussé sur la pile le segment correspondant au FCB du fichier et placé dans DI son
- décalage
- ~ si la procédure utilise d’autres paramètres (nom du fichier pour ASSIGN, taille du bloc pour
- REWRITE, adresse du tampon, nombre de blocs à lire, nombre de blocs effectivement lus
- pour BLOCKREAD...), ceux ci sont soit placés dans des registres soit poussés sur la pile.
- — si vous ne précisez pas la taille du bloc, TURBO utilise 128 octets par défaut
- — le nombre de blocs effectivement lus par BLOCKREAD est optionnel.
- Le bloc de contrôle utilisé par les fichiers de blocs est identique à celui des fichiers de fiches.
- AU COEUR DE TURBO PASCAL 311 AU COEUR DE TURBO PASCAL |
- ==================== PAGE 5 ====================
- LE CODE COMPILE 5
- read et write 5.5
- 5.5.4.2 LES AUTRES PROCEDURES STANDARD
- Les autres procédures utilisables avec les fichiers de blocs (RESET, SEEK, CHAIN, ERASE,
- EXECUTE, FLUSH, RENAME, LONGSEEK, EOF, FILEPOS, LONFILEPOS, FILESIZE,
- LONGFILESIZE) sont compilées de façon similaire aux routines que nous avons présentées.
- Signalons que nous ne pouvons pas utiliser avec un fichier de blocs les fonctions EOLN,
- SEEKEOF et SEEKEOLN, qui sont réservées aux fichiers de type TEXT, ni READ et WRITE
- réservées aux fichiers de fiches.
- {5.5.5 LES FICHIERS DE TYPE TEXT
- 5.5.5.1 TRAITEMENT D’UN FICHIER DE TYPE TEXT
- Voici un programme utilisant un fichier de type TEXT:
- \0 00 JA Un BR Ww D — ©
- (* 001 texte *)
- (* 11 avr 87 *)
- (*$r+*)
- PROGRAM desasemble_texte;
- VAR texte: TEXT;
- caractere: CHAR;
- nom_texte: STRING/$20);
- BEGIN
- ASSIGN(texte, nom_texte);
- REWRITE(texte);
- READ(texte, caractere);
- WRITE(texte, caractere);
- CLOSE(texte);
- END.
- Fig. 5.113 Le programme desassemble_texte.
- Voici le code généré:
- 2D4D E849DD call TU_PARAGRAPHS
- 2D50 0600 hex 0600 ; options
- 2D52 780B hex 780B ; cs
- 2D54 3C15 hex 108 te LS
- 2D56 DDO2 hex DDO2 ; code
- 2D58 3500 hex 3500 ; globales
- 2D5A 0004 hex 0004 ; min piles
- 2D5C 00A0 hex 00A0 ; max piles
- 2D5E 1000 hex 1000 ; fichiers
- 2D60 0000 hex 0000 ; input
- 2D62 0000 hex 0000 ; output
- AU COEUR DE TURBO PASCAL 312 AU COEUR DE TURBO PASCAL
- 5 LE CODE COMPILE 5
- 5.5 read et write 5.5
- 2D64 8BEC mov bp, sp
- 2D66 E814DF call TU_TAILLE_CODE
- 2D69, 5F00 hex 5F00 ; taille
- 2D6B 6D2D adr SAUT_PRINCI PAL
- 2D6D E90000 SAUT_PRINCIPAL jmp PRINCIPAL
- À 2D70 BF6202 PRINCIPAL mov di, $0262
- | 2D73 16 push ds
- 4 2D74 57 push di
- à 2D75 BF2F03 mov din!) $032F
- 1 2D78 1E push ds
- À 2D79 E806E4 call TU_POUSSE_STRING |
- a 2D7C E81EFS call TU_ASS IGN_TXT
- q 2D7F E851E2 call TU_10_CHECK
- 2D82 BF6202 mov di, $0262
- i 2D85 1E push ds
- À 2D86 B98000 mov cx, $0080
- i 2D89 E86AF5 call TU_REWRITE_TXT
- | 2D8C E844E2 call TU_10_CHECK
- À 2D8F BF6202 mov di, $0262
- } 2D92.1E push ds
- h 2D93 E86FF7 call TU_DEB_READ_TE
- q 2D96 BF2E03 mov di, $032E
- 4 2D99 1E push ds
- 2D9A E88FF9 call TU_READ_CAR
- | 2D9D E833E2 call TU_1IO_CHECK
- i 2DA0 BF6202 mov di, $0262
- a 2DA3 1E push ds
- 4 2DA4 E88DF7 call TU_DEB_W_TEXT
- f 2DA7 A02E03 mov al, [$032E]
- \ 2DAA 32E4 xor ah, ah
- 2DAC 50 push ax
- 2DAD B80000 mov ax, $0000
- 1 2DBO E8B4FA call TU_WRITE_CAR
- À | 2DB3 E81DE2 call TU_IO_CHECK
- 2DB6 BF6202 mov di, $0262
- 2DB9 1E push ds
- | 2DBA E860F6 call TU_CLOSE_TEXT
- 2DBD E813E2 call TU_1O_CHECK
- À 2DC0 E90000 jmp FIN
- À 2DC3 33C0 FIN xor ax, ax
- 2DC5 E878DE call TU_HALT
- | 2DC8 0000 hex 0000
- Fig. 5.114 fichier de type TEXT.
- à AU COEUR DE TURBO PASCAL : 313 AU COEUR DE TURBO PASCAL
- ge 2
- ==================== PAGE 6 ====================
- 5 LE CODE COMPILE s 4 5 LE CODE COMPILE s
- 5.5 read et write 5.54 5.5 read et write 5:5
- Notez que: Voici le code généré:
- — les primitives d'ouverture, fermeture, changement de nom... fonctionnent exactement comme
- pour les fichiers de fiches ou les fichiers de blocs: le compilateur ne génère que des appels àla M 2D4D E849DD call TU_PARAGRAPHS
- librairie, en passant l'adresse du FCB. Les routines de la librairie sont chargées d’effectuer les 2D50 0600 hex 0600 ; options
- | appels à MS-DOS, en utilisant les numéros de fichiers ("handle") | 2D52 780B hex 780B ; cs
- — les procédures READ et WRITE fonctionnent comme les lecture clavier ou écriture écran, 2D54 3C15 hex ACIS pds
- mais des routines d’initialisation spécifiques (TU_DEB_READ_TEXT et _ 2D56 DDO2 hex DD02 ; code
- TU_DEB_WRITE_TEXT) sont invoquées i 2D58 2700 hex 2700 ; globales
- — la taille du tampon est par défaut de $80. Cette valeur est utilisée par RESET et REWRITE. M 2D5A 0004 hex 0004 ; min piles
- Nous pouvons la modifier au moment de la déclaration: À 2D5C 00A0 hex O0A0 ; max piles
- t i 2D5E 1000 hex 1000 ; fichiers
- Do) VAR fichier _texte: TEXT[$20]; 2D60 0000 hex 0000 ; input
- ‘ i ; 2D62 0000 hex 0000 ; output
- 11 2D64 8BEC mov bp, sp
- t Le probléme est ici compliqué par: A 2D66 E814DF call TU_TAILLE_CODE
- | q 2D69 5F00 hex 5FOO ; taille
- 4 — la structure par ligne (qui doit être testable par EOLN, avec concordance de EOLN et EOF à M 2D6B 6D2D adr SAUT_PRINCI PAL
- q TRUE en fin de fichier) b !
- | — l'impossibilité de détecter à l’avance la fin de ligne ou de fichier lorsque le fichier est un 2D6D E90000 SAUT_PRINCIPAL jmp PRINCI PAL
- ’ périphérique autre que le disque (clavier, ligne série.) il
- D | — les propositions du PASCAL standard (remplacer le RETURN par un ESPACE, en _ 2D70 BF4801 PRINCIPAL mov di, $0148
- ig positionnant EOLN, possibilité de lire plusieurs entiers par READ, en les séparant par des M 2D73 1E push ds
- (4 signes d'opération, par exemple) à 2D74 E8BDF7 call TU_DEB_W_TEXT
- 11 — les choix de TURBO: utilisation de tampons par défaut, interdiction de lire des entiers séparés M 2D77 A16202 mov ax, [$0262]
- nil: par des signes + ou -, possibilités d’édition temporaire.) f 2D7A 50 push ax
- D. — la possibilité de gérer les périphériques de type caractère (le clavier, l'écran, le modem) comme _ 2D7B B80000 mov ax, $0000
- if | des fichiers de type TEXT \ 2D7E E802FB call TU_WRITE_ENTIE
- { ' — la possibilité de rediriger un fichier TEXT vers la disquette ou vers un fichier de caractére 2D81 E84FE2 call TU_I10_CHEXK
- | | q 2D84 BF4801 mov di, $0148
- À { 2D87 1E push ds
- | 5.5.5.2 LES PERIPHERIQUES COMME FICHIERS TEXT | 2D88 E8A9F7 call TU_DEB_W_TEXT
- | À 2D8B A16202 mov ax, [$0262]
- 1 i 2D8E 50 push ax
- | Voici un programme qui émet directement des caractères vers des périphériques autres que le | 2D8F B80000 mov ax, $0000
- | | périphérique standard: 1 2D92 E8EEFA call TU_WRITE_ENTIE
- | | 2D95 E83BE2 call TU_1O_CHECK
- i 0 (* 001 write4 *) À 2D98 BF4CO01 mov di, $014C
- quil 1 (*11avr87*) ) 2D9B 1E push ds
- 2 $ | 2D9C E895F7 ¢ al l TU_DEB_W_TEXT
- 1 3 (*$r+*) 4 2D9F A16202 mov ax, ($0262]
- Wy 4 PROGRAM desassemble_write_standard; | 2DA2 50 push ax
- | 3 VAR entier: INTEGER; q 2DA3 B80000 mov ax, $0000
- 6 BEGIN 1 2DA6 E8DAFA ‘call TU_WRITE_ENTIE
- | WRITE(CON, entier); 1 2DA9 E827E2 call TU_10_CHECK
- 8 WRITE(TRM, entier); |
- 9 WRITE(KBD, entier); À 2DAC BF5001 mov di, $0150
- | | 10 WRITE(LST, entier); i 2DAF 1E push ds
- || 11 END. 4 2DB0 E881F7 call TU_DEB_W_TEXT
- |. À 2DB3 A16202 mov ax, [$0262]
- ! Fig. 5.115 Le programme desassemble_write_standard. 2DB6 50 push ax
- iq À 2DB7 B80000 mov ax, $0000
- i 4 2DBA E8C6FA call TU_WRITE_ENTIE
- 14 | 2DBD E813E2 call TU_I1O_CHECK
- 1
- 1 AU COEUR DE TURBO PASCAL 314 AU COEUR DE TURBO PASCAL — AU COEUR DE TURBO PASCAL 315 AU COEUR DE TURBO PASCAL
- | if
- Ng 4
- ==================== PAGE 7 ====================
- LE CODE COMPILE 5
- 5 LE CODE COMPILE 5 ‘
- 55 readied WAS 5.5 read et write 5.5
- : D64 8BEC mov bp, sp
- 2DC0 £90000 jmp FIN 2D66 E814DF call TU-TAILLE_CODE
- hex VoO0 shen te
- 2DC3 33C0 FIN Kor ax, ax 2D69 5300 ;
- peser ae a 2D6D £90000 SAUT_PRINCIPAL jmp PRINCIPAL
- Fig. 5.116 vets des périphériques standard Ÿ à 2D70 BF4801 PRINCIPAL in6Ÿ di, $0148
- a 2D73 1E push ds
- 2D74 E88EF7 call tie
- a 2D77 BF6202 mov di,
- a Poe 2D7A IE push ds
- 4 i | — le code est identique au code d’affichage vers un fichier TEXT. Seule l’adresse du bloc de 2D7B E8C2F9 call TU_READ_ENTIER
- : ! rap dron modifiée a is ie 2D7E E852E2 call TU_IO_CHECK
- — ces fichiers TEXT sont ouverts par défaut. Il n’est pas nécessaire d’exécuter un A et un à
- 4 RESET ou REWRITE a ape heen dot A LE ROR
- 4 — les autres fichiers (AUX et USR) sont situés aux adresses $0154 et $0158. uy À ah 5 E87DF7 A 11 TU DEB READ TE
- | | — l'émission vers LST ne garantit pas que la transmission fonctionnera. Encore faut-il que la el BF6202 ae di) )$0060 1.)
- liaison série ait été initialisée correctement auparavant a Spa BIE push ds :
- a 2D8C E8B1F9 call TU_READ_ENTIER
- | 2D8F E841E2 call: - TWO, CHECK
- De façon similaire pour READ, nous avons: il 2D92 BF4C01 batho di, $014C
- ‘| 206 ES vs DEB_READ_TE
- va 2D96 E86CF7 ca a, ha A
- hate net t a 2D99 BF6202 mov di, $0262
- ii nc Sa 4 2D9C 1E push ds
- 3 (sree). ti 2D9D E8A0F9 call TU_READ_ENTIER
- 4 PROGRAM desassemble read_ standard; ne 2DAQ see ni TUDIOLCHECK
- 2. SANS INTEGER: ll 2DA3 BF5001 mov di, $0150
- 7 READ(CON, entier): 194 2DA6 1E push ds
- i SRE) ae 2DA7 E85BF7 call TU_DEB_READ_TE
- pete tng A a 2DAA BF6202 mov di, $0262
- 9 READ(KBD, entier); BY 2DAD 1E push ay
- EO, te ed Mimi ot 2DAE E88FF9 call TU_READ_ENTIER
- i . oe 2DB1 E81FE2 call TU_1IO_CHECK
- Fig. 5.117 Le programme desassemble_read_standard. 54 2DB4 E90000 jmp FIN
- y ‘1 2DB7 3300 FIN Kor ax ax
- y TE pe. | DB9 E884DE call TUL)
- L avec le code suivant: + ‘À 2DBC 0000 by 0000
- | | 2D4D E849DD dau TU_PARAGRAPHS $ i Fig. 5.118 READ des périphériques TEXT
- | 2D50 0600 hex 0600 ; options a
- | 2D52 780B hex 780B, (7) es VA
- À 2D54 3C15 hex 3C1S us al
- 1 2D56 DCO02 hex DCO02 ; code a
- | 2D58 2700 hex 2700 ; globales à
- | 2D5A 0004 hex 0004 ; min piles M
- 1 2D5C 00A0 hex OOAO ; max piles
- | 2D5E 1000 hex 1000 ; fichiers
- | 2D60 0000 hex 0000 ; input
- iW | 2D62 0000 hex 0000 ; output |
- | 1
- | | ÿ
- | uf hi,
- AU COEUR DE TURBO PASCAL 316 AU COEUR DE TURBO PAS. AU COEUR DE TURBO PASCAL 317 AU COEUR DE TURBO PASCAL
- ye
- Nuch
- ==================== PAGE 8 ====================
- 5 LE CODE COMPILE
- 5.5 read et write
- Wn
- 5.5.5.3 LE BLOC DE CONTROLE DES FICHIERS TEXT
- \ contenant:
- — aux deux premiers octets le numéro de fichier
- 1 — aux deux octets suivant: L |
- 1 — dans les bits 0 à 3, sur 4 bits le fichier logique
- est déja lu)
- | Voici un programme qui affiche ces blocs de contrôle:
- Actuellement, pour lès fichiers TEXT sur disque, TURBO utilise un bloc de contrôle limité, 1
- — dans le bit 5, une étiquette indiquant qu'un entier a été lu par READ (le caractère suivaniil
- — dans le bit 6, une étiquette indiquant que le fichier est un fichier qui peut être écrit
- — dans le bit 7, une étiquette indiquant que le fichier est un fichier qui peut être lu
- O (*O21fcbit *)
- " 1, (f28myn87 ()
- | 2
- iM 3 (*Sr+*}
- 4 PROGRAM teste_fcb_turbo_texte;
- H 5 TYPE ¢_array_16_caracteres= ARRAY/0..15] OF CHAR;
- a 6 VAR choix: CHAR;
- i 7 avant: t_array_16 caracteres;
- 4 8 fichier_texte: TEXT/$20];
- 9 apres: t_array_16_caracteres;
- | 10
- il 11 PROCEDURE affiche_octet_hexadecimal(p_octet: BYTE);
- | | 52 Le ks_hex: ARRAY/(0..15] OF CHAR= '0123456789ABCDEF' ;
- 1m 13 B
- ik 14 WRITE(ks_hex/(p_octet AND $F0) SHR 4], ks_hex[p_octet AND $0F]);
- 1 15 END; (* affiche_octet_hexadecimal *)
- | 16
- | 17 PROCEDURE affiche_entier_hexadecimal(p_entier: INTEGER);
- il 18 BEGIN
- Hi! | 19 affiche_octet_hexadecimal(HI(p_entier));
- | 20 affiche_octet_hexadecimal(LO(p_entier));
- Hl 21 END; (* affiche_entier_hexadecimal *)
- 4l 22
- 4 | 23 PROCEDURE affiche_memoire(p_segment, p_decalage_debut,
- q | 71 END; (* affiche_memoire *)
- Hi 72
- 13 PROCEDURE affiche fcb;
- | 74 VAR fcb_texte: RECORD
- | 75 numero: INTEGER;
- 118 76 etiquette: INTEGER;
- | 77 decalage_tampon: INTEGER;
- Mh 78 taille_tampon: INTEGER;
- ly 79 decalage_prochain_caractere: INTEGER;
- i 80 decalage fin_tampon: INTEGER;
- | 81 END ABSOLUTE fichier _texte;
- |
- AU COEUR DE TURBO PASCAL 318 AU COEUR DE TURBO PASC
- LE CODE COMPILE 5
- read et write 5.5
- 82 BEGIN (* affiche _fcb *);
- 83 WITH fcb_texte DO
- 84 BEGIN
- 85 affiche_entier_hexadecimal(numero);
- 86 CASE etiquette AND $000F OF
- 87 0: WRITE(’ disque’);
- 88 1: WRITE( CON’);
- 89 2: WRITE(’ KBD ’);
- 90 3: WRITE(’ LST ’);
- 91 4: WRITE(’ AUX ’);
- 92 5: WRITE(’ USR ’);
- 93 END;
- 94 [is
- i WRITE (etiquette AND $0010) SHR 4: 2);
- )
- 97 WRITE((etiquette AND $0020) SHR 5: 2);
- 98 WRITE((etiquette AND $0040) SHR 6: 2);
- 99 WRITE((etiquette AND $0080) SHR 7: 2);
- 100 WRITE(’ ’);
- 101 affiche_entier_hexadecimal(decalage_tampon); WRITE(’ ');
- 102 affiche_entier_hexadecimal(taille_ tampon); WRITE(’ ');
- 103 affiche_entier_hexadecimal(decalage_prochain_caractere); WRITE(’ ’);
- 104 affiche_entier_hexadecimal(decalage_fin_tampon);
- 105 WRITELN;
- 106 END;
- Fe END; (* affiche_le_fcb *)
- 10:
- 109 PROCEDURE affiche_fcb_turbo_texte_disque;
- 110 VAR | _caractere: CHAR;
- 111 Lentier: INTEGER;
- 112 [ ligne: STRING/80];
- 113 BEGIN (* affiche _fcb_turbo_texte *)
- 114 ASSIGN(ichier_texte, 'TEXT.TXT');
- 115 REWRITE(fichier_texte);
- 116 (* interdit:
- He READ(fichier_texte, l_caractere);
- 119 affiche_memoire(SEG(fichier_texte), OFS(fichier_texte)- 16,
- os OFS(fichier_texte)+ SIZEOF (fichier_texte)+ 16- 1);
- 122 WRITE( ligne <5678> ?’);
- i READLN(I_ ligne);
- 125 WRITELN(’'num sortie f o i tamp taille proch fin’);
- 126 affiche_fcb;
- 127
- 128 WRITELN(fichier_texte, |_ligne);
- 129 affiche_fcb;
- 130 WRITELN(fichier_texte, |_ligne);
- 131 affiche_fcb;
- 132 WRITELN(fichier_texte, |_ligne);
- 133 affiche_fcb;
- 134
- 135 CLOSE(fichier_texte);
- pee affiche_fcb; WRITELN;
- AU COEUR DE TURBO PASCAL 319 AU COEUR DE TURBO PASCAL
- ==================== PAGE 9 ====================
- LE CODE COMPILE
- read et write
- 138
- 139
- 140
- 141
- 142
- 143
- | 145
- Hi 146
- a 147
- it 148
- | 149
- M 152
- q 153
- | 154
- 155
- a 156
- 1 157
- 158
- 159
- 161
- L 162
- q
- | 163
- 164
- 11 i 165
- 166
- 167
- 168
- 169
- 170
- | 171
- | 172
- 173
- 174
- 175
- 176
- 177
- | 178
- Hil 179
- | 180
- | 181
- | 182
- 184
- 185
- | 186
- | i 188
- 1 189
- | 190
- | 191
- iy 192
- |) i 193
- ASSIGN(fichier_texte, 'TEXT.TXT');
- RESET(fichier_texte);
- (* interdit:
- WRITE(fichier_texte, l_ligne);
- i
- affiche_memoire(SEG(fichier_texte), OFS(fichier_texte)- 16,
- j OFS(fichier_texte)+ SIZEOF (fichier_texte)+ 16- 1);
- affiche_fcb;
- READ(fichier_texte, |_entier); WRITELN(’ L_entier=", entier);
- affiche_fcb;
- READ(fichier_texte, |_caractere); WRITELN(’ #, ORD(I_caractere));
- affiche_fcb;
- READLN(fichier_texte, |_entier); WRITELN(’ |_entier=’, l_entier);
- affiche_fcb;
- READ(fichier_texte, |_caractere); WRITELN(’ #, ORD(!_caractere));
- affiche_fcb;
- CLOSE(fichier_texte);
- affiche_fcb;
- END; (* affiche_fcb_turbo_texte_disque *)
- PROCEDURE affiche _fcb_turbo_texte_con;
- VAR !_caractere, |_deux: C
- HAR;
- 1 éntier: INTEGER;
- BEGIN (* affiche_fcb_turbo_texte_con *)
- ASSIGN(fichier_texte, 'CON.’);
- RESET (fichier_texte);
- affiche_fcb;
- WRITE(’ entier <5678> ?’);
- READ(fichier_texte, |_entier); WRITELN(’ | _entier=', |_entier);
- affiche_fcb;
- WRITE(’ caractere ?’);
- READ(fichier_texte, |_caractere); WRITELN(’ #, ORD(!_caractere));
- affiche_fcb;
- WRITE(’ entier ?’);
- READLN(fichier_texte, |_entier); WRITELN(’ Lentier=", l_entier);
- affiche_fcb;
- WRITE(’ caractere ?');
- READ(fichier_texte, |_caractere); WRITELN(’ #, ORD(/_caractere));
- affiche_fcb;
- CLOSE(fichier_texte);
- END; (* affiche_fcb_turbo_texte_con *)
- PROCEDURE initialise;
- BEGIN
- avant:= ’AAAAAAAAAAAAAAAA’ ;
- apres:= ’BBBBBBBBBBBBBBBB' ;
- END; (* initialise *)
- BEGIN (* principal *)
- initialise;
- REPEAT
- WRITELN;
- Hi $1677
- | AU COEUR DE TURBO PASCAL
- 320
- AU COEUR DE TURBO PASCA!
- À 5 LE CODE COMPILE 5
- 5.5 read et write 5.5
- 4 q 194 WRITE(‘f(cb disque, fc(b CON:, q(uitte ?’);
- 1 195 READ(KBD, choix); WRITELN(choix);
- | 196 CASE choix OF
- 1 ( 197 ’c’ : affiche_fcb_turbo_texte_con;
- A, 1 198 ’f : affiche _fcb_turbo_texte disque;
- À 199 ND;
- i 200 UNTIL choix= ’q’;
- 4 i 201 END. (* principal *)
- Voici un exemple d’exécution avec un fichier TEXT sur disque:
- 1 Fig. 5.119 Le programme teste_fcb_turbo_texte.
- f(cb disque, fc(b con:, q(uitte ? f
- $1677:$0260
- ‘ $1677:$0268
- { $1677:$0270
- q $1677:$0270
- i $1677:$0278
- if $1677:$0280
- À $1677:$0288
- \ $1677:$0290
- 1 $1677:$0298
- $1677: $02A0
- D $1677 :$02A8
- q $1677:$02B0
- 4 $1677:$02B8
- a $1677:$02B8
- i $1677: $02C0
- Y $1677:$02C8
- :$02D0
- :$02D8
- : $02D8
- $41
- $41
- $06
- $BF
- $2E
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $42
- $42
- $41
- $41
- $00
- $02
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $42
- $42
- $41
- $41
- $40
- $DF
- $58
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $42
- $42
- $41
- $41
- $02
- $45
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $41
- $41
- $20
- $58
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $41
- $41
- $00
- $54
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $42 $42
- $42 $42
- ? 5678
- 0 02BF
- 0 02BF
- 0 02BF
- 0 02BF
- 0 02BF
- $41
- $41 $41
- $41
- À $1677
- ) $1677
- i $1677:$02E0 $42
- | $1677:$02E8 $42
- x ligne <5678>
- 0006 disque
- i 0006 disque
- 4 0006 disque
- i 0006 disque
- | FFFF disque
- 0020
- 0020
- 0020
- 0020
- 0020
- $41 $41
- $41 $41
- oooceo
- Ome mn
- iN $1677:$0260
- 4 | $1677:$0268 $41
- | $1677:$0270 $41
- $41
- $41
- ae
- $00
- $00
- $00
- $00
- $00
- $00
- $42
- $42
- 02BF
- 02C5
- 02CB
- 02D1
- 02BF
- $41
- $41
- 02DF
- 02DF
- 02DF
- 02DF
- 02DF
- $41
- $41
- : AAAAAAAA
- : AAA
- ‘ B
- : BBBBBBBB
- : BBBBBBB
- AAAAA
- AU COEUR DE TURBO PASCAL 321
- AU COEUR DE TURBO PASCAL
- ==================== PAGE 10 ====================
- LE CODE COMPILE
- read et write
- $1677
- $1677
- $1677
- $1677
- $1677
- $1677
- $1677
- $1677
- $1677
- $1677
- $1677
- $1677
- $1677
- $1677
- $1677
- $1677
- :$0270
- :$0278
- :$0280
- :$0288
- :$0290
- :$0298
- :$02A0
- : $02A8
- :$02B0
- $1677:
- :$02B8
- :$02C0
- :$02C8
- :$02D0
- :$02D8
- :$02D8
- $1677:
- :$02E8
- $02B8
- $02E0
- $02
- $45
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $36
- $38
- $0A
- $00
- $42
- $42
- num sortie
- 0006 disque
- l_entier=
- 0006 disque
- #13
- 0006 disque
- l_entier=
- 0006 disque
- #53
- 0006 disque
- FFFF disque
- $20
- $58
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $37
- $0D
- $00
- $00
- $42
- $42
- fo
- 5678
- 110
- coo ono
- oo O©Oc©
- $00
- $38
- $OA
- $00
- $00
- $42
- $42
- $06
- $BF
- $2E
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $0D
- $35
- $00
- $00
- $42
- $42
- i
- 1
- 1
- tamp
- 02BF
- 02BF
- 02BF
- 02BF
- 02BF
- 02BF
- f(cb disque, fc(b con:, q(uitte ? q
- $00
- $02
- $54
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $OA
- $36
- $00
- $00
- $42
- $42
- $80
- $BF
- $58
- $00
- $00
- $00
- $00
- $00
- $00
- $00
- $35
- $37
- $00
- $00
- $42
- $42
- $42
- $42
- taille proch
- 0020
- 0020
- 0020
- 0020
- 0020
- 0020
- 02BF
- 02C4
- 02C4
- 02CB
- 02CC
- 02CC
- : BBBBBBBB
- : BBBBBBB
- fin
- 02BF
- 02D1
- 02D1
- 02D1
- 02D1
- 02D1
- Fig. 5.120 Affichage du bloc de contrôle d’un fichier TEXT sur disque
- Notez que:
- = lorsqu'un fichier TEXT est ouvert à l’aide de REWRITE, vous n’avez pas le droit de lire ce,
- fichier
- — lorsqu'un fichier TEXT est ouvert à l’aide de RESET, vous n’avez pas le droit d’écrire dans ce”
- fichier
- i
- 5 LE CODE COMPILE 5
- 5.5 read et write $:5
- —— -
- PP . i
- Voici ce que donne l’exécution de ce programme lorsque notre fichier est redirigé vers la console:
- f(cb disque, fc(b con:, q(uitte ? c
- f(cb disque, fc(b con:, q(uitte ? q
- num sortie f o i tamp taille proch fi
- FFFF CON 0 1 1 02BF 0020 Po2cc 02D1
- entier <5678> ? 5678
- l_entier= 5678
- FFFF COON 1 1 1 02BF 0020 02CC 02D1
- Ee a gag ? #13
- CON 0 1 1 02BF 0020 02CC
- entier ? <8765> 8765 pt
- l_entier= 8765
- FFFF CON 0 1 1 02BF 0020 02CC 02D1
- caractere ? A
- #65
- FFFF CON 0 1 1 02BF 0020 02CC 02D1
- Notez que:
- — le fichier associé à la console n’utilise
- ouverte)
- Fig. 5.121 Le bloc de contrôle d’un fichier TEXT lié à la console
- — les zones concernant le tampon ne sont plus utilisées
- — le même comportement se retrouve pour la lecture d’entiers par READ.
- {5.5.6
- RESUME
- pas un nouveau numéro de fichier (la console étant déjà
- Pour gérer les fichiers:
- — le code effectue des appels à la librairie en respectant la mécanique d
- DOS (utilisation d’un numéro de fichier tained handle), qui pe
- au DOS de gérer le véritable FCB du fichier)
- — TURBO PASCAL continue à utiliser un bloc de contrôle réduit
- si vous lisez un entier par READ, le prochain caractère (le RETURN, qui est le seul caractère,
- qui ne provoquera pas d’erreur) est conservé, et sera utilisé par le prochain READ. Dans ni
- exemple, c’est la lecture du caractère qui suit qui hérite du RETURN. Si vous lisez un entier €!
- i} utilisant READLN, le RETURN et l’INTERLIGNE seront bien consommés
- AU COEUR DE TURBO PASCAL 322 AU COEUR DE TURBO PAS
- jet
- AU COEUR DE TURBO PASCAL 323 AU COEUR DE TURBO PASCAL
- ==================== PAGE 11 ====================
- 5 LE CODE COMPILE
- 5.6 if, case, repeat, while, for 5
- (5.6 LES INSTRUCTIONS DE CONTROLE
- instructions de répétition (REPEAT, WHILE et FOR).
- 5.6.1 (IK
- Voici un programme utilisant IF:
- Fig. 5.122 Le programme desassemble_if. 4
- Voici le code compilé: À
- 2D4D E849DD call TU_PARAGRAPHS ne
- 2D50 0600 — hex 0600 ; options |
- 2D52 7B06 hex 7B06 ; cs i
- 2D54 3F10 hex BRIO) (3) a8 {
- 2D56 DB02 hex DBO2 ; code i
- 2D58 2700 hex 2700 ; globales À
- 2D5A 0004 hex 0004 ; min piles ©
- 2D5C 00A0 hex 00A0 ; max piles q
- 2D5E 1000 hex 1000 ; fichiers ad
- 2D60 0000 hex 0000 ; input wl
- 2D62 0000 hex 0000 ; output i
- 2D64 8BEC mov bp, sp Al
- 2D66 E814DF call TU_TAILLE_CODE i
- 2D69 4400 hex 4400 ; taille |
- 2D6B 6D2D adr SAUT_PRINCIPAL i
- 2D6D E90000 SAUT_PRINCIPAL jmp PRINCIPAL 4
- AU COEUR DE TURBO PASCAL 324
- AU COEUR DE TURBO PAS 4
- Examinons à présent comment TURBO compile les instructions de test (IF et CASE) et les
- 0 (*001IF *)
- 1! (iliavr 817) À
- 2 4
- 3. (*Sr+ *) af
- 4 PROGRAM desassemble_if; q
- § VAR entier: INTEGER; |
- 6 BEGIN |
- 7 IF entier= $11 4
- 8 THEN entier:= $22; À
- 9 IF entier= $33 q
- 10 THEN entier:= $44
- 11 ELSE entier:= $55;
- 12 IF TRUE |
- 13 THEN ; AY
- 14 END. |
- 5 LE CODE COMPILE 5
- = if, case, repeat, while, for 5.6
- 2p70 A16202 PRINCIPAL mov ax, [$0262
- 2D73 3D1100 cmp ax, $0011
- 2D76 7403 je THEN1
- 2D78 £90600 jmp FIN_IFI
- 2D7B B82200 THENI mov ax, $0022
- 2D7E A36202 mov [$0262], ax
- 2D81 A16202 FIN_IFI mov ax, [$0262
- 2D84 3D3300 cmp ax! 13033
- 2D87 7403 Te THEN2
- 2D89 E90900 jmp ELSE2
- 2D8C B84400 THEN2 mov ax, $0044
- 2D8F A36202. mov [$0262], ax
- 2D92 E90600 jmp FIN_IF2
- 2D95 B85500 ELSE2 mov ax, $0055
- 2D98 A36202 mov [$0262], ax
- 2D9B B80100 FIN_IF2
- 2D9E OBCO ve || Be sila
- 2DA0 7503 jnz FIN_IF3
- 2DA2 E90000 jmp FIN_IF3
- 2DA5 E90000 FIN_IF3 jmp FIN
- 2DA8 33C0 FIN
- 2DAA E893DE call TU HALT
- Fig. 5.123 Le code du programme desassemble_if.
- Notez que:
- - a Boy la condition de test évaluée, le code saute soit au THEN soit au ELSE ou à la fin du
- — comme la taille du code à exécuter lorsque la condition est vraie n°
- tail xé € n’est pas connue au mom
- de la compilation de la condition, le code met en oeuvre un saut long: m vi
- calcul de la condition
- saut court au THEN
- saut long après le code exécuté lorsque la condition est vraie
- 3 ree optimisation n'est effectuée pour accélérer l'évaluation de la condition (IF FALSE
- ND autre_condition calculera entièrement autre_condition, bien que la condition soit déjà
- fausse). Il est vrai que WIRTH n’avait pas demand i i
- pu à Pp andé que les expressions booléennes soient
- AU COEUR DE TURBO PASCAL 325 AU COEUR DE TURBO PASCAL
- ==================== PAGE 12 ====================
- 5 LE CODE COMPILE À
- 5.6 if, case, repeat, while, for } 5 LE CODE COMPILE 5
- « 3.6 if, case, repeat, while, for 5.6
- RESUME à Ce programme génère le code suivant:
- |
- La structure de IF condition THEN instruction est la suivante b ap4D ES 4 9DD cada TU_PARAGRAPHS
- ï 2D50 hex 0600 ; options
- calcul de la condition i 2D52 7B06 hex 7806 ; cs
- i Jxx debut_then | 2054 bai DOC ve
- i Sn D ex Paes d
- | JMP fin_if q 2058 Fae 4 mae 2700 ; gioperes
- ; , de 2D ex 0004 ; min piles
- fi debut_then instruction a 2D5C 00A0 hex OOAO ; max eites
- q | fin_if À 2D5E 1000 hex 1000 ; fichiers
- ae 4 2D60 0000 hex 0000 ; input
- ti me 2D62 0000 hex 0000 ; output
- if 1 et la structure de IF condition THEN instruction] ELSE instruction2: a 2D64 8BEC mov “ee
- 4 calcul de la condition ;: D 7800 en TERR TS
- a | Jxx debut_then à | 2D6B 6D2D adr SAUT_PRINCI PAL
- | JMP debut_else i 2D6D E90000 SAUT_PRINCIPAL jmp PRINCIPAL
- : A , H
- nm | debut_then D 4 2070 A16202 PRINCIPAL mov ax, [$0262]
- 14 ing c + $0
- i debut_else instruction2 4 2D76 7403 SPA PARA
- i # 7 2D78 £90900 jmp TEST_2
- L | . " al
- | | fin_if 7 2D7B B82200 CAS_1 mov ax, _ $0022
- 1 ' 2D7E A36402 mov [$0264], ax
- 4 | À 2D81 E95500 jmp FIN_CASE
- i
- q ‘ 2D84 3D2200 TEST_2 cm 0022
- À a 2D87 7C05 je. TEST 21
- nn [5.6.2 CASE à 2D89 3D3300 cmp ax, $0033
- 1 2D8C 7E03 118 O3
- | Voici un programme contenant un CASE: 2D8E E90900 TEST_21 jmp TEST_3
- i i 2D91 B84400 CAS: 2 mov ax, $0044
- | | 0 (* 001 CASE *) | Do: 436402 mov [$0264], ax
- | 1 (*11 avr 87*) } 7 E93F00 jmp FIN_CASE
- M 2. 4 2D9A 3DAAAA T AAAA
- | EST:3
- | Sy(ter+ *) i q 2D9D 7403 : à ie CAS 3
- | 4 PROGRAM desassemble_case; ‘ 2D9F E90900 i T
- i | 5 VAR selecteur, entier: INTEGER; a jmp TEST_4
- 6 BEGIN ‘à 2DA2 B85500
- ‘4 CAS_3 mov , $0055
- 9 $22..$33 : entier:= $44; jmp = FIN_CASE
- i) i gigi mena Mo À De SE TEST_4 cmp ax, $0025
- i 12 $40, $50..$60, $70 : entier:= $77; à re i CASA,
- | 13 END; j al
- 1] 14 END. : De B86600 CAS_4 mov ax, $0066
- 1 Fig. 5.124 Le programme desassemble_case. 4 mov [$0264], ax
- i, ig prog a 1 2DB9 E91D00 jmp FIN_CASE
- }
- 1 R RBO PASC CRT -
- M AU COEUR DE TURBO PASCAL 326 AU COEUR DE TU ’ AU COEUR DE TURBO PASCAL 327 AU COEUR DE TURBO PASCAL
- #
- ==================== PAGE 13 ====================
- 5 LE CODE COMPILE i 5 LE CODE COMPILE
- 5.6 if, case, repeat, while, for .( 5.6 if, case, repeat, while, for 5 4
- * — .
- 2DBC 3D4000 TEST_5 cmp ax, $0040 4 RESUME
- 2DBF 7412 je CAS 5 i
- 2DC1 3D5000 . cmp ax, $0050
- 2DC4 1608 \ jl Dor een a 1
- 2DC6 3D6000 cmp axl. A La structure du CASE P
- 2DC9 7E08 jle CAS_5 ; € du est la suivante:
- 2DCB 3D7000 TES 1 cmp aa 7 i 8
- 2DCE 7403 je Al a | :
- 2DD0 E90600 jmp $FIN_CASE : évaluation de la valeur du sélecteur
- L 4 CMP AX, éti
- LL. 2DD3 B87700 CAS_5 mov ax, $0077 a Fo) cee alana
- a | 2DD6 A36402 mov [$0264], ax i : iy
- à MI CMP AX, borne_inféri
- 0 2DD9 E90000 FIN_CASE jmp FIN 1 JL Hear meg 9
- n 7 CMP AX, &ri
- (] 2DDC 33C0 FIN xor ax, ax 4 Mao en
- a | 2DDE E85FDE call TU_HALT 4 j m
- À i ‘ . étiquette_suivante_14
- | Fig. 5.125 Le code du programme desassemble_case. CMP AX, detniére_étiquette_1
- | JE traite_cas
- nn 4 JMP teste_liste_étiquettes_2 ou fin_case
- i” | Notez que: ‘ traite_cas instructions
- 1 hs JMP fi
- 1 _ le CASE est implémenté strictement comme une cascade de IF 4 ano
- a - il n’y a donc pas de limite maximale à la valeur scalaire que peuvent prendre les étiquette ! teste_liste_étiquettes_2
- | (dans la limite de MAXINT) i
- | i — ceci explique aussi: LA
- À — la possibilité d’utiliser des plages d'étiquettes q
- D | — que lorsque plusieurs étiquettes ont la même valeur (ou qu’une valeur est située dans fin_case
- | plage des valeurs d’un autre cas) c’est la première valeur rencontrée qui est utilisée 4
- (fl — lorsque le nombre de valeurs distinctes dépasse 20, les sauts courts ne peuvent pas accéder
- li | code du cas. Un JMP_S relai est alors placé dans le code (non présenté ici) i
- i i À
- i) |
- i ' n q
- | i , { 5.6.3 REPEAT
- (A ‘0
- (M | " 1
- 1 | 4 Voici un programme avec des REPEAT:
- | Mi
- | 4 0 (*00] REPEAT *)
- i À ; (* 11 avr 87 *)
- 4
- i À 4 PROGRAM desassemble repeat;
- || a 5 VAR entier: INTEGER;
- | \ 6 BEGIN
- | ï. d REPEAT
- | 8 entier:= $11;
- | L: 9 UNTIL entier> $22;
- (| ‘ 10 REPEAT:
- 1 11 UNTIL FALSE;
- il 12 END.
- | | À Fig. 5.126 Le programme desassemble_repeat.
- iW
- AU COEUR DE TURBO PASCAL 328 AU COEUR DE TURBO PAS CA . AU COEUR DE TURBO PASCAL 329 AU COEUR DE TURBO PASCAL
- ==================== PAGE 14 ====================
- 5 LE CODE COMPILE
- 5.6 if, case, repeat, while, for 1 . LE CODE COMPILE 5
- 5.6 if, case, repeat, while, for 5.6
- — É
- Voici le code généré: RESUME
- 2D4D E849DD ©. call TU _PARAGRAPHS ~
- 2D50 0600 hex 0600 ; options Voici la structure de REPEAT instruction UNTIL condition:
- 2D52 7B06 pie Sere ; is
- 2D54 3F10 ex Tehri ks i
- 2D56 DAO2 hex DAO02 ; code debut_repeat instruction
- 2D58 2700 hex 2700 ; globales uw
- 2D5A 0004 hex 0004 ; min piles © calcul de condition
- 2D5C 00A0 hex 00A0 ; max piles | Jxx fin_repeat
- 2D5E 1000 hex 1000 ; fichiers | fi JMP debut_repeat
- 2D60 0000 hex 0000 ; input i in_repeat
- 2D62 0000 hex 0000 ; output 4
- #3
- 2D64 8BEC mov bp, sp 4
- 2D66 E814DF call © TU_TAILLE_CODE
- 2D69 2A00 hex 2A00 ; taille a
- 2D6B 6D2D adr SAUT_PRINCI PAL q {5.6.4 WHILE
- 2D6D E90000 SAUT_PRINICPAL jmp PRINCI PAL : Voici un pates aline WHILE:
- 2D70 PRINCIPAL stu y
- 4 2D70 B81100 DEBUT_REPATI mov ax, 11 \
- 11 2D73 A36202 mov [$0262], ax ‘ Pere
- LL: 2D76 A16202 mov ax, [$0262] 7
- ‘M k 3 (*$r+ *)
- l oe rear bs | sh, Seuss 4 PROGRAM desassemble while;
- jnle FIN_REPEATI 5 VAR entier: ,
- 7 | 2D7E E9EFFF jmp DEBUT_REPEATI 2 Saar INTEGER;
- | °
- i 2D81 FIN_REPEATI £ WHILE entier> $11 DO
- i! 2D81 B80000 DEBUT_REPEAT2 mov ax, $0000 9 entier:= $22;
- ff À 2D84 OBCO or Oe Vex
- a 2D86 7503 jnz FIN_REPEAT2 10 Te ee
- : 2D88 E9F6FF jmp DEBUT_REPEAT2 12 WHILE FALSE AND (entier> $33) DO;
- q 2D8B E90000 FIN_REPEAT2 jmp FIN 13 END.
- i | 2DSE 33C0 FIN ind diet él i Fig. 5.128 Le programme desassemble_while.
- i 2D90 E8ADDE call TU_HALT À
- | | Fig. 5.127 Le code du programme desassemble_repeat. À et le code correspondant:
- i Notez que: À
- | [ _ le saut arrière est effectué par un JMP, ce qui permet de traiter par une même mécanique, pe EAU call TU_PARAGRAPHS
- Ny sauts longs et courts 2D52 7B06 es ob ; Options
- ex 7 ee
- i + 3F10 hex 3F10 ; ds
- i, q 2Dse DC02 hex DCO2 ; code
- 1 4 Hi hex 2700 ; globales
- À à 2Dèc 0004 hex 0004 ; min piles
- | , 2D3E 00A0 hex OOAO ; max piles
- 2060 1000 hex 1000 ; fichiers
- 1 ‘à 2D62 0000 hex 0000 ; input
- il 0000 hex 0000 ; output
- |
- | AU COEUR DE TURBO PASCAL 330 AU COEUR DE TURBO P SC. Wire
- | AU COEUR DE TURBO PASCAL 331 AU COEUR DE TURBO PASCAL
- |
- *
- ==================== PAGE 15 ====================
- LE CODE COMPILE
- if, case, repeat, while, for
- 2D64 8BEC
- 2D66 E814DF
- M 2D69 4D00
- à 2D6B 6D2D
- R | 2D6D E90000
- 2D70 A16202
- | 2D73 3D1100
- ji. 2D76 7F03
- i 2D78 £90900
- 2D7B B82200
- i 2D7E A36202
- il 2D81 E9ECFF
- (l
- t 4
- IA 2D84 B80100
- | | 2D87 OBCO
- rn 2D89 7503
- | | 2D8B E90300
- i 2D8E E9F3FF
- 2D91 B80000
- fl 50
- A16202
- j : 2D98 3D3300
- i 2D9B B80100
- 2D9E 7FO1
- Je
- N
- ie)
- ve)
- un
- il | 2DA8 E90300
- 2DAB E9E3FF
- 2DAE E90000
- 2DB1 33C0
- E88ADE
- Notez:
- SAUT _PRINCI PAL
- PRINCIPAL
- TESTE_WHILE1
- DEBUT_WHILE1
- FIN_WHILE1
- TESTE_WHILE2
- DEBUT_WHILE2
- FIN_WHILE2
- TESTE_WHILE3
- TESTE_WHILE31
- DEBUT_WHILE3
- FIN_WAILE3
- FIN
- mov
- call
- hex
- adr
- jmp
- mov
- cmp
- jnle
- jmp
- mov
- mov
- jmp
- mov
- or
- jnz
- jmp
- jmp
- jmp
- xor
- call
- Fig. 5.129 Le code programme desassemble_while.
- bp, sp
- TU_TAILLE_CODE
- 4D00 ; progranme
- SAUT_PRINCI PAL
- PRINCI PAL
- ax, [$0262]
- ax, $0011
- DEBUT_WHILE1
- FIN_WHILE1
- ax, $0022
- [$0262], ax
- TESTE_WHILE1
- ax, $0001
- Nyy 40%
- DEBUT_WHILE2
- FIN_WHILE2
- TESTE_WHILE2
- ax, $0000
- ax
- ax, [$0262]
- ax, $0033
- ax, $0001
- TESTE_WHILE31
- ax
- cx
- Mw OX
- ax) ax
- DEBUT_WHILE3
- FIN_WHILE3
- TESTE_WHILE3
- FIN
- ax, ax
- TU_HALT
- _ l'utilisation des JMP longs pour contourner les instructions du WHILE
- l’avant ou vers l’arrière
- — l’absence d’optimisation de test des expressions booléennes
- AU COEUR DE TURBO PASCAL 332
- AU COEUR DE TURBO PASCA
- AU COEUR DE TURBO PASCAL 333
- 5 LE CODE COMPILE
- i b ,
- 5.6 if, case, repeat, while, for 5.6
- —— -
- RESUME
- Le code généré pour WHILE condition DO instruction est:
- teste_while calcul de la condition
- Jxx debut_while
- JMP fin_while
- debut_while instruction
- JMP teste_while
- fin_while
- 5.6.5 FOR
- Et un programme muni de boucles FOR:
- 0 (* 001 FOR *)
- 1 (* 11 avr 87 *)
- 2
- 3 (*$r+ *)
- 4 PROGRAM desassemble_for;
- 5 VAR indice, bornel, borne2: INTEGER;
- 6 indicel, indice2: INTEGER;
- 7 BEGIN
- 8 FOR indice:= borne! TO borne2 DO
- i WRITELN;
- 11 FOR indicel:= $10 TO $20 DO
- 12 FOR indice2:= $30 TO $40 DO
- li * indice:= SUCC(indice);
- 15 FOR indice:= $22 TO $11 DO
- 16 indice:= SUCC/(indice);
- 17 END.
- Fig. 5.130 Le programme desassemble_for.
- et voici son code:
- AU COEUR DE TURBO PASCAL
- ==================== PAGE 16 ====================
- pa iris 5 | 5. 2 LE CODE COMPILE 5
- À 6 if, ti repeat, while, for 5.6 | 5. if, case, repeat, while, for 5.6
- | 2DA9 “ue ENTRE _FOR2 inc cx
- ; 2DAA A mov [$0268], ax
- call TU_PARAGRAPHS 2DAD 51 BOUCLE_FOR2 push cx
- Pris + a hes ne AR “M à JS ph ba INIT_FOR3 ey ae $0030
- ex ; ! pus ax
- ex ,
- ort Ar hex 2700 ; globales 2DB6 91 iche on
- i 0004 hex 0004 ; min piles 2DB7 2BC8 sub ex ax
- C 00A0 hex 00A0 ; max pile 2DB9 7D03 jnl ENTRE _FOR3
- ae 1000 hex 1000 ; fichiers 2DBB E91700 jmp FIN_FOR3
- 260 0000 BER: OOM a Swe i
- 2D62 0000 hex 0000 ; output 2DBE 41 ENTRE_FOR3 inc cx
- b { 2DC2 Si Sue es ut eat
- mov Pp, Sp \ Ww us cx
- 202 ge tH call TU_TAILLE_CODE q 2DC3 A16202 he ax, [$0262]
- 2D69 A600 hex A600 ; taille 1 2DC6 40 rot vw
- i 2D6B 6D2D adr SAUT_PRINCI PAL i one 426202 mov [$0262], ax
- q pop cx
- SAUT_PRINCIPAL jmp PRINCI PAL à 2DCB 49 dec cx
- | PRINCIPAL inc w [ A]
- r Er NAT AN INIT_FORI mov ax, ($0264] 2DD2 E9EDFF imp BOUCLE_FOR3
- | pus ax q
- | 2D14 À 6602 mov ax, [$0266] 4 po is de age ts
- | ° cx 1 ec cx
- 2D78 31 Leg cx 2DD7 7407 je FIN_FOR2
- n ak
- | 2D7D £91900 imp FIN_FORI ELA aa oa HO i
- qi 2D80 41 ENTRE_FOR1 inc cx i 2DE0 B82200 INIT_FOR4 mov ax, $0022
- FA mov [$0262], ax 1 2DE3 50 if push ax
- 2D81 A36202
- LE_FORI ush cx 2DE4 B81100 mo , $0011
- 2D85 ÉBDAF7 TE call TU_DEB_RW_DEFAU ; 2DE7 59 ee) à
- 2D88 E8B4FB call TU_WRITELN 4 2DE8 91 xchg cx
- 2D8B E845E2 call = TU_IO_CHECK q 2DE9 2BC8 sub cx, ax
- 2D8E 59 pop cx À 2DEB 7D03 jnl _FOR4
- 2D8F 49 $35 oe NRA a 2DED E91700 jmp FIN_FOR4
- 2D96 E9EBFF jmp BOUCLE _FOR1 1 2DF1 A36202 mov [$0262], ax
- q bts 51 she BOUCLE _FOR4 push cx
- N_FOR1 2DF5 A16 , [$0262
- 2099 B81000 INIT. FOR2 mov ax, $0010 2DF8 40 may en [$ ]
- 2D9C 50 push ax 2DF9 A36202 mov [$0262], ax
- 2D9D B82000 oh ak $0020 preg pop ex
- ec cx
- oe 4 xchg cx 2DFE 7407 je FIN_FOR4
- jn in 1 4 jm ICLE_F
- 2Da6 £53700 imp FIN_FOR2 an
- | 2E07 E90000 FIN_FOR4 jmp FIN
- | q 2E0A 33C0 FIN xor ax | ax
- | | 2E0C E831DE call TU_HALT
- Fig. 5.131 Le code du programme desassemble_for.
- } AU COEUR DE TURBO PASCAL 335 AU COEUR DE TURBO PASCAL
- AU COEUR DE TURBO PASCAL
- : AU COEUR DE TURBO PASCAL 334
- ==================== PAGE 17 ====================
- 5 LE CODE COMPILE 5 À 5 LE CODE COMPILE 5
- 5.6 if, case, repeat, while, for 5.6 | 5.6 if, case, repeat, while, for 5.6
- ;
- Notez que: 4 |
- — le code comporte une partie initialisation, les instructions du FOR et l’incrémentation du :
- compteur
- — pendant l’initialisation, la valeur de la première borne est sauvée sur la pile (pour ne pas étre q Voici un programme comportant une instruction EXIT:
- | modifiée par l’initialisation de la seconde borne, au cas où celle-ci était réalisée par une
- fonction ayant des effets de bord)
- | O (* 001 EXIT *)
- — la valeur du compteur est indéterminée après la boucle: i à (* 10 avr 87 *)
- — si à l’entrée dans le FOR, la valeur de la borne de départ est supérieure à celle de la borne b 3 PROGRAM desassemble_exit;
- il d’arrivée, nous ne rentrons jamais dans la boucle, et la valeur du compteur n'est pas ( 4 BEGIN
- | modifiée par le FOR 14 5 EXIT;
- — si nous rentrons dans la boucle, sa valeur est égale à la borne finale à ; on
- f b
- — TURBO n’empéche pas de placer dans la boucle FOR des instructions qui modifient la valeur Mf : :
- | du compteur (et par conséquent modifient le nombre de répétitions) } Fig. 5.132 Le programme desassemble_exit.
- | — il est interdit de sauter par un GOTO dans le corps du FOR (parce que CX n'est pas sur la i
- pile). Le GOTO en dehors du FOR nécessite de méme des instructions spéciales pour dépiler
- CX. Ce cas sera examiné plus bas. à ui
- — le cas de DOWNTO est similaire au cas de TO, en remplaçant les INC par des DEC. À Voici son code:
- | Des trois instructions de répétition, FOR est, comme d’habitude, la plus complexe. |
- a 2D4D E849DD call TU_PARAGRAPHS
- i 2D50 0600 hex 0600 ; options
- i 2D52 780B hex 780B ; cs
- j RESUME i 2D54 3C15 hex 2013: Be
- a 2D56 D902 hex D902 ; code
- À 2D58 2700 hex 2700 ; globales
- Le code généré pour FOR compteur:= debut TO fin DO instruction est: A 2D5A 0004 hex 0004 ; min piles
- pl 2D5C 00A0 hex OOAO ; max piles
- 4 2D5E 1000 hex 1000 ; fichiers
- calcul des bornes q 2D60 0000 hex 0000 ; input
- stockage du nombre de répétitions dans CX 4 2D62 0000 hex 0000 ; output
- JGE entre_for iq
- JMP fin_for 4 2D64 8BEC mov bp, sp
- Î 2D66 E814DF call TU_TAILLE_CODE
- entre_for INC CX qi 2D69 1B00 hex 1B00 ; taille
- MOV [compteur], debut i 2D6B 6D2D adr SAUT_PRINCI PAL
- \\
- i
- boucle_for PUSH CX à 2D6D E90000 SAUT _PRINCIPAL jmp PRINCIPAL
- Va
- instruction if 2D70 E90900 PRINCIPAL jmp $2D7C
- \
- POP CX i] 2D73 E8ACF7 call TU_WRITE_DEFAUT
- DEC CX i 2D76 E8C6FB call TU_WRITELN
- JE fin_for i 2D79 E857E2 call TU_10_CHECK
- INC W [compteur] it
- JMP boucle_for jo 2D7C E90000 LR_2D7C jmp FIN
- fin_for a 2D7F 33C0 FIN xor AX, ae
- 2D81 E8BCDE call TU_HALT
- | 2D84 0000 hex 0000
- 1
- ! Fig. 5.133 Le code de desassemble_exit.
- i %
- i i
- it a
- IN si |
- AU COEUR DE TURBO PASCAL 336 AU COEUR DE TURBO PASCAL q AU COEUR DE TURBO PASCAL 337 AU COEUR DE TURBO PASCAL
- | i
- ==================== PAGE 18 ====================
- x] LE CODE COMPILE 5
- p : : 5 LE CODE COMPILE 4
- 5.6 if, case, repeat, while, for 5.6 36 ify ivaalitephenn vhs ited 56
- | Notez que: 2D70 PRINCIPAL
- | — le code généré effectue simplement un saut’a la fin du programme. Ceci est aussi le cas pour les 2D70 B81100 AVANT mov ax, $0011
- | EXIT o procédures . 4 NÉ 2D73 A36202 mov [$0262], ax
- | | 2D76 E9F7FF © jmp AVANT
- | {5.67 L’INSTRUCTION GOTO q 2079 ee jmp APRES
- 1 2D7C B82200 mov ax, $0022
- | Voici un programme avec des GOTO: 4 2D7F A36202 mov [$0262], ax
- | L' | 2D82 E90000 APRES jmp. FIN
- 0 (* 001 GOTO * |
- 1 ts 10 avr 87 *) ; q 2D85 33C0 FIN xor ax, ax
- 2. 4 2D87 E8B6DE call TU_HALT
- 3 (*$r+*) q 2D8A 0000 hex 0000
- \ 4 PROGRAM d bl to; hi
- 5 LABEL | Aer ARTE j Fig. 5.135 Un programme avec des GOTO .
- 6 VAR entier: INTEGER; fl,
- mJ BEGIN a
- 8, avant: À
- \ | 9 entier:= $11; Notez que:
- i 1 iT i . i
- Pare, prs — le GOTO est mis en oeuvre par de simples sauts.
- 12 entier:= $22; |
- i, 13 apres:
- 14 END. j ù :
- | Par contre lorsque nous souhaitons sortir d’une boucle FOR, le code est un peu plus compliqué:
- | Fig. 5.134 Le programme desassemble_goto. À
- | } 0 (* 001 gotof*)
- À 1 (* 10 avr 87 *)
- | Le code de ce programme est: i” 2
- ig 3 (*$r+*)
- 4 eq desassemble_goto for;
- 2D4D E849DD call TU_PARAGRAPHS 4 5 LABEL avant, apres;
- 2D50 0600 hex 0600 ; options a 6 VAR compteur: INTEGER;
- 2D52 780B hex 780B ; cs q 7 BEGIN
- | 2D54 3C15 hex 30715; ds 8 avant:
- i 2D56 D902 hex D902 ; code | 9 FOR compteur:= $11 TO $22 DO
- 2D58 2700 hex 2700 ; globales À 10 BEGIN
- | 2D5A 0004 hex 0004 ; min piles 4 11 GOTO avant;
- . 2D5C 00A0 hex 00A0 ; max piles & 12 GOTO apres;
- 2D5E 1000 hex 1000 ; fichiers 4 13 END;
- 2D60 0000 hex 0000 ; input À 14 apres:
- | | 2D62 0000 hex 0000 ; output 1 15 END.
- | 2D64 8BEC mov bp, sp Fig. 5.136 Le programme desassemble_goto_for.
- Il 2D66 E814DF call TU_TAILLE_ OCDE 1
- À 2D69 2100 hex 2100 ; taille 4
- | 2D6B 6D2D adr SAUT_PRINCI PAL q ‘ay
- 1 \ dont voici le code:
- | 2D6D E90000 SAUT_PRINCIPAL jmp PRINCI PAL 4
- L !
- ll
- !
- AU COEUR DE TURBO PASCAL 338 AU COEUR DE TURBO PASCAL
- AU COEUR DE TURBO PASCAL 339 AU COEUR DE TURBO PASCAL
- ==================== PAGE 19 ====================
- |
- |
- ï
- |
- i]
- |
- q
- |
- If
- à LE CODE COMPILE 5
- 5.6 if, case, repeat, while, for 5.6
- 2D4D E849DD call TU_PARAGRAPHS
- 2D50 0600 hex 0600 ; options
- 2D52 780B ah hex 1808108
- 2D54 3C15 hex Sees as
- 2D56 DBO2 hex DBO2 ; code
- 2D58 2700 hex 2700 ; globales |
- 2DS5A 0004 hex 0004 ; min piles 1
- 2D5C 00A0 hex 00A0 ; max piles \
- 2D5E 1000 hex 1000 ; fichiers |
- 2D60 0000 hex 0000 ; input 4
- 2D62 0000 hex 0000 ; output À
- 2D64 8BEC mov bp, sp i
- 2D66 E814DF call §TU_TAILLE_CODE 4
- 2D69 3D00 hex 3D00 ; taille M
- 2D6B 6D2D adr SAUT_PRINCI PAL
- 2D6D E90000 SAUT_PRINCIPAL jmp PRINCIPAL
- 2D70 PRINCIPAL i
- 2D70 B81100 AVANT mov ax, $0011 |
- 2D73 50 push ax q
- 2D74 B82200 mov ax, $0022 4
- 2D710) 59 pop cx i)
- 2D78 91 xchg cx if
- 2D79 2BC8 sub CX, ax q
- 2D7B 7D03 jnl ENTRE_FOR k
- 2D7D E91600 jmp FIN_FOR |
- 2D80 41 ENTRE _FOR inc cx 1
- 2D81 A36202 mov [$0262], ax 4
- 2D84 51 BOUCLE_FOR push cx q
- 2D85 E91100 jmp RELAI_GOTO_1 q
- 2D88 E91200 jmp RELAI_GOTO_2 À
- 2D8B 59 pop cx 4
- 2D8C 49 dec cx À
- 2D8D 7407 je FIN_FOR 4
- 2D8F FF066202 inc w [$0262] à
- 2D93 E9EEFF jmp BOUCLE _ FOR :
- À
- 2D96 FIN_FOR 7
- 2D96 E90800 APRES jmp FIN P
- 2D99 58 RELAI_GOTO_1 pop ax 4
- 2D9A E9D3FF jmp AVANT a
- 2D9D 58 RELAI_GOTO_2 pop ax À
- 2D9E E9FSFF jmp APRES q
- 2DA1 33C0 FIN xor ax, ax 4
- 2DA3 E89ADE call TU_HALT
- 2DA6 0000 hex 0000
- Fig. 5.137 Des GOTO hors d’une boucle FOR. Al
- AU COEUR DE TURBO PASCAL 340 AU COEUR DE TURBO PASCAL —
- i
- 4
- { 5.7.1 UN APPEL DE ROUTINE 8088
- 5 LE CODE COMPILE 3
- 5.6 if, case, repeat, while, for 5.6
- Notez que:
- — lorsqu’un GOTO vers un label situé plus loin est rencontré, le compilateur ne sait pas encore si
- ce label sera situé en dehors du FOR ou non. Il ne peut donc pas savoir s’il faut dépiler CX ou
- non. D'où les instructions spéciales, coincées à la fin du bloc, et utilisées pour tous les GOTO
- en dehors d’une boucle FOR.
- RESUME
- Les instructions EXIT et GOTO sont exécutées au moyens de sauts.
- Lorsqu’un GOTO ou un EXIT saute hors d’une boucle FOR, des
- instructions placées en fin de bloc se chargent de dépiler le nombre de
- répétitions.
- {5.7 LES APPELS DE PROCEDURES |
- Nous allons ici examiner le code généré par les appels de procédures. Une bonne compréhension
- de ce paragraphe est essentielle pour la programmation en PASCAL en général, et surtout pour la
- mise en oeuvre d’extensions de TURBO PASCAL (dépasser 64K de code, rendre des procédures
- résidentes, effectuer des EXIT de plusieurs niveaux...)
- Nous allons examiner:
- — un appel de routine en 8088
- — un appel de procédure simple
- — la pile des variables locales
- — la chaîne d’appel
- — l'accès aux variables visibles
- — les paramètres valeur
- — les paramètres variable
- — les appels de fonctions
- Commençons par examiner en détail comment est effectué un appel de routine en 8088. Voici un
- petit programme comportant un tel appel:
- ; 001 AFFA.ASM
- 29 avr 87
- org $0100
- call sous_routine
- ret
- AU COEUR DE TURBO PASCAL 341 AU COEUR DE TURBO PASCAL
- ==================== PAGE 20 ====================
- 5 LE CODE COMPILE 5
- ST les appels de procédures SF
- sous_routine push ds
- mov ax, $B000
- mov dsijolax
- mov Bhyoar
- mov [$0280] > a4
- pop ds
- ret
- Fig. 5.138 Un programme en assembleur avec appel de sous-routine
- Voici le code de ce programme aprés assemblage:
- 0100:
- 0100:
- 0100:
- 0100:
- 0100:E80100
- 0103:C3
- 0104:
- 0104:
- 0104:
- 0104:1E
- 0105 ee at
- ; 001 AFFA.ASM
- ; 29 avr 87
- org $0100
- call sous_routine
- ret
- sous_routine push ds
- mov ax, $B000
- 0108:8 mov ds, ax
- 010A:
- 010A:B041 mov al 1347
- 010C:A28002 mov [$0280], al
- 010F:
- 010F:1F pop ds
- 0110:C3 ret
- Fig. 5.139 Le code du programme
- Nous chargeons le fichier .COM correspondant. En supposant que la première adresse disponible
- soit $067B:$0000, MS-DOS:
- — construit une zone de données de $067B:$0000 à $067B:$00FF (le Program Segment Prefix)
- — charge le programme à l’adresse $067B:$0100
- — place les valeurs $067B dans les registres de segment CS, DS, SS et ES
- — place la valeur $0100 dans le compteur programme (PC)
- — place la valeur $10000 dans le pointeur de pile 8088 (SP) et pousse $0000 sur la pile (pour
- permettre le retour à MS-DOS)
- Voici le déroulement de l’exécution à partir de cet instant:
- — juste après le chargement, la valeur du compteur programme, PC, est $0100 et la valeur du
- pointeur de pile, SP, est $FFFE:
- AU COEUR DE TURBO PASCAL 342
- AU COEUR DE TURBO PASCAL
- 5 LE CODE COMPILE 5
- 57 les appels de procédures 57
- $00000
- SYSTEME
- $067B0 CS DS SS ES
- PSP de AFFA.COM
- $068B0 call... le code de AFFA.COM PC= $0100
- $068B3 Tet
- $068B4 push...
- $068C1
- $167CE $00 SP= $FFFE
- $167CF $00
- $167B0
- inutilisé
- $70000 sommet de la mémoire vive 448K
- SYSTEME
- $FFFFF
- Fig. 5.140 La mémoire juste aprés le chargement
- — le 8088 exécute l’appel de la sous-routine. Pour cela il pousse l’adresse de retour (ici'$0103)
- sur la pile et place dans PC l’adresse de la première instruction de la sous-routine (ici $0104):
- $00000
- SYSTEME
- $067B0 CS DS SS ES
- PSP de AFFA.COM
- $068B0 call... le code de AFFA.COM
- $068B3 ret
- $068B4 push... PC= $0104
- $068C1
- $167CC $03 SP= $FFFC
- $167CD $01
- $167CE $00
- $167CF $00
- $167B0
- inutilisé
- $70000 sommet de la mémoire vive 448K
- SYSTEME
- $FFFFF
- Fig. 5.141 La mémoire juste après l’appel
- AU COEUR DE TURBO PASCAL 343 AU COEUR DE TURBO PASCAL
- ==================== PAGE 21 ====================
- 5 LE CODE COMPILE 5
- S7 les appels de procédures Sit
- ‘ AU COEUR DE TURBO PASCAL 344
- — le 8088 exécute le code de la sous-routine, et arrive au RET de cette sous-routine (ici $0110). A
- ce moment, le 8088:
- — dépile la valeur située, sur le sommet de la pile
- — place cette valeur dans PC:
- $00000
- SYSTEME
- $067B0 CS DS SS ES
- PSP de AFFA.COM
- $068B0 call... le code de AFFA.COM
- $068B3 ret PC= $0103
- $068B4 push...
- $068C1
- $167CE $00 SP= $FFFE
- $167CF $00
- $167B0
- inutilisé
- $70000 sommet de la mémoire vive 448K
- SYSTEME
- $FFFFF
- Fig. 5.142 La mémoire juste aprés le retour
- Le programme se poursuit donc:
- — à l'instruction qui suit l’appel
- — SP ayant la même valeur qu’avant l’appel
- Notez que:
- — lors d’une instruction PUSH, le 8088:
- — commence par réduire la valeur de SP de 2
- — puis stocke la valeur à cette adresse, l’octet faible en tête.
- Si SP a la valeur $1234 par exemple et que AX contient la valeur $5678, alors après push ax:
- — SP aura la valeur 1232
- — l'adresse $1232 contiendra $78
- — l'adresse $1233 contiendra $56
- AU COEUR DE TURBO PASCAL
- 5 LE CODE COMPILE 5
- 5.7 les appels de procédures 1
- $00000
- $01232 $78 <-- SP
- $01233 $56
- $01234 <-- SP XX
- $01235
- $FFFFF
- Fig. 5.143 L’instruction PUSH
- — l’instruction POP place dans le registre ou la mémoire les 2 octets pointés par SP et incrémente
- SP de 2
- — voici comment s’opére le retour à MS-DOS (le RET situé en $0103):
- — SP est égal à $FFFE
- — notre instruction ret (ici en $01) retire du sommet de la pile l’adresse de retour. Ici elle a
- pour valeur $0000 (elle a été placée par MS-DOS lors du lancement du programme). Cette
- adresse est la première du PSP. A cet endroit MS-DOS a placé une instruction pour
- redonner la main à MS-DOS (ici l’instruction INT $20)
- Fondamentalement, le 8088 transfère le contrôle à la sous-routine, en sauvegardant
- automatiquement l’adresse de retour sur la pile 8088.
- {5.7.2 APPEL DE PROCEDURE SIMPLE
- ’ En PASCAL, un appel de procédure correspond aussi à un transfert de contrôle puis un retour,
- mais il faut en plus gérer les variables locales et les paramétres.
- Ces données sont placées sur la pile du 8088. Elles forment pour chaque procédure appelée une
- zone comportant:
- — les valeurs transmises par la procédure qui appelle
- — l’adresse de retour
- — l’espace nécessaire aux objets locaux
- AU COEUR DE TURBO PASCAL 345 AU COEUR DE TURBO PASCAL
- ==================== PAGE 22 ====================
- 5
- 5.7
- LE CODE COMPILE
- les appels de procédures
- 5
- 54
- Voici alors un programme comportant une seule procédure, sans variable locale ni paramètre
- appelée depuis le programme principal:
- (* 001 proc *)
- (* 11 avr 87 *)
- *$r+*
- PROGRAM desassemble_appel_ procedure;
- PROCEDURE deux;
- BEGIN
- WRITELN;
- END;
- 11 BEGIN
- 13 END.
- © © 00 -J A Un BR Ww ND = ©
- Fig. 5.144 Le programme desassemble_appel_ procedure.
- Voici le code du programme:
- 2D4D E849DD call TU_PARAGRAPHS
- 2D50 0600 hex 0600 ; options
- 2D52 7B06 hex 7B06 ; cs
- 2D54 3F10 hex 3F10 ; ds
- 2D56 DA02 hex DAO2 ; code
- 2D58 2700 hex 2700 ; globales
- 2D5A 0004 hex 0004 ; min piles
- 2D5C 00A0 hex OOAO ; max piles
- 2D5E 1000 hex 1000 ; fichiers
- 2D60 0000 hex 0000 ; input
- 2D62 0000 hex 0000 ; output
- 2D64 8BEC mov bp, sp
- 2D66 E814DF call TU_TAILLE_CODE
- 2D69 2F00 hex 2F00 ; taille
- 2D6B 6D2D adr SAUT _PRINCI PAL
- 2D6D E91700 SAUT_PRINCIPAL jmp PRINCIPAL
- 2D70 55 DEUX push bp
- 2D71 8BEC mov bp, sp
- 2D73., 55 push bp
- 2D74 E90000 jmp DEBUT _DEUX
- 2D77 E8A8F7 DEBUT_DEUX call TU_DEB_RW_DEFAU
- 2D7A E8C2FB call TU_WRITELN
- 2D7D E853E2 call TU_IO_CHECK
- 2D80 E90000 jmp FIN_DEUX
- 2D83 8BE5 FIN_DEUX mov sp, bp
- 2D85 5D pop bp
- 2D86 C3 ret
- AU COEUR DE TURBO PASCAL 346 AU COEUR DE TURBO PASCAL
- 5 LE CODE COMPILE 5
- 57 les appels de procédures $7
- 2D87 B90600 PRINCI PAL mov cx, $0006
- 2D8A E8FS5E1 call TU_STACK_CHECK
- 2D8D E8EO0FF call DEUX
- 2D90 E90000 jmp FIN
- 2D93 33C0 FIN xor AXE
- 2D95 E8A8DE call TU_HALT
- Fig. 5.145 Le code du programme desassemble_appel_procedure.
- Plaçons nous à l'endroit où le programme principal appelle la procédure (en $2D8D) et suivons le
- déroulement de l’appel.
- — initialement PC est égal à $2D8D et SP est égal à $FFFE
- $00000
- SYSTEME
- $067B0 PSP et code de PROC.COM
- PC= $2D8D
- $068C1
- $6FFFE | $0000 | SP= $FFFE
- $70000 sommet de la mémoire vive 448K
- SYSTEME
- $FFFFF
- Fig. 5.146 La mémoire avant l’appel
- — l’appel en $2D8D pousse l’adresse de retour $2D90 sur la pile et transfère le contrôle à
- r
- adresse $2D70
- $00000
- SYSTEME
- $067B0 PSP et code de PROC.COM
- PC= $2D70
- $068C1
- $6FFFC $2D90 SP= $FFFC
- : $6FFFE $0000
- $70000 sommet de la mémoire vive 448K
- SYSTEME
- $FFFFF
- Fig. 5.147 La mémoire avant l’appel
- AU COEUR DE TURBO PASCAL 347 AU COEUR DE TURBO PASCAL
- ==================== PAGE 23 ====================
- 5 LE CODE COMPILE 5
- 5.7 les appels de procédures 5.7
- — en $2D70 la procédure:
- — pousse BP
- — place SP dans BP et pousse BP:
- $00000
- SYSTEME
- $067B0 PSP et code de PROC.COM
- PC= $2D74
- $068C1
- $6FFF8 $FFFA SP= $FFF8
- $6FFFA BP_PREC
- $6FFFC $2D90
- $6FFFE $0000
- $70000 sommet de la mémoire vive 448K
- SYSTEME
- $FFFFF
- Fig. 5.148 La mémoire en $2D74
- — les instructions de $2D77 à $2D80 sont exécutées
- — pour retourner:
- — en $2D83 SP prend la valeur contenue dans BP, ici $6FFA
- — en $2D85, BP retrouve la valeur qu’il avait avant l’entrée dans cette procédure
- — en $2D86 l'instruction RET dépile $2D90 et place cette valeur dans PC, ce qui constitue le
- retour dans le programme principal
- Notez que:
- — le registre BP si soigneusement sauvegardé à l’entrée dans la procédure, et restauré avant le
- retour, est utilisé pour gérer les données locales, comme nous allons le voir plus bas
- — pour simplifier la gestion de la pile 8088 utilisée par certaines routines de la librairie, TURBO
- préfère sauvegarder la valeur de SP et la restaurer avant le retour (plutôt que de faire
- correspondre le nombre de PUSH avec le nombre de POP)
- — il y a donc ici en tout 6 octets pour sauvegarder l’environnement (adresse de retour, BP et SP).
- Avant l’appel de la procédure, en $2D8A, TURBO vérifie à l’aide de la routine
- TU_STACK_CHECK qu'il reste au moins 6 octets de mémoire libre
- — le saut en $2D6D permet de sauter le code de la procédure, qui est généré avant celui du
- programme principal, compte tenu de la syntaxe PASCAL et de la compilation en une passe
- — le saut entre le début et le corps de la procédure en $2D74 est prévu pour contourner les
- éventuelles constantes typées de la procédure
- AU COEUR DE TURBO PASCAL 348
- AU COEUR DE TURBO PASCAL
- 5 LE CODE COMPILE 5
- 5.7 les appels de procédures 5.7
- RESUME
- L'appel d’une procédure est réalisé:
- — en vérifiant que la pile contient assez de place pour accomoder la
- procédure è
- — en effectuant un CALL
- Le code de la procédure comporte:
- — les instructions de sauvegarde du contexte d’appel (ici PC et SP)
- — la mise en place de la pile locale
- — les instructions de la procédure
- — la restauration du contexte de l’appel
- {5.7.3 UNE PROCEDURE AVEC DES VARIABLES LOCALES
- Voyons a présent comment sont gérées les variables locales.
- Voici un programme avec des variables locales:
- (* 001 locales *)
- (* 28 avr 87 *)
- ( * $ r+*
- PROGRAM desassemble_procedure_avec_locales;
- PROCEDURE deux;
- VAR | entier: INTEGER;
- l caractere: CHAR;
- BEGIN
- Lentier:= $77;
- ! caractere:=’A’;
- END;
- BEGIN
- deux;
- END.
- ee EE
- DU B © D = © 10 00 AU B W D = ©
- Fig. 5.149 Le programme desassemble_procedure_avec_locales.
- Et voici le code correspondant:
- AU COEUR DE TURBO PASCAL 349 AU COEUR DE TURBO PASCAL
- ==================== PAGE 24 ====================
- 5 LE CODE COMPILE sa LE CODE COMPILE 5
- 5.7 les appels de procédures 5.7 0! a les appels de procédures 57
- q
- 2D4D E849DD call TU_PARAGRAPHS | $00000
- 2D50 0600 hex 0600 ; options ; } SYSTEME
- 2D52 7B06 hex 7B06 ; cs $067B0
- 2D54 3F10 ÿ hex 3F10 ; ds 4 PSP et code de LOCALES.COM
- 2D56 DBO2 hex DBO2 ; code q PC= $2D74
- | 2D58 2700 hex 2700 ; globales q
- 2D5A 0004 hex 0004 ; min piles j $068C1
- 2D5C 00A0 hex OOAO ; max
- 2D5E 1000 hex 1000 ; fichiers 7
- 2D60 0000 hex 0000 ; input
- 2D62 0000 hex 0000 ; output q
- | 4
- # $6FFF8 $FFFA SP= $FFF8
- j 2D64 8BEC mov bp, sp 1 = $FFFA
- j 2D66 E814DF call TU_TAILLE_CODE poset peti vias iis |b
- 2D69 3E00 hex 3E00 ; taille À $6FFFE $0000
- 2D6B 6D2D adr SAUT_PRINCI PAL 4 $70000 sommet de la mémoire vive 448K
- | 2D6D E92600 SAUT_PRINCIPAL jmp PRINCIPAL À SFFFFF pee oy
- | 2D70 55 DEUX push bp ‘
- | 2D71 8BEC mov bp, sp ; F :
- | 2D73 55 uae be 1 Fig. 5.151 La mémoire en $2D74
- 7 2D74 E90000 jmp DEBUT _DEUX
- | 2D77 83EC03 DEBUT_DEUX sub sp, $03 i — les variables locales vont être placées en SS:$FFF6 et SS:$FFF7 pour /_entier et en SS:$FFF5
- q 2D7A B87700 mov ax, $0077 #4 poe
- 2D7D 8946FC mov [bp+ $FC], ax ; | Pour éviter que ces données ne soient détruites par des appels subséquents de routines, le code
- 2080 B841 00 ay we $004 1 1 déplace alors le sommet de la pile de 3 octets. C'est le résultat de l'instruction en $2D77.
- | 2D83 B9000 mov cx, $0000 : itüdtions
- | 2D86 BAFF00 po dx. $00FF À | Voilà alors la situation:
- i 2D89 E8E8E1 call TU_RANGE_CHECK À j
- ji 2D8C 8846FB mov [bp+ $FB], al 4 $00000
- | | 2D8F E90000 jmp FIN_DEUX À SYSTEME
- | | | ; $067B0
- | | 2D92 8BES FIN_DEUX mov sp, bp 4 PSP et code de LOCALES.COM
- | 2D94 5D pop bp | PC= $2D77
- | 2D95 C3 ret \ |
- i 4 068C1
- | 2D96 B90900 PRINCIPAL mov cx, $0009 i *
- | | 2D99 E8E6E1 call TU_STACK_CHECK q
- 2D9C E8D1FF call LC_2D70 4 | S6FFFS SP= $FFFS
- 1 2D9F E90000 jmp $2DA2 i )
- q a $6FFF8 $FFFA
- | 2DA2 33C0 LR_2DA2 xor ax, as a $6FFFA BP_PREC BP= $FFFA
- 2DA4 E899DE call TU_HALT 4 S6FFFC $2D90
- | } i $6FFFE $0000
- i Fig. 5.150 Le code de desassemble_procedure_avec_locales. a $70000 sommet de la mémoire vive 448K
- ! SYSTEME
- i ‘ $FFFFF
- || Nous voyons ici comment TURBO utilise la pile 8088 pour stocker les variables locales, en :
- | . utilisant BP pour accéder à ces variables: À Fig. 5.152 La mémoire en $2D77
- * — après la fin du prologue de la procédure, en $2D74, la mémoire a l’allure suivante: 4
- AU COEUR DE TURBO PASCAL 350 AU COEUR DE TURBO PASCAL — AU COEUR DE TURBO PASCAL 351 AU COEUR DE TURBO PASCAL
- ==================== PAGE 25 ====================
- |
- |
- |
- 5 LE CODE COMPILE ke
- 517 les appels de procédures Sf
- — pour stocker la premiére variable locale, qui est un entier et utilise 2 octets, TURBO utilise:
- mov [BP+ $FFFC], ax
- Comme BP a pour valeur $FFFA, et qu’il ne faut pas détruire la valeur de SP préservée sur la
- pile, il faut donc reculer de 4 octets. pour stocker la variable. D'où le décalage de $FFFC par
- rapport à BP: |
- $00000
- SYSTEME
- $067B0
- PSP et code de LOCALES.COM
- PC= $2D80
- $068C1
- $6FFF5 SP= $FFF5
- $6FFF6 $0077 Lentier à l'adresse [BP+ $F FFC]
- $6FFF8 $FFFA
- $6FFFA BP_PREC BP= $FFFA
- $6FFFC $2D90
- $6FFFE $0000
- $70000 sommet de la mémoire vive 448K
- SYSTEME
- $FFFFF
- Fig. 5.153 La mémoire après /_entier:= $77
- — de façon similaire, la variable suivante sera placée à SS:$FFFS, soit [BP+ $FFFB]:
- $00000
- SYSTEME
- $067B0
- PSP et code de LOCALES.COM
- PC= $2D8F
- $068C1
- “
- $6FFF5 $61 | caractere à l'adresse [BP+ $FFFB]
- $6FFF6 $0077 L_entier à l'adresse [BP+ $FFFC]
- ri $FFFA
- FFFA BP_PREC BP= $FFFA
- $6FFFC $2D90 ‘
- $6FFFE $0000
- $70000 sommet de la mémoire vive 448K
- SYSTEME
- $FFFFF
- Fig. 5.154 La mémoire après /_caractere:= ’A’
- AU COEUR DE TURBO PASCAL 352 AU COEUR DE TURBO PASCAL
- 5 LE CODE COMPILE 5
- 5.7 les appels de procédures si
- Notez que:
- — avant l’appel, TURBO vérifie qu’il reste bien 9 octets sur la pile 8088 (6 octets pour le contexte
- et 3 octets pour les variables locales)
- — les variables locales sont placées sur la pile dans l’ordre où le compilateur les a rencontrées (la
- dernière variable rencontrée est à la plus faible adresse) À
- — lorsque le déplacement par rapport à BP est court, le code généré utilise le déplacement sur un
- octet:
- MOV [BP+ $FC], ax
- RESUME
- Les variables locales:
- — sont situées sur la pile, après (plus près de zéro) l’environnement de
- sauvegarde et d’accès de la procédure |
- — sont accédées en utilisant BP avec des décalages négatifs
- dernière variable locale <--- SP
- variable locale2
- première variable locale [BP+ $FFFD]
- valeur du BP actuel
- valeur du BP de l’appelant <--- BP
- adresse de retour
- (5.74 UNE CHAINE D’APPELS
- Voici par conséquent comment se fait une suite d’appels de procédures:
- (* 001 appch *)
- (* 29 avr 87 *)
- (*$r+*
- PROGRAM appel_chaine;
- PROCEDURE deux;
- VAR ! locale_2]: INTEGER;
- | Tocale_22: INTEGER;
- 00 JAN Un B W D = ©
- AU COEUR DE TURBO PASCAL
- AU COEUR DE TURBO PASCAL 353
- ==================== PAGE 26 ====================
- LE CODE COMPILE 5
- 5 LE CODE COMPILE 5
- 5.7 les appels de procédures 5.7 = eS SS eee a2
- p77 83EC04 DEBUT_DEUX sub sp, $04
- 9 BEGIN (* deux *) 2D7A B82211 mov ax, $1122
- 10 1 locale_21:= $1122; 2D7D 8946FC mov [bp+ $FC], ax
- 11 E locale 22:= $2222; 2D80 B82222 mov ax, $2222
- 12 WRITELN; | 2D83 8946FA mov [bp+ SFA], ax
- 7 END; (* deux *) { 2D86 one reek TU_WRITE_DEFAUT
- 8B3F TU_WRITE
- | 15 PROCEDURE rrois; ÿ 2D89 Essia. de haat bill
- 16 VAR 1 locale 3: INTEGER; 1 2D8C Ed : woo
- 17 BEGIN (* trols *) nr on i
- 18 | locale_3:= $3333; i 2D92 8BE5 FIN_DEUX mov sp, bp
- 19 de | 2D94 5D pop bp
- ! 20 END; (* trois *) 2D95 C3 ret
- j 21 |
- 22 PROCEDURE quatre; TROIS h
- 23 VAR | locale_4: INTEGER; 1 4 FRE] ps +p sp
- 24 BEGIN (* quatre *) É 2D99 55 push bp
- 25 l_locale_4:= $4444; : 2D9A E90000 jmp DEBUT_TROIS
- 26 trois; i
- | 4 END; (* quatre *) j 2D9D 4C DEBUT_TROIS dec sp
- Aye» ¥ 2D9E 4C dec s
- | 29 BEGIN (* principal *) À 2D9F B83333 mov ba $3333
- | 30 ig | 2DA2 8946FC mov [bp+ $FC], ax
- | 31 END. (* principal *) ; 2DAS B90A00 mov cx, $000A
- | Fig. 5.155 Le programme appel_chaine. \ A ped coll onal ere
- 1 \ 2DAE E90000 jmp FIN_TROIS
- À B1 8BES FIN_TROIS 5
- Voici le code de ce programme: | = Pe ce pr a bp
- | 1 2DB4 C3 ret
- 2D4D E849DD call TU_PARAGRAPHS | 2DB5 55 ATRE h
- | 2D50 0600 hex 0600 ; options D 2DB6 8BEC pa Lotus mi sp
- | 2D52 bas pin pe pe ; > 2DB8 55 push bp
- 2D54 ex LOS i 1
- peepee “he sa DF02 : code ‘ 2DB9 E90000 jmp DEBUT_QUATRE
- 2 2D58 2700 hex 700 ; globales Y 2DBC 4C DEBUT_QUATRE
- | 2D5A 0004 hex 0004 ; min piles 4 2DBD 4C -Q de $
- | 2D5C, 00A0 hex 00A0 ; max piles 2DBE B84444 mov ax, $4444
- | 2D5E 1000 hex 1000 ; fichiers À 2DC1 8946FC mov [bp+ $FC], ax
- | 2D60 0000 hex 0000 ; input } 2DC4 B90800 mov cx, $0008
- | 2D62 0000 « hex 0000 ; output 2DC7 E8B8E1 call TU_STACK_CHEXK
- | one ais ate a \ 22 E8C9FF call TROIS
- | , ‘4 j
- | Dé D te TU TAILLE. cove | E90000 jmp FIN_QUATRE
- | 2D69 7C00 hex 7 ; taille | 2DD0 8BES FIN_QUATRE
- | 2D6B 6D2D adr SAUT_PRINCIPAL ( 2DD2 sD QU yy
- | 2
- I 2D6D E90000 SAUT_PRINCIPAL jmp PRINCIPAL 4 Dom Ge ao
- i) | 2DD4 B90800 PRINCIPAL mov cx, $0008
- I 2D70 55 DEUX keg DR 4 2DD7 E8A8E1 call TU_STAK_CHEK
- ik 2D71 8BEC Eh de sp \ 2DDA E8D8FF call QUATRE
- ! 2D73 55 pri Pp 4 2DDD E90000 jmp FIN
- il 2D74 E90000 jmp DEBUT _DEUX '
- ll 1 ( 2DE0 33C0 FIN xor ax lex
- | | 2DE2 E85BDE call TU_HALT
- 2DE5 0000 hex 0000
- { Fig. 5.156 Le code du programme appel_chaine.
- AU COEUR DE TURBO PASCAL 354 AU COEUR DE TURBO PASCAL l AU COEUR DE TURBO PASCAL 355 AU COEUR DE TURBO PASCAL
- ==================== PAGE 27 ====================
- pl 5 LE CODE COMPILE 5
- 5.7 les appels de procédures 57 LE CODE COMPILE 5
- 7 les appels de procédures a
- Wn
- Ce programme ne fait que généraliser ce que nous avions vu pour l’appel d’une procédure avec des Notez que:
- variables locales. otez que:
- — la figure est incomplète car nous n’avons pas représenté les zones de la procédure
- D po dde ahs. entier_hexadécimal et affiche_octet_hexadécimale, qui ant situées
- j 1 à : 5 À au-dessus des zones de deux
- — avant l'appel, TURBO vérifie que la pile 8088 dispose d’assez de place, en tenant compte de la : — les adresses de retour dans le programme principal ou dans quatre ou trois ne correspondent
- | place occupée par les variables locales ‘ s à :
- — après l’appel, TURBO protège les locales en déplaçant au-delà d’elles le sommet de la pile | pas à celle du désassemblage, car nous avons inséré les procédures d'affichage de la pile 8088
- 8088. Ceci a lieu même dans deux, car deux peut appeler des routines de la librairie (qui
- appelleront éventuellement des routines de MS-DOS ou du BIOS), et risqueraient par
- conséquent d’écraser les locales de deux.
- | {5.7.5 APPELS EMBOITES
- ! Si nous incorporons dans ce programme la procédure d'affichage du contenu de la mémoire, et que
- nous remplaçons le WRITELN de la procédure deux par: | pre de pu PASCAL sont emboîtées les unes dans les autres, la procédure la plus
- affiche_memoire(SSEG, ofs(l_locale_22), $FFFF); profondément nichée peut utiliser les variables locales de toutes les procédures qui l’englobent.
- | À ‘ Voici un exemple:
- alors nous pourrons examiner le contenu de la pile 8088: P
- Notez en particulier que: . |
- | 1 0 (*001 visib *)
- 1 * 22 *
- $9000:SFFEO ger $22 $22 822 SUE I j } Corner
- $9000:$FFE8 SEA $FF $F Bl +. QA 0 ] PR Pa
- $9000, SEFFO $ $FF $ $FF $D0 $30 par nee are | dr er
- $9000:$FF F2 FA 1 LE ;
- i $9000: $FFFO $44 $44 : DD é PÉEGIN a
- $9000:$FFF8 $FA $FF $FE $FF $15 $32 SUM a any 2 7 END; (* deux *)
- $9000: $FFF8 $00 $00 : aR 8 '
- | i " PROCEDURE rois;
- | Fig. 5.157 Le contenu de la pile 8088 | DEL in ae atoning
- a) l 13 PROCEDURE cinq;
- iM ‘ i BEGIN (* cing *)
- i i :(* cing *
- a) Nous apercevons: à 14 END; (* cinq *)
- 17 *
- _ de SS:$FFFE à SS:$FFFF l'adresse de retour à MS-DOS (via l'instruction INT $20 placée par 18 ENGI rt
- nee “ri le of 4 19 ;
- | — de SS:$FFF6 à SS:$FFFD la zone utilisée par quatre \ 20 fue
- | — de SS:$FFEE à SS:$FFFS la zone utilisée par trois 1 21 ah hese
- iW — de SS:$FFE4 à SS:$FFED la zone utilisée par deux iq 22 END; (* six *)
- | ‘à 23
- | À 24 BEGIN (* trois *)
- | i +(* ic *
- | Chaque procédure utilise bien une zone comportant: : 26 sce tre he
- if à ‘abl \ 11 27 PROCEDURE sepr;
- dernière variable locale ne 4 BEGIN (* sept *)
- Il deuxième variable locale 1 30 ro al
- i} première variable locale (À 31 BEGIN (* principal *)
- D. nn || 32 END. (* principal *)
- sauvegarde du BP actuel ;
- sauvegarde du BP de l'appelant à Fig. 5.158 Le programme visibilite.
- adresse de retour i
- AU PORE aa mre FAREAL +54 AU COEUR DE TURBO PASCAB AG AU COEUR DE TURBO PASCAL 357 AU COEUR DE TURBO PASCAL
- ==================== PAGE 28 ====================
- | 5 LE CODE COMPILE 5 LE CODE COMPILE 5
- | 5.7 les appels de procédures 5.7 les appels de procédures 57
- Il ne faut donc pas confondre: PROCEDURE quatre;
- | À \ VAR | locale_4: INTEGER;
- — la chaîne des appels (qui est un phénomène lié à l’exécution) BEGIN (* quatre *)
- / — l’emboitement (qui est lié à la structure statique du programme) sn
- | — la possibilité d’appeler une procédure (qui est lié à l’emboîtement ET à la position, à cause de
- | la compilation en une passe)
- | locale_4:= $4444;
- 1 locale_3:= $3333;
- [locale~2:= $2222:
- globale:= $1111;
- Dans notre exemple: END; (* quatre *)
- | — la chaîne d’appel est principal -> sept -> trois -> quatre -> cing | 22: BEGIN (* trois *)
- — six et deux ne figurent pas dans cette chaine 3 quatre;
- | AI 24 END; (* trois *)
- il — cing est emboitée dans quatre, dans trois et dans principal | 25
- C PAU | 26 BEGIN (* deux *)
- | — sept figure dans la chaîne d’appel mais cing ne peut accéder à ses données q 27 trois;
- | } ; ; À 28 END; (* deux *)
- | — sept peut appeler deux, mais deux ne peut appeler sept car le compilateur n’a pas encore 4 29
- | rencontré la déclaration de sept lorsqu'il compile deux (nous pourrions bien sûr utiliser une | 30 BEGIN (* principal *)
- déclaration FORWARD qui permet de traiter le cas des procédures qui s'appellent l’une 31 deux:
- l’autre) À 32 END. (* principal *)
- Fig. 5.159 Le programme appel_emboite.
- Les données auxquelles a accès une procédure appartiennent nécessairement à des procédures M
- figurant dans la chaîne d’appel (quatre, trois et principal figurent bien dans la chaîne d’appel de
- cing). L'inverse n’est pas vrai: une procédure n’a pas accès aux données des procédures figurant M Et voici le code généré:
- il dans la chaîne d’appel qui ne l’englobent pas (cing ne peut pas accéder aux données de sept). }
- 2D4D E849DD call TU_PARAGRAPHS
- | 2D50 0600 h à :
- A chaque appel de procédure correspond une zone locale sur la pile 8088. Pour accéder à des 2D52 7B06 Les ee : a’ bit
- données englobantes il aurait été possible de remonter la suite des zones locales, en paramétrant M 2D54 3F10 hex 3F10 ; ds
- soigneusement ces remontées. j 2D56 E002 hex E002 ; code
- À 2D58 2700 he 27 ;
- TURBO a préféré utiliser une autre technique qui place dans chaque zone locale une table 2D5A 0004 ya uns 4 Sie ated
- contenant l’adresse des zones englobantes. 4 2D5C 00A0 hex 00A0 : max piles
- : 2DSE 1000 hex 1000 ; fichiers
- k aH Fe hex 0000 ; input
- 1 h i
- Voici un programme avec des procédures emboitées: Y x ee nn
- it q 2D64 8BEC mov bp, sp
- | À 1 2D66 E814DF call TU_TAILLE_CODE
- | 0 (* 001 appemb *) | 2D69 8700 hex 8700 ; taille
- | : (* 29 avr 87 *) f 2D6B 6D2D adr SAUT_PRINCI PAL
- | 3 (*$r+*) a 2D6D E96F00 SAUT_PRINCIPAL j PRI P
- | 4 PROGRAM appel _emboite; 4 ‘i am Bae,
- i) 5 VAR globale: INTEGER; 2D70 55 DEUX push bp
- | 6 4 2D71 8BEC mov bp, sp
- 7 PROCEDURE deux; a 2D73 53 push bp
- | : VAR | _locale_2: INTEGER; à 2D74 E95600 jmp DEBUT_DEUX
- | 10 PROCEDURE trois; | 2D77 55 TROIS push bp
- 11 VAR !_locale_3: INTEGER; 4 ‘ 2D78 8BC4 mov ax, Sp
- 12 | 2D7A FF76FE push [bp+ $FE]
- | 2D7D 8BE8 mov bp, ax
- | ' 2D7F 55 push p
- | ‘4 2D80 E93800 jmp DEBUT_TROIS
- . AU COEUR DE TURBO PASCAL 358 AU COEUR DE TURBO PASCAL 1 AU COEUR DE TURBO PASCAL 359 AU COEUR DE TURBO PASCAL
- ==================== PAGE 29 ====================
- 5 LE CODE COMPILE 5s 5 LE CODE COMPILE 5
- 5.7 les appels de procédures SF ‘ 5.7 les appels de procédures 5.7
- 2D83 55 ATRE ush b | 2DDF B90800 PRINCIPAL mov cx, $0008
- 2D84 8BC4 7 Lier re + Sp À 2DE2 E89DE1 call TU_STACK_CHECK
- 2D86 FF76FE push [bp+ $FE] \ 2DE5 E888FF call ‘DEUX
- 2D89 FF76FC Ms ; push [bp+ $FC] i 2DE8 E90000 jmp FIN
- bp, 4
- att ss pea he aii | 2DEB 33C0 FIN xor ax, ax
- 2D8F £90000 jmp DEBUT_QUATRE 1 2DED E850DE call TU_HALT
- | 2D92 4C DEBUT_QUATRE ui sp | Fig. 5.160 Le code du programme appel_emboite.
- | 2D93 4C dec sp i
- [ 2D94 B84444 mov ax, $4444 4 1 j
- Î 2D97 8946F8 mov [bp+ $F8], ax À Voici comment se déroule l’appel de quatre:
- | 2D9A B83333 mov ax, $3333 — en $2DC3, trois appelle quatre
- | 2D9D 8B5EFC mov bx, [bp+ $FC] - en $2D83, quatre prépare le changement de contexte:
- ath nan ib E | en $2D83 la valeur de BP utilisée par trois est sauvée sur la pile
- PERTE ne On SEW a » — en $2D84 SP est temporairement sauvé dans AX
- 2DA4 B82222 mov ax, $2222 ; — en $2D86 et $2D89 la table des accès de trois est recopiée dans la zone de quatre
- 2DA7 8BSEFE ay bx, [bp+ $FE] À — en $2D8C BP pointe vers le début de la table des accès
- 2DAA 36 seg $s À — en tr à em ns d de BP est ajoutée à la table, au cas où une procédure cing aurait à
- | recopier la table de quatre
- pele bi ent Lt AMbig À — en $2D8F le contournement des constantes typées éventuelles
- 2DAE B81111 mov ax, $1111 4 — en $2D92 et $2D93 l'allocation des 2 octets nécessaires à la variable locale de quatre
- rs ect bre (90263210 1 me nur widow me la table des accès aux procédures qui l’englobent. Au début de
- . i, chaque procédure la table de la procédure immédiatement englobante est recopiée, et
- 2084 90000 Jmp FAALQUATRE | complétée par le BP de la procédure, pour préparer la copie éventuelle par une su
- 2DB7 8BES FIN_QUATRE mov sp, bp emboitée.
- | 2DB9 5D pop bp 3 s 1
- 2DBA C3 ret chématiquement nous avons donc:
- | 2DBB 4C DEBUT_TROIS dec sp q
- 2DBC 4C dec sp }
- 2DBD B90C00 mov cx, $000C |
- 2DC0 E8BFE1 call TU_STACK_CHECK |
- 2DC3 E8BDFF call QUATRE (À
- 2DC6 E90000 jmp FIN_TROIS i
- 2DC9 8BES FIN_TROIS mov sp, bp
- 2DCB 5D pop bp ‘4
- 20 C3 ret i
- | 2DCD 4C DEBUT_DEUX dec sp 4
- | 2DCE 4C dec sp i
- 2DCF B90A00 mov cx, $000A a
- 2DD2 E8ADE1 call TU_STACK_CHECK a
- I! 2DD5 E89FFF call TROIS 1
- | 2DD8 E90000 jmp FIN_DEUX À
- || 2DDB 8BES FIN_DEUX mov sp, bp |
- if 2DDD 5D pop bp ;
- | 2DDE C3 ret
- ==================== PAGE 30 ====================
- 5 LE CODE COMPILE 5
- a3 les appels de procédures ST
- $00000
- SYSTEME
- $067B0
- PSP et code de PROC.COM
- PC= $2D94
- $068C1
- $6FFEO $4444 | locale_4 SP= $FFEO
- $6FFE2 $FFE8 BP de quatre
- $6FFE4 $FFF2 BP de trois
- $6FFE6 $FFFA BP de deux
- $6FFE8 $FF2F BP de trois BP= $FFE8
- $6FFEA $30E9 retour dans trois
- $6FFEC $3333 | locale_3
- $6FFEE $FFF2 BP de trois
- $6FFFO $FFFA BP de deux
- $6FFF2 $FFFA BP de deux
- $6FFF4 $30FB retour dans deux
- $6FFF6 $2222 | locale_2
- $6FFF8 $FFFA BP de deux
- $6FFFA $FFFE BP de principal
- $6FFFC $3199 retour dans principal
- $6FFFE $0000 retour 4 MS-DOS
- $70000 sommet de la mémoire vive 448K
- SYSTEME
- $FFFFF
- Fig. 5.161 La mémoire en $2D94
- Ces tables d’accés sont alors utilisées pour accéder aux données des procédures englobantes.
- Dans le cas de quatre, la zone locale comporte donc $0C octets (l’adresse de retour, les 4
- valeurs de BP et la variable locale). Par rapport à la valeur de BP, la première variable locale
- est donc décalée de $08 octets (par conséquent elle sera accédée par [BP+ $FFF8]
- — en $2D94 et $2D97 nous affectons $4444 à la variable locale de quatre. Cette affectation se fait
- donc par rapport à BP:
- mov [BP+ $F8], ax
- — de $2D9A à $2DA1 nous traitons la variable englobante /_locale_3:
- — le BP de trois est placé dans BX (la valeur de ce BP est située dans la table des accès de
- quatre, 4 octets plus haut, donc à [BP+ $FC])
- — | locale _3 est située dans la zone de trois, à 6 octets du BP de trois (donc accessible par
- (BX+ $FA])
- AU COEUR DE TURBO PASCAL 362 AU COEUR DE TURBO PASCAL
- 5 LE CODE COMPILE 5
- S77 les appels de procédures 67
- ~— même chose pour / locale 2:
- — le BP de deux est placé dans BX (la valeur de ce BP est situé dans la table des accès de
- quatre, 2 octets plus haut, donc à [BP+ $FE])
- — |_locale_2 est située dans la zone de deux, à 4 octets du BP de deux (donc accédée par
- [BX+ $FC])
- — en $2DAE et $2DB1 nous affectons une valeur à une variable globale, en utilisant DS
- comme d’habitude
- Notez que:
- — avant chaque appel, le code teste si la pile a assez de place pour la zone locale de la
- procédure appelée.
- Ainsi en $2DBD, trois vérifie que la pile 8088 a au moins $0C octets pour la zone locale de
- quatre.
- Pour le retour, le code reste le méme:
- — SP pointe le BP de la procédure qui a appelé
- — POP BP permet de restaurer BP vers la pile de l’appelant
- — RET récupère le PC de l’appel
- Si nous ajoutons la procédure d’affichage mémoire, et plagons dans quatre l'appel:
- affiche_memoire(SSEG, OFS(l_locale_4), $FFFF);
- nous obtiendrons:
- $6000:$FFEO $44 $44 $E8 $FF $F2 $FF $FA $FF :DD ED UE
- $6000:S$FFE8 $F2 $FF $E9 $30 .0
- $6000 : $FFE8 $33 $33 $F2 $FF : 39).
- $6000:$FFFO $FA $FF $FA $FF $FB $30 big atta 0
- $6000: $FFFO $22 522 : Ji
- $6000:$FFF8 $FA $FF $FE $FF $99 $31 NSE CH 1
- $6000: $FFF8 $00 $00 :
- Fig. 5.162 Les zones locales sur la pile 8088
- AU COEUR DE TURBO PASCAL 363
- AU COEUR DE TURBO PASCAL
- ==================== PAGE 31 ====================
- 5 LE CODE COMPILE 5
- 5.7 les appels de procédures 5.7
- RESUME
- Dans chaque pile locale nous avons:
- la derniére variable locale <--- SP
- la deuxième variable locale
- ‘| la première variable locale
- la valeur de BP actuelle
- la valeur de BP de la procédure englobante
- la valeur de BP de la premiére procédure
- la valeur de BP de l’appelant <--- BP
- | l’adresse de retour
- Lorsque la procédure est la dernière de la chaîne de l'appel, SP pointe la
- dernière variable locale, et BP pointe la valeur de BP de l’appelant.
- 1 { 5.7.6 LES PARAMETRES VALEUR ET VARIABLE
- Voici à présent une procédure comportant des paramètres valeur et variable:
- 0 (*001 varvall *)
- 1}! (22 jan 87 *)
- 2
- 3" (8r+*)
- 4 PROGRAM desassemble parametres;
- 5 VAR globalel, globale2, globale3, globale4: INTEGER;
- 6
- 7 PROCEDURE deux(p1, p2: INTEGER; VAR pv3, pv4: INTEGER);
- 8 BEGIN (* deux *)
- 9 pl:= $1111; p2:= $2222;
- | 10 pv3:= $3333; pv4:= $4444;
- | 11 END; (* deux *)
- 12
- Hy 13 BEGIN
- 14 deux($AAAA, $BBBB, globale2, globale4);
- 15 END.
- | Fig. 5.163 Le programme desassemble_parametres.
- AU COEUR DE TURBO PASCAL 364
- AU COEUR DE TURBO PASCAL
- 5 LE CODE COMPILE 5
- 5.7 les appels de procédures Sa
- Voici le code généré:
- 2D4D E849DD call TU_PARAGRAPHS
- 2D50 0600 hex 0600 ; options
- 2D52 780B hex 780B ; cs
- 2D54 3C15 hex 3C15.::11d8
- 2D56 DDO02 hex DDO2 ; code
- 2D58 2700 hex 2700 ; globales
- 2D5A 0004 hex 0004 ; min piles
- 2D5C 00A0 hex OOAO ; max piles
- 2D5E 1000 hex 1000 ; fichiers
- 2D60 0000 hex 0000 ; input
- 2D62 0000 hex 0000 ; output
- 2D64 8BEC mov bp, sp
- 2D66 E814DF call TU_TAILLE_CODE
- 2D69 5800 hex 5800 ; taille
- 2D6B 6D2D adr SAUT_PRINCI PAL
- 2D6D E90000 SAUT_PRINCIPAL jmp PRINCI PAL
- 2D70 55 DEUX push bp
- 2D71 8BEC mov bp, sp
- 2D73 55 push bp
- 2D74 E90000 jmp DEBUT_DEUX
- 2D77 B81111 DEBUT _DEUX mov Ad 93111
- 2D7A 89460E mov [bp+ $0E], ax
- 2D7D B82222 mov ax; $2222
- 2D80 89460C mov [bp+ $0C], ax
- 2D83 C47E08 les di, [bp+ $08]
- 2D86 B83333 mov ax, $3333
- 2D89 26 seg es
- 2D8A 8905 mov (di Jt ax
- 2D8C C47E04 les di, [bp+ $04]
- 2D8F B84444 mov ax, $4444
- 2D92 26 seg es
- 2D93 8905 mov Las), ax
- 2D95 E90000 jmp FIN_DEUX
- 2D98 8BE5 FIN_DEUX mov sp, bp
- 2D9A SD pop bp
- 2D9B C20C00 ret 000C ; intra
- AU COEUR DE TURBO PASCAL 365 AU COEUR DE TURBO PASCAL
- ==================== PAGE 32 ====================
- |
- 5 LE CODE COMPILE
- 5.7 les appels de procédures
- 2D9E B91200 PRINCIPAL mov cx, $0012
- 2DA1 E8DEE1 call TU_STACK_CHECK
- 2DA4 B8AAAA mov ax, $AAAA
- 2DA7 50 4 push ax
- 2DA8 B8BBBB mov ax, $BBBB
- 2DAB 50 push ax
- 2DAC BF6402 mov di, $0264
- 2DAF 1E push ds
- 2DB0 57 push di
- 2DB1 BF6802 mov di, $0268
- 2DB4 1E push ds
- 2DBS 57 push di
- 2DB6 E8B7FF call DEUX
- 2DB9 E90000 jmp FIN
- ‘2DBC 33C0 FIN xor AX, AX
- 2DBE E87FDE call TU_HALT
- 2DC1 0000 hex 0000
- Fig. 5.164 Le code du programme desassemble_parametres.
- Notez que:
- — au moment de l’appel:
- — le code vérifie si la pile dispose bien de $12 octets (6 pour l’environnement, 2*2 pour les
- paramètres valeur, 2*4 pour les paramètres variable)
- — pousse la valeur des paramètres valeur sur la pile
- — pousse l'adresse des paramètres variable sur la pile
- — la procédure appelée:
- — met en place son environnement comme d’habitude (ici sauvegarde du BP de l’appelant et
- du BP actuel). La situation est alors la suivante:
- AU COEUR DE TURBO PASCAL 366 AU COEUR DE TURBO PASCAL
- #
- i
- LE CODE COMPILE 5
- les appels de procédures ST
- $00000
- SYSTEME
- $067B0
- PSP et code de PROC.COM 5
- PC= $2D77
- $068C1
- $6FFEC $FFEE BP de deux SP= $FFEC
- $6FFEE $FFFE BP de principal BP= $FFEE
- $6FFFO $2DB9 retour dans principal
- $6FFF2 $0268 décalage de globale4
- $6FFF4 $19F3 segment de globale4
- $6FFF6 $0266 décalage de globale3
- $6FFF8 $19F3 segment de globale3
- $6FFFA $BBBB valeur de globale2
- $6FFFC $AAAA valeur de globalel
- $6FFFE $0000 retour à MS-DOS
- $70000 sommet de la mémoire vive 448K
- SYSTEME
- $FFFFF
- Fig. 5.165 La mémoire en $2D77
- — Les paramètres se trouvent donc sous l’environnement local. Le premier octet des
- paramètres se trouve après le BP du programme appelant, et après l’adresse de retour, donc
- à BP+ 4.
- Par conséquent, pour accéder au premier paramètre valeur, le code utilisera:
- MOV AX, [BP+ $0E]
- En effet ce paramètre se trouve après les 2 paramètres variable (8 octets) et après le second
- paramètre valeur (2 octets). En tout 4+ 8+ 2.
- — pour accéder au paramètre valeur, il suffit de charger son adresse dans ES et DI. Ainsi pour
- le premier paramètre variable (situé avant le second paramètre variable), nous utilisons:
- LES DI, [BP+ $08]
- AU COEUR DE TURBO PASCAL
- 367 AU COEUR DE TURBO PASCAL
- ==================== PAGE 33 ====================
- 5 LE CODE COMPILE
- kW à les appels de procédures
- | Voici pour terminer un appel en utilisant comme paramètres des variables intermédiaires:
- 0 (*001 param2 *)
- 1 (* 22 jan 87 *)
- 2
- 2 Tnt")
- 4 PROGRAM desassemble_parametre2;
- 5
- 6 PROCEDURE deux;
- Û VAR localel, locale2: INTEGER;
- ' à PROCEDURE trois;
- 1
- 11 PROCEDURE quatre(p: INTEGER; VAR pv: INTEGER);
- 12 BEGIN (* quatre *)
- 13 p:= $1111;
- 14 pv:= $2222;
- 15 END; (* quatre *)
- | 16
- ; 17 BEGIN (* trois *)
- | 18 quatre(localel, locale2);
- 19 END; (* trois *)
- 20
- 21 BEGIN (* deux *)
- 22 END; (* deux *)
- 23
- 24 BEGIN (* principal *)
- 25 END. (* END *)
- | Fig. 5.166 Le programme desassemble_parametre2.
- | Voici le code généré:
- 2D4D. E849DD call TU_PARAGRAPHS
- 2D50 0600 hex 0600 ; options
- | 2D52 780B hex 780B : ¢s
- | 2D54 3C15 hex 3GIS Ad's
- | 2D56 DE02 hex DEO02 ; code
- | 2D58 2700 hex 2700 ; globales
- | 2D5A 0004 hex 0004 ; min piles
- | 2D5C 00A0 hex QOAO ; max piles
- | 2D5E 1000 hex 1000 ; fichiers
- | 2D60 0000 hex 0000 ; input
- | 2D62 0000 hex 0000 ; output
- | 2D64 8BEC mov bp, sp
- 2D66 E814DF call TU_TAILLE_CODE
- | 2D69 7400 hex 7400 ; taille
- I 2D6B 6D2D adr SAUT_PRINCI PAL
- |
- Il
- i
- if
- AU COEUR DE TURBO PASCAL 368 AU COEUR DE TURBO PASCAL A
- 5 LE CODE COMPILE §
- 5.7 les appels de procédures sh
- 2D6D E90000 SAUT_PRINCIPAL jmp PRINCI PAL
- 2D70 55 DEUX push bp
- 2D71 8BEC mov bp, sp
- 2D73 52 push bp
- 2D74 E95400 jmp DEBUT _DEUX
- 2D77, 54 TROIS push bp
- 2D78 8BC4 mov ax, sp
- 2D7A FF76FE push [bp+ $FE]
- 2D7D 8BE8 mov bp, ax
- 2D7E 59 push bp
- 2D80 E92700 jmp DEBUT_TROIS
- 2D83 55 QUATRE push bp
- 2D84 8BC4 mov ax, wl
- 2D86 FF76FE push [bp+ $FE]
- 2D89 FF76FC push [bp+ $FC]
- 2D8C 8BE8 mov bp, ax
- 2D8E 55 push bp
- 2D8F E90000 jmp DEBUT_QUATRE
- 2D92 B81111 DEBUT_QUATRE mov ax, $1111
- 2D95 894608 mov [bp+ $08], ax
- 2D98 C47E04 les di, [bp+ $04]
- 2D9B B82222 mov ax, $2222
- 2D9E 26 seg es
- 2D9F 8905 mov [di], ax
- 2DA1 E90000 jmp FIN_QUATRE
- 2DA4 8BES FIN_QUATRE mov sp, bp
- 2DA6 5D pop bp
- 2DA7 C20600 ret 0006 ; intra
- 2DAA B91000 DEBUT_TROIS mov cx, $0010
- 2DAD E8D2E1 call TU_STACK_CHECK
- 2DB0 8B5EFE mov bx, [bp+ $FE]
- 2DB3 36 seg ss
- 2DB4 8B47FC mov ax, [bx+ $FC]
- 2DB7 50 push ax
- 2DB8 8BSEFE mov bx, [bp+ $FE]
- 2DBB 36 seg ss
- 2DBC 8D7FFA lea di, [bx+ $FA]
- 2DBF 16 push ss
- 2DC0 57 push di
- 2DC1 E8BFFF call LC_2D83
- 2DC4 E90000 jmp FIN_TROIS
- 2DC7 8BES FIN_TROIS mov sp, bp
- 2DC9 5D pop bp
- 2DCA C3 ret
- 2DCB 83EC04 DEBUT _DEUX sub sp, $04
- 2DCE E90000 jmp FIN_DEUX
- 2DD1 8BES FIN_DEUX mov sp, bp
- 2DD3 5D pop bp
- 2DD4 C3 ret
- AU COEUR DE TURBO PASCAL 369 AU COEUR DE TURBO PASCAL
- ==================== PAGE 34 ====================
- 5 LE CODE COMPILE 5
- | 5.7
- | les appels de procédures 5.7
- 2DDS5 E90000 PRINCIPAL jmp FIN
- 2DD8 33C0 FIN xor FL PU LÀ
- 2DDA E863DE ( call TU_HALT
- 2DDD 0000 } hex 0000
- Fig. 5.167 Des variables intermédiaires comme paramètres.
- Notez que:
- — pour simplifier le code nous n’avons pas effectué tous les appels
- — l'accès aux paramètres est identique. Cela était prévisible du fait qu’une procédure doit pouvoir
- accéder à plusieurs piles locales (d’où la table des BP englobants), mais n’a qu’un seul jeu de
- paramètres, tous situés avant l’environnement
- — voici par contre comment trois place les paramètres sur la pile avant d’effectuer l’appel. Voici
- la situation juste avant de pousser ces paramètres (en $2DB0):
- —
- BP de trois <-- SP actuel
- BP de deux
- BP de deux <-- BP actuel
- adresse de retour dans deux
- ‘ locale2
- localel
- BP de deux
- BP de principal (BP de deux)
- adresse de retour dans principal
- Pour récupérer la valeur d’un paramètre valeur, l’accès se fait comme d’habitude pour les
- variables intermédiaires:
- | — [BP+ $FE] nous fournit le BP de deux
- — cette valeur est stockée dans BX
- — locale2 se trouve alors à [BX+ $FC] (2 octets pour sauter la copie de BP de deux et 2 pour
- accéder au premier octet de localel) °
- | " Pour récupérer l’adresse de locale2:
- — [BP+ $FE] nous fournit le BP de deux
- — cette valeur est stockée dans BX
- — BX+ $FA contient alors le décalage de locale2. Ce décalage est alors placé dans DI par
- l'instruction
- LEA DI, [BX+$FA]
- — puis SS et DI sont poussés sur la pile
- AU COEUR DE TURBO PASCAL 370 AU COEUR DE TURBO PASCAL
- 5 LE CODE COMPILE 5
- 5.7 les appels de procédures 57
- RESUME
- Les paramètres sont poussés sur la pile par la procédure appelante. Celle ci
- pousse la valeur des paramètres valeur, et l’adresse segmentée des
- paramètres variable.
- La procédure accède à ces paramètres en utilisant BP. Le premier octet de
- ces paramètres est situé à une distance de BP+ 4.
- Pour les paramètres variable, l'adresse segmentée est chargée dans ES et
- DI qui permettent d'accéder à la variable passée comme paramètre.
- La pile comporte donc:
- la dernière variable locale <--- SP
- la deuxième variable locale
- la première variable locale
- la valeur de BP actuelle
- la valeur de BP de la procédure englobante
- la valeur de BP de la première procédure
- la valeur de BP de l’appelant <--- BP
- l’adresse de retour
- dernier paramètre
- premier paramètre
- {5.7.7 LES APPELS DE FONCTIONS
- Voici à présent un appel de fonction:
- AU COEUR DE TURBO PASCAL : 371 AU COEUR DE TURBO PASCAL
- ==================== PAGE 35 ====================
- 5 LE CODE COMPILE 5 LE CODE COMPILE 5
- 5.7 les appels de procédures 5.7 les appels de procédures 5.7
- B90800 PRINCIPAL mov cx, $0008
- O (* 001 sfct *) E8F3E1 call © TU_STACK_CHECK
- 1 (* 29 aou 87 *) 4C i dec sp
- 2 ‘ 4C dec sp
- 3 PROGRAM desassemble appel fonction; i E8DCFF call F_FONCTION
- 4 VAR entier: INTEGER; 2D94 A36202 mov [$0262], ax
- 5 2D97 E90000 jmp FIN
- 6 FUNCTION f entier: INTEGER; |
- 7 BEGIN ~— 2D9A 33C0 FIN xor ax, ax
- 8 f entier:= $77; 4 2D9C E8A1DE call . TU_HALT
- 4 END; (* f_entier *) | 2D9F 0000 hex 0000
- 1
- | 11 BEGIN (* principal *) À Fig. 5.169 Le code de desassemble fonction .
- | 12 entier:= f_entier; À
- | 13 END. 4
- Fig. 5.168 Le programme desassemble_fonction. 1 Notez que:
- — au moment de l’appel, en $2D89, le code vérifie que la pile pourra accomoder la fonction (6
- octets pour l’environnement traditionnel plus 2 octets pour le résultat entier de la fonction). La
- j Et voici le code généré: a pile est alors décrémentée de 2 octets pour laisser la place au résultat de la fonction.
- q — dans le corps de la fonction:
- 2D4D E849DD call TU_PARAGRAPHS 4 — l'affectation de la valeur à la fonction se fait en stockant directement cette valeur en
- 2D50 0600 hex 0600 ; options 4 [BP+ $04], où se trouve l’emplacement réservé pour le résultat de la fonction
- 2D52 780B hex 780B ; cs ( — avant de quitter la fonction, la valeur de celle-ci est chargée dans AX. L’expression utilisant
- 2D54 3C15 hex BC25 |; ds 3 ce résultat entier est donc assuré de trouver cette valeur dans AX.
- 2D56 DBO2 hex DBO2 ; code \
- 2D58 2700 hex 2700 ; globales
- 2D5A 0004 hex 0004 ; min piles \
- | 2D5C O00A0 hex 00A0 ; max piles a Lorsque le résultat de la fonction est un réel ou une chaîne, le mécanisme est similaire:
- | 2DSE 1000 hex 1000 ; fichiers
- | 2D60 0000 hex 0000 ; input |
- | 2D62 0000 hex 0000 ; output \| O (* 001 sfctst *)
- i] 4 1 (* 29 aou 87 *)
- 2D64 8BEC mov bp, sp à 2
- 2D66 E814DF call TU_TAILLE_CODE q 3 PROGRAM desassemble_appel_fonction_string;
- 2D69 3600 hex 3600 ; taille 1 4 TYPE string]1= STRING{11];
- | 2D6B 6D2D adr SAUT _PRINCI PAL i 5 VAR chaine: string11;
- 2D6D E90000 SAUT_PRINCIPAL jmp PRINCIPAL \ ; ee string!1;
- 2D70 55 F_ENTIER push bp 4 9 f chaine:= "ABC";
- 2D71 8BEC mov bp, sp \ 10 END; (* f_entier *)
- 2D73 50 push bp q 11
- 2D74 E90000 jmp DEBUT_F_ENTIER 1} 12 BEGIN (* principal *)
- 4 13 chaine:= f chaine;
- 2D77 B87700 DEBUT_F_ENTIER mov ax, $0077 i 14 END.
- 2D7A 894604 mov [bp+ $04], ax q
- 2D7D E90000 jmp FIN_F_ENTIER t Fig. 5.170 Le programme desassemble_appel_fonction_chaine.
- | 2D80 8B4604 FIN_F_ENTIER mov ax, [bp+ $04] À
- iy 2D83 8BES mov sp, bp \
- | 2D85 5D pop bp
- | 2D86 C20200 ret 0002 ; intra i
- i
- |
- Il ;
- i L
- i) AU COEUR DE TURBO PASCAL 372 AU COEUR DE TURBO PASCAL q AU COEUR DE TURBO PASCAL 373 AU COEUR DE TURBO PASCAL
- ==================== PAGE 36 ====================
- 5
- SA
- LE CODE COMPILE
- les appels de procédures
- Voici le code:
- 2D4D E849DD call TU_PARAGRAPHS
- 2D50 0600 hex 0600 ; options
- 2D52 780B hex 780B ; cs
- 2D54 3C15 hex 30171 (ds
- 2D56 DCO02 hex DCO2 ; code
- 2D58 2700 hex 2700 ; globales
- 2D5A 0004 hex 0004 ; min piles
- 2D5C 00A0 hex 00A0 ; max piles
- 2D5E 1000 hex 1000 ; fichiers
- 2D60 0000 hex 0000 ; input
- 2D62 0000 hex 0000 ; output
- 2D64 8BEC mov bp, sp
- 2D66 E814DF call TU_TAILLE_CODE
- 2D69 4B00 hex 4B00 ; taille
- 2D6B 6D2D adr SAUT_PRINCI PAL
- 2D6D E90000 SAUT_PRINCIPAL jmp PRINCI PAL
- 2D70 55 F_CHAINE push bp
- 2D71 8BEC mov bp, sp
- 2D73 55 push bp
- 2D74 E90000 jmp DEBUT_F_CHAINE
- 2D77 8D7E04 DEBUT_F_CHAINE lea di, [bp+ $04]
- 2D7A 16 push ss
- 2D7B 57 push di
- 2D7C E81CE4 call TU_POUSSE_K_ST
- 2D7F 03 hex 03
- 2D80 414243 asc *ABC’
- 2D83 B10B mov cl, $0B
- 2D85 E829E4 call TU_POP_STRING
- 2D88 E90000 jmp FIN_F_CHAINE
- 2D8B BA0000 F IN_F_CHAINE mov dx, $0000
- 2D8E B10B mov cl, $0B
- 2D90 8BE5 mov sp, bp
- 2D92 5D pop bp
- 2D93 E9C5E6 jmp TU_RESU_FCT_ST
- 2D96 BF6202. PRINCI PAL mov di, $0262
- 2D99 1E push ds
- 2D9A 57 push di
- 2D9B B91200 mov cx, $0012
- 2D9E E8EIEI call TU_STACK_CHECK
- 2DA1 83EC0C sub sp, $0C
- 2DA4 E8C9FF call F_CHAINE
- 2DA7 B10B mov cl, $0B
- 2DA9 E805E4 call TU_POP_STRING
- 2DAC E90000 jmp FIN
- 2DAF 33C0 FIN xor BX ax
- 2DB1 E88CDE call TU_HALT
- 2DB4 0000 hex 0000
- Fig. 5.171 Le code de desassemble_appel_fonction_chaine.
- AU COEUR DE TURBO PASCAL 374 ‘AU COEUR DE TURBO PASCAL
- i
- if LE CODE COMPILE 5
- 5.7 les appels de procédures ST
- Notez que:
- _ Ja fonction pousse la constante sur la pile, dépile cette valeur dans la zone réservée sur la pile à
- la chaîne. L'expression utilisant peut alors utiliser cette valeur qui reste sur la pile après l'appel
- de la fonction.
- RESUME
- Le résultat d’une fonction est placé sur la pile. Dans le cas d’une fonction
- À entière, la fonction place la valeur du résultat dans AX avant de retourner.
- i Dans le cas de réels ou de chaines, la valeur du résultat est laissé sur la pile.
- Pendant l’exécution de la fonction, la pile comporte donc:
- la dernière variable locale <--- SP
- la deuxième variable locale
- | la première variable locale
- la valeur de BP actuelle
- la valeur de BP de la procédure englobante
- 1 la valeur de BP de la première procédure
- la valeur de BP de l’appelant <--- BP
- l’adresse de retour
- dernier paramètre
- premier paramètre
- 1 résultat de la fonction
- AU COEUR DE TURBO PASCAL 375 AU COEUR DE TURBO PASCAL
- “A
- ==================== PAGE 37 ====================
- 5 LE CODE COMPILE 5
- 5.8 les constantes typées 5.8
- {5.8 LES CONSTANTES TYPEES |
- {5.8.1 DEFINITION DES CONSTANTES TYPEES
- TURBO PASCAL a inventé une nouvelle race de données, appelées "constantes typées".
- Ces objets:
- — sont définis après CONST
- — utilisent une syntaxe qui est une combinaison de la syntaxe des déclarations de variables et des
- définitions de types
- — sont modifiables comme n’importe quelle variable
- — Sont stockés au milieu du code du programme
- — sont accédés à l’aide du registre CS
- Voici quelques exemples de déclarations:
- CONST kt_entier: INTEGER= $88;
- kt_caractere: CHAR= ’A’;
- kt_string: STRING[S5]:= "ABC;
- kt_tableau: ARRAY(0..2] OF BYTE= ($11, $22, $33);
- kt_ensemble: SET OF CHARS [’a’..’z’, ’A’];
- Ce qui distingue donc une constante ordinaire d’une constante typée est la présence du type de la
- constante entre le nom de la constante et la valeur de cette constante. La syntaxe de la définition est
- donc:
- CONST nom_constante : type_constante = valeur_constante ;
- qui est une combinaison de la syntaxe de définition des constantes:
- CONST nom_constante = valeur_constante ;
- et de la syntaxe de déclaration de variables:
- VAR nom_variable : type_variable ;
- La valeur des constantes typées est placé au milieu du code du programme. Ceci entraîne que:
- — la valeur est unique. Si vous utilisez la constante en plusieurs endroits, la copie unique sera
- utilisée. Le code contient en effet l’adresse où se trouve la valeur (et non pas une copie de la
- valeur, comme pour les constantes usuelles)
- — les octets utilisés pour les constantes typées diminuent d’autant la place utilisable pour les
- instructions, et augmentent d'autant la place pour les variables globales ou locales
- — ces octets sont accessibles à partir du segment CS du 8088 (et non pas à partir de DS ou SS
- comme pour les ‘variables globales ou locales). Ceci est surtout intéressant lorsqu’un
- programme TURBO PASCAL est rendu résident et que nous y accédons par interruption: au
- moment de l'interruption, seul CS et le compteur programme sont connus.
- AU COEUR DE TURBO PASCAL 376 AU COEUR DE TURBO PASCAL
- 5 LE CODE COMPILE 5
- 5.8 les constantes typées 5.8
- a
- Finalement nous pouvons modifier la valeur d’une constante typée, en utilisant l’affectation ou la
- lecture:
- READLN(kt_entier);
- kt_tableau[3]:= 5;
- Elles se comportent donc de ce point de vue:
- — comme des variables initialisées par le compilateur (au lieu d’être initialisées par nos
- instructions). (
- — comme des variables statiques: les constantes typées d’une procédure existent en dehors de la
- procédure, et gardent leur valeur d’un appel à l’autre. Le fait que la valeur ne soit pas modifiée
- provient de ce qu'elle est stockée, en un seul exemplaire, et dans le code (et non pas créée puis
- détruite sur la pile des variables locales). Si une procédure récursive modifie cette valeur, c’est
- la dernière modification qui sera retenue (alors que pour les variables locales, les valeurs
- empilées seront dépilées dans l’ordre inverse, et la dernière détruite à la sortie du dernier appel).
- Concrètement, ces constantes typées sont utilisées:
- — pour disposer des constantes structurées uh 4
- — pour économiser de la place lorsque la constante est utilisée de nombreuses fois et prend
- beaucoup de place (chaînes de caractères) | |
- — pour éviter d’écrire des instructions d’initialisation de variables et pour éviter de perdre du
- temps à les.initialiser au moment de l’exécution
- — pour disposer de variables statiques
- — pour disposer de variables accessibles par CS
- Il aurait été plus heureux de séparer ces propriétés fort différentes:
- — en permettant l’initialisation de variables sous VAR (au lieu de CONST) \
- — en créant l’attribut STATIQUE pour séparer l'existence d’une variable locale de l'exécution
- d’une procédure ?
- — en créant l’attribut CODE pour imposer le stockage de la variable dans le code du programme
- Quoiqu'il en soit, examinons comment sont traitées ces données.
- { 5.8.2 LES CONSTANTES TYPEES SIMPLES
- Voici un programme utilisant des constantes typées simples:
- (* 001 consttl *)
- (* 11 avr 87 *)
- (*$r+*)
- PROGRAM desassemble_constantes_typees;
- CONST kt_entier: INTEGER= $1711;
- kt_booleen: BOOLEAN= TRUE;
- kt_caractere: CHAR= ’A’;
- kt_reel: REAL= 1.75;
- 00 -J D Un PB W D = ©
- AU COEUR DE TURBO PASCAL 377
- AU COEUR DE TURBO PASCAL
- ==================== PAGE 38 ====================
- > LE CODE COMPILE
- 5.8 les constantes typées
- 9 VAR entier: INTEGER;
- 10 reel: REAL;
- 11 booleen: BOOLEAN;
- 12 caractere: CHAR;
- 13 BEGIN
- 14 kt_entier:= entier,
- LS kt_booleen:= booleen;
- 16 caractere:= kt_caractere;
- 17 kt_reel:= reel;
- 18 END.
- Fig. 5.172 Le programme desassemble_constantes_typées
- Voici le code correspondant:
- 2D4D E849DD call TU_PARAGRAPHS
- 2D50 0600 hex 0600 ; options
- 2D52 780B hex 713806. ¢ cs
- 2D54 3C15 hex Berets as
- 2D56 DCO02 hex DCO2 ; code
- 2D58 2700 hex 2700 ; globales
- 2DSA 0004 hex 0004 ; min piles
- 2D5C 00A0 hex 00A0 ; max piles
- 2DSE 1000 hex 1000 ; fichiers
- 2D60 0000 hex 0000 ; input
- 2D62 0000 hex 0000 ; output
- 2D64 8BEC moy bp, sp
- 2D66 E814DF call TU_TAILLE_CODE
- 2D69 5300 hex 5300 ; taille
- 2D6B 6D2D adr SAUT_PRINCI PAL
- 2D6D E90A00 SAUT_PRINCIPAL jmp PRINCIPAL
- 2D70 1111 adr aN a
- 2D72 01 hex 01
- 2D73 41 asc *A’
- 2D74 810000000060 hex 810000000060
- 2D7A A16202 PRINCI PAL mov ax, [$0262]
- 2D7D: 2E seg cs
- 2D7E A3702D mov [$2D70], ax
- 2D81 A06A02 mov al, [$026A]
- 2D84 32E4 xor ah, ah
- 2D86 B90000 mov cx, $0000
- 2D89 BA0100 mov dx, $0001
- 2D8C E8E5E1 call TU_RANGE_CHECK
- 2D8F 2E seg cs
- 2D90 A2722D mov [$2D72], al
- AU COEUR DE TURBO PASCAL 378 AU COEUR DE TURBO PASCAL
- LE CODE COMPILE 5
- 5
- 5.8 les constantes typées 5.8
- 2E seg cs
- 4 A0732D mov al, [$2D73]
- 2D97 32E4 xor ah, ah
- 2D99 B90000 mov cx, $0000
- 2D9C BAFF00 mov dx, $00FF
- 2D9F E8D2E1 call TU_RANGE_CHECK
- 2DA2 A26B02 mov [$026B], al
- 2DA5 BF742D mov di, $2D74
- 2DA8 OE push cs
- 2DA9 57 push di
- 2DAA BF6402 mov di, $0264
- 2DAD 1E push ds
- 2DAE E885EB call TU_POUSSE_REEL
- 2DB1 E8A2EB call TU_POP_REEL_DI
- 2DB4 E90000 jmp FIN
- 2DB7 33C0 FIN xor ax ax
- 2DB9 E884DE call TU_HALT
- 2DBC 0000 hex 0000
- Fig. 5.173 Traitement des constantes typées simples
- Notez que:
- — le code contient bien les valeurs des constantes telles que nous les avons initialisées
- — le programme saute par dessus la zone de ces constantes, pour débuter à la première instruction
- 8088. Cette technique est aussi appliquée dans le cas des procédures
- — l’accés aux constantes typées se fait de la façon suivante:
- — pour toutes les instructions qui chargeaient des valeurs simples dans AX au moyen de
- MOV, les traitements sont simplement préfixés par SEG CS
- — pour toutes les instructions qui poussaient le segment de la donnée sur la pile, c’est
- simplement CS qui est poussé (au lieu de DS)
- {5.8.3 LES CONSTANTES TYPEES COMPLEXES
- Voici un exemple de constante typée plus complexe:
- (* 001 constt2 *)
- (* 11 avr 87 *)
- (*$r+*)
- PROGRAM desassbmle_constante_typee2;
- TYPE t_record= RECORD
- nom: STRING/$3];
- age: INTEGER;
- END;
- t_tableau_record= ARRAY/$10..$11] OF t_record;
- 10 CONST kt_tableau_record: t_tableau_record=
- \O 00 JA Un PB & D = ©
- (
- 12 (nom: ’ABC’ ; age: $1F),
- i (nom: "DEF"; age: $2F) );
- AU COEUR DE TURBO PASCAL 379 AU COEUR DE TURBO PASCAL
- ==================== PAGE 39 ====================
- 5 r LE CODE COMPILE 5 LE CODE COMPILE 5
- 5.8 les constantes typées 5.8 les constantes typées 5.8
- 14 VAR indice: INTEGER; A16202 mov ax, [$0262]
- | 15 BEGIN vi 2D1000 sub ax, HO
- 16 kt tableau recordlindice].age:= $FF; B90200 mov CX 2
- 17 WITH kr tableau _record[indice] DO E8C5E1 call TU_INDEX_CHECK
- 18 age:=$77;., — D1E0 shl ax.
- 19 END. 8BC8 mov cxT)iax
- D1E0 shl axpok
- Fig. 5.174 Le programme desassemble_constante_typee2. 03C1 add ax, Cx
- Hf, i 97 xchg di
- 81C7702D add di, $2D70
- 0E push cs
- Li ici : 57 push di
- | Voici son code: C47EFC les di, [bp+ $FC]
- | B87700 mov ax, $0077
- 2D4D E849DD call TU_PARAGRAPHS 26 seg es.
- 2D50 0600 hex 0600 ; options 894504 mov [di+ $04], ax
- 2D52 780B hex 780B ; cs 83C404 add sp, $04
- 2D54 3C15 hex 3015 3) ds ‘
- 2D56 DDO2 hex DD02 ; code £90000 jmp FIN
- 2D58 2700 hex 2700 ; globales
- 2D5A 0004 hex 0004 ; min piles 33C0 FIN xor ax, ax
- | 2D5C 00A0 hex OOAO ; max piles E877DE call TU_HALT
- 2D5E 1000 hex 1000 ; fichiers 0000 hex 0000
- 2D60 0000 h 0000 ; i t L
- 2D62 0000 hee 0000 ; saga Fig. 5.175 Constantes typées structurées .
- 2D64 8BEC mov bp, sp j
- 2D66 E814DF call TU_TAILLE_CODE d
- i 2D69 6000 hex 6000 ; taille | Notez que:
- 2D6B 6D2D d SAUT _PRINCI PAL i
- | ; tinh sma 4 — pour accéder à la zone, l’instruction MOV est simplement préfixée par CS
- 2D6D E90C00 SAUT_PRINCIPAL jmp PRINCIPAL q — dans le cas du WITH, c’est le segment CS qui est poussé sur la pile. Les autres instructions
- | Fe | sont alors similaires à celles du WITH normal.
- | 2D70 03 hex 03 à
- | 2D71 414243 asc ? ABC’ \
- 2D74 1F00 hex 1F00 |
- | 2D76 03 hex 03 {5.8.4 RESUME
- | 2D77 444546 asc * DEF’ |
- 2D7A 2F00 \ hex 0000
- Les constantes typées:
- ( 202 }
- | JD 501000 Matt tin js qu Bit À — sont des variables initialisées stockées dans le code du programme et
- | 2D82 B90200 mov cx, $0002 4 accessible par CS
- | 2D85 E8E2E1 call TU_INDEX_CHECK | : Ë
- nl. 2D88 DIEO shl ax, 1 1 — pour traiter ces variables, le code:
- \ 2D8A 8BC8 mov Cx, ax | k |
- | 2D8C DIEO shl ax, 1 1 — préfixe les instructions de transfert par le segment CS
- | 2D8E 03C1 add ax. cx À — pousse CS sur la pile pour les instructions ou les routines de la
- | 2D90 97 xchg ih 4 librairie qui attendent le segment de la donnée sur la pile
- 2D91 B8FF00 mov ax, $OOFF 4
- 2D94 2E seg cs M
- i} 2D95 8985742D mov [di+ $2D74], ax \
- 1 AU COEUR DE TURBO PASCAL 380 AU COEUR DE TURBO PASCAL q AU COEUR DE TURBO PASCAL 381 AU COEUR DE TURBO PASCAL
- ==================== PAGE 40 ====================
- 5 LE CODE COMPILE 5
- 5.9 les variables absolues 5.9
- {5.9 LES VARIABLES ABSOLUES |
- {5.9.1 DEFINITION DES VARIABLES ABSOLUES
- TURBO PASCAL permet au programmeur de ge mnped à quel endroit est stockée une variable.
- Pour cela il suffit d'utiliser l’attribut ABSOLUTE. Par exemple:
- VAR entier: INTEGER ABSOLUTE $1234:$5678;
- Il existe 4 types de variables absolues:
- — les variables absolues situées dans le segment CS:
- VAR options: INTEGER ABSOLUTE CSEG: $2D50;
- — les variables absolues situées dans le segment DS:
- VAR handle! : INTEGER ABSOLUTE DSEG: $0242;
- — les variables absolues situées à la même adresse qu’une autre donnée (variable globale, locale,
- paramètre). Par exemple:
- VAR chaine: STRING[15];
- taille: BYTE ABSOLUTE chaine;
- — des variables absolues situées à une adresse quelconque:
- VAR equipement: BYTE ABSOLUTE $0040: $0010;
- {5.9.2 ACCES AUX VARIABLES ABSOLUES
- Voici comment le compilateur traite les variables absolues:
- — les variables absolues par rapport à DS sont traitées comme n’importe quelle variable globale.
- Le compilateur utilise simplement le décalage que vous lui fournissez, au lieu de le calculer
- lui-même
- — les variables absolues par rapport à CS sont traitées comme les constantes typées
- — les variables absolues greffées sur une autre variable sont traitées comme les variables du
- segment où se trouve la variable (DS ou SS)
- — les variables situées à une adresse quelconque sont traitées comme des constantes typées.
- AU COEUR DE TURBO PASCAL 382 AU COEUR DE TURBO PASCAL
- LE CODE COMPILE 5
- 5.9 les variables absolues 5.9
- Examinons le dernier cas à l’aide d’un petit exemple:
- (* 001 abso *)
- (* 18 aou 87 *)
- 0
- 1
- ?
- 3 PROGRAM desassemble absolute;
- 4 VAR absolue: INTEGER ABSOLUTE $1234: $5678;
- 5 entier: INTEGER;
- 6 BEGIN
- 7 entier:= absolue;
- 8 END.
- Fig. 5.176 Le programme desassemble_absolue.
- Voici le code correspondant:
- 2D4D E849DD call TU_PARAGRAPHS
- 2D50 0600 hex 0600 ; options
- 2D52 780B hex 780B ; cs
- 2D54 3C15 hex 3015): ds
- 2D56 D902. hex D902 ; code
- 2D58 2700 hex 2700 ; globales
- 2D5A 0004 hex 0004 ; min piles
- 2D5C 00A0 hex 00A0 ; max piles
- 2DS5E 1000 hex 1000 ; fichiers
- 2D60 0000 hex 0000 ; input
- 2D62 0000 hex 0000 ; output
- 2D64 8BEC mov b
- Pp, s
- 2D66 E814DF call TU. TATLLE_CODE
- td 1E00 hex 1E00 ; taille
- D6B 6D2D adr SAUT_PRINCI PAL
- 2D6D E90400 SAUT_PRINCIPAL jmp PRINCI PAL
- 2D70 7856 h
- ‘2D72 3412 han 3419
- 2D74 2E PRINCIPAL Ss
- 2D75 C43E702D tes di [$2D70]
- 2D79 26 seg es”
- 2D7A 8B05 mov ax, [di]
- 2D7C A36202 mov [$0262], ax
- 2D7F E90000 jmp FIN
- 2D82 33C0 FIN
- 2D84 E8B9DE call TU HALT
- 2D87 0000 hex 0000
- Fig. 5.177 Une variable absolue .
- AU COEUR DE TURBO PASCAL 383 AU COEUR DE TURBO PASCAL
- ==================== PAGE 41 ====================
- 5 LE CODE COMPILE 5
- 5.9 les variables absolues 5.9
- Notez que:
- — l’utilisation du code pour stocker l’adresse de la variable facilite son accès en utilisant LES DI.
- Elle permet aussi de ‘bénéficier de la mécanique des constantes typées, en évitant d’avoir à
- créer une nouvelle technique d’accès. :
- {5.9.3 RESUME
- Les variables absolues sont traitées:
- ~ comme des variables globales (absolues DSEG ou greffées sur une
- globale)
- - comme des constantes typées (absolues CSEG ou à une adresse
- absolue)
- _ comme des variables locales (absolues greffées sur des variables
- locales ou des paramètres)
- {S.A SYNTHESE)
- Le code TURBO PASCAL distingue 2 types de données:
- — les données manipulables dans les registres
- — les données dont la taille peut dépasser la capacité des registres disponibles.
- Pour les données trop volumineuses, le code utilise systématiquement la pile
- — pour stocker les valeurs à traiter
- — pour placer le segment de ces données (ce segment pouvant être DS, CS, SS ou ES). DI est
- alors utilisé pour connaitre de déplacement.
- Les données traitées ainsi comprennent les réels, les chaines, les tableaux et les enregistrements
- lorsqu’ils sont manipulés globalement et les ensembles.
- Pour les données manipulables dans les registres:
- — toute l’arithmétique est effectuée dans AX, en sauvant les valeurs intermédiaires sur la pile et
- en les récupérant dans CX
- — les accès par le biais de sélecteurs (tableaux, enregistrements, pointeurs)
- — sont calculés directement chaque fois que le compilateur connaît les valeurs à utiliser pour
- le calcul
- — sont effectuées en utilisant DI pour calculer le décalage, plus un décalage relatif constant
- dépendant des indices de départ ou des zones sélectionnées. ES est alors utilisé comme
- segment.
- — dans le cas de WITH, l'adresse de base est poussée sur la pile et récupérée dans ES et DI à
- l’aide de BP
- AU COEUR DE TURBO PASCAL 384 AU COEUR DE TURBO PASCAL
- LE CODE COMPILE 5
- synthèse 5.A
- 5.A
- ——
- _ J’accés aux variables locales et aux paramètres est effectué à l’aide de BP
- _ l'accès aux variables intermédiaires est effectué en utilisant la table des pointeurs des pi
- englobantes stockés dans chaque pile locale. PO S piles
- à Dans le cas de l'affectation, le calcul de l’adresse peut être séparé des instructions de stockage. La
- À sauvegarde sur la pile des adresses calculées est alors effectuée.
- Le traitement des fichiers utilise systématiquement la librairie, qui fait appel au DOS.
- à (5.8 CONCLUSION)
- } Dans ce chapitre nous avons examiné:
- 4 — par quelles instructions le code manipulait:
- — les données simples et structurées
- — globales, locales, sur le tas, dans le code
- i — en mémoire ou vers un périphérique
- AU COEUR DE TURBO PASCAL 385
- AU COEUR DE TURBO PASCAL
- ==================== PAGE 42 ====================
- LES OPTIONS DE COMPILATION 6
- CHAPITRE 6
- LES OPTIONS DE COMPILATION
- Dans ce chapitre nous allons:
- — décrire les options de compilation
- — indiquer leur effet sur le code généré
- A l'issue de ce chapitre vous serez en mesure:
- — d'éviter l’arrêt d'exécution lorsqu'une erreur d’entrée / sortie se produit
- — d'utiliser des lectures clavier non tamponnées
- — de modifier le nombre de fichiers ou de dimensionner les tampons d'entrée
- AU COEUR DE TURBO PASCAL 387 AU COEUR DE TURBO PASCAL
|