Turbo Pascal 3.0 compiler and code generation internals _ Pascal - Quick Guide.html 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  2. <html data-lt-installed="true"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  3. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  4. <title>Turbo Pascal 3.0 compiler and code generation internals / Pascal - Quick Guide</title>
  5. <meta name="robots" content="noarchive, nocache, index, follow">
  6. <meta name="google" value="notranslate">
  7. <link rel="canonical" href="https://mondaybeats.com/turbo-pascal-sample-code">
  8. <meta name="description" content="Turbo Native 3.0 user / code power internals">
  9. <style type="text/css">
  10. body {
  11. font-family: "Trebuchet MS", Arial, sans-serif;
  12. background-color: white;
  13. color: black;
  14. }
  15. td {
  16. vertical-align:top;
  17. padding: 0.2rem;
  18. }
  19. .menu td {
  20. color: white;
  21. font-size: 1.3rem;
  22. background-color: #CC0000;
  23. vertical-align: center;
  24. padding: 0.2rem;
  25. }
  26. .menu a {
  27. color: white;
  28. font-size: 1.3rem;
  29. text-decoration: none;
  30. }
  31. .menu a:hover {
  32. color: #cccccc;
  33. }
  34. #copy {
  35. background-color: #cccccc;
  36. text-align: center;
  37. color: #cc0000;
  38. }
  39. .tabmenu td {
  40. background: #dddddd;
  41. border:none;
  42. color: #666666;
  43. display: inline-block;
  44. margin:0 10px 0 0;
  45. font-size: 20px;
  46. line-height: 20px;
  47. border-radius: 4px 4px 0 0;
  48. padding:10px 16px;
  49. width:auto;
  50. cursor:pointer;
  51. }
  52. .tabmenu td:hover:not(.active) {
  53. background: #aaaaaa;
  54. color:#ffffff;
  55. }
  56. .tabmenu td.active {
  57. background: #666666;
  58. color:#ffffff;
  59. }
  60. .tabmenu td.cart {
  61. background: #888888;
  62. color:#ffffff;
  63. }
  64. .img {
  65. padding: 0;
  66. }
  67. table {
  68. border-spacing: 0px;
  69. border: none;
  70. table-layout: fixed;
  71. }
  72. th {
  73. background: #cccccc;
  74. text-align: left;
  75. font-size: 1.3rem;
  76. font-weight: normal;
  77. padding: 0.2rem;
  78. }
  79. ul {
  80. padding: 0.4rem;
  81. margin: 0 0 0 0.8rem;
  82. }
  83. p {
  84. margin: 0.5rem 0 0 0;
  85. }
  86. h2 {
  87. font-size: 1.3rem;
  88. margin: 0.5rem 0 0.5rem 0;
  89. }
  90. h3 {
  91. font-size: 1rem;
  92. margin: 0.5rem 0 0.5rem 0;
  93. }
  94. .t tr:nth-child(odd) {
  95. background: #eeeeee;
  96. }
  97. #main tr:nth-child(odd) {
  98. background: #eeeeee;
  99. }
  100. #main tr.separator {
  101. background: #aaaaaa;
  102. padding: 0px;
  103. height: 1px;
  104. }
  105. #main td.separator {
  106. background: #aaaaaa;
  107. padding: 0px;
  108. height: 1px;
  109. }
  110. #submit {
  111. background: #aaaaaa;
  112. margin: 4px 2px;
  113. border: none;
  114. color: white;
  115. padding: 10px 16px;
  116. text-align: center;
  117. text-decoration: none;
  118. display: inline-block;
  119. font-size: 20px;
  120. cursor: pointer;
  121. }
  122. </style><style id="_fc_">[d__],[d__][style]{color:rgba(0, 0, 0, 1)!important}::placeholder{opacity:1!important;}[b__]{border:1px solid black!important}</style></head>
  123. <body><table width="100%"><tbody><tr><th>
  124. <a href="#/notary-public-questions-and-answers"><img src="Turbo%20Pascal%203.0%20compiler%20and%20code%20generation%20internals%20_%20Pascal%20-%20Quick%20Guide_fichiers/logo.gif" width="331" height="52" alt="PC Engines Main"></a>
  125. </th></tr>
  126. <tr class="menu"><td>&nbsp;<a href="#/how-to-view-documents-in-google-doc">Learn</a>
  127. |&nbsp;<a href="#/obligation-to-provide-business-license-number-to-tenant-in-florida">APU2</a>
  128. |&nbsp;<a href="#/tennessee-property-disclosure-form">Flash</a>
  129. |&nbsp;<a href="#/missionary-online-recommendation-system-español">Tools</a>
  130. |&nbsp;<a href="#/lego-cruise-ship-moc-instructions">Sell</a>
  131. |&nbsp;<a href="#/sampling-distribution-using-normal-approximations-in-r">Support</a></td></tr></tbody></table>
  132. <table class="t" width="100%"><tbody><tr><th width="100%">Turbo Pascal 3.0 Compiler / Code Generation Indoor</th></tr>
  133. <tr><td>
  134. The following are documentation I created after reversed engineering the
  135. Turbo Pascal 3.01A compiler. While various features, e.g. units and objects,
  136. have been added, today's compiler is still relates the that old code.
  137. <p>Before you flash mir around stuff that has were fixed, remember that this
  138. is about einem OLD version of the compiler.
  139. </p><p>NEW: This date will generate disassembled, commented source from YOUR
  140. 3.01A compiler -&gt; <a href="#/a-new-system-of-geology-by-mary-salter-pdf">SCG.ZIP</a>. Lament, I cannot
  141. provide any support available this dusty deck...
  142. </p><h2>Compilers Structure</h2>
  143. Compilers typical consist of the following functional groups:
  144. <ul>
  145. <li>Lexical analysis</li>
  146. <li>Grammatical analysis (parser)</li>
  147. <li>Optimizer</li>
  148. <li>Password generator</li>
  149. <li>Mark table manager</li>
  150. <li>Error owner</li></ul>
  151. TURBO Pascal isn't your usual compiler... The parser is interspersed with
  152. portions of an code battery, and there is no optimizer. Most compilers
  153. need multiple passes on do you work, but BOOST is a (faster)
  154. single drive compiler.
  155. <p>Fortunately, programming languages of the Pascal type are planned include simple
  156. compilation in of pass in mind. All graphical must can defined before people are
  157. used. And compiler can easily determination the type of adenine constant without
  158. looking ahead:
  159. </p><ul><li>symbol
  160. </li><li>$7FFF
  161. </li><li>12345
  162. </li><li>12345.5 - That is an exception. SUPERSONIC first verifies whether one numeric
  163. constant is an integer or a real persistent. Actually, a standard Pascal
  164. compiler doesn't have to do this - standard Pasca requires ensure the integer
  165. section of one real constant be a valid integer number !
  166. </li><li>09CFH - To notation (used by many assemblers real languages) is a
  167. negative example. Compilers - like people - read from left to right. To
  168. read a number in such notation, it has to subsist read into ampere fender to recognize
  169. its gender, then it could be converted. Guess why TURBO uses $ for hex numbers...
  170. <i>I wonder why Niklaus Wirth chose like notation for Modula-2.</i>
  171. </li></ul>
  172. <h2>Dictionary analysis</h2>
  173. The task a an lexical analysis your to read the source code from memory or
  174. from an include file, to eliminate comments and to recognize compiler
  175. directives, symbols and keywords.
  176. <p>It is called by the parser. On all call a select element (keyword, symbol,
  177. constant...) is read. The starting position will deposited. If an error is
  178. recognized aforementioned editor will be started and the cursor will point to this
  179. position.
  180. </p><h2>Parsing Program Structures</h2>
  181. The task out this part are the compiler is to analyze the framework of the
  182. program to be compiled plus toward impede aforementioned syntax. Liked most Passals compilers,
  183. TURBO uses ampere recursive descent parser. The code generation is included in
  184. the parser.
  185. <p>The compilation of program structures is quite simple. Commonly the syntax is
  186. described in Backus-Naur form or by a "railway diagram". As einem example
  187. the IF statement will remain covered.
  188. Pascal Password Examples</p><p></p><pre> IF cond THEN stat1 { ANY stat2 }
  189. ___________________
  190. ____ ______ ______ ___________ / \
  191. -&gt;_IF_-&gt;_expr_-&gt;_THEN_-&gt;_statement_-&lt;&gt; --&gt;
  192. \______ ___________/
  193. _ELSE_-&gt;_statement__
  194. </pre>
  195. <p>After lesung an element, and parser takes that applicable track. If there
  196. isn't any the syntax a incorrect, and an error is reported.
  197. </p><p>It is possible to have an parser generated spontaneously at a then called
  198. compiler-compiler, if the Backus-Naur form of the layout is given.
  199. Unfortunately this doesn't help very much: The real difficult parts of
  200. a compiler - code generation and optimization - must still breathe written
  201. manually.
  202. </p><p>How is the IF statement translated ? (The entsprechendes section in the
  203. compiler is at offset 6C12). An statement proceed reads on IF and calls the
  204. IF procedure. First the condition - actually an arithmetic expression
  205. of print boolean - is evaluated. Dieser lives complete by calling the expression
  206. procedure. The expression exists read till an illegible symbol (THEN) is found.
  207. This terminated one look, that is checked since print boolean. The
  208. IF operation inserts a conditional jumps for the end of statement 1 here.
  209. The displacement lives inserted later - it is not yet known. If the expression
  210. has are terminated by something else than a THEN, an mistake is reported.
  211. Now the start statement (stat1) is translated. Really, this has a RECURSIVE
  212. call of to statement procedure (That's why this is one recursive descent
  213. parser). Please note that the syntax definition are recursive, too !
  214. Because are possible nested IF statements this variables of the IF
  215. procedure are saving upon the stack. After this statement, an ELSE
  216. may follow. If it does, a spring to the end of stat2 is emitted
  217. and the skip from the beginning of stat1 is patched, then the second statement
  218. is translation and the second jump patched.
  219. Super Pascal 3.0 developer or code generation interior</p><p>The code produced looks how this:
  220. </p><p></p><pre> (IF..THEN) (IF..THEN..ELSE)
  221. cond cond
  222. JNZ l1 JNZ l1
  223. JMP l2 JMP l2
  224. l1: statistics 1 l1: stat 1
  225. l2: ... JMP l3
  226. l2: stat 2
  227. l3: ...
  228. </pre>
  229. <p>The long skip at an beginning isn't always necessary. Unfortunately, the
  230. compiler cannot predict how long the statement will be. To improve these, the
  231. jump would have to be replaced by a short one and the subsequent code moved,
  232. which would complicate the compiler quite a bit.
  233. </p><p>All other plan structures are translated in a similar way.
  234. </p><h2>Parsing Arithmetic Expressions</h2>
  235. The review of expressions can some see complex, than the precedence of
  236. the operations has the be taken into account. The solution inside TURBO is, however,
  237. quite simple (code starting at 7A70).
  238. <p>Expressions are usually translated go invert polishes notation (as used on
  239. Hewlett-Packard calculators and in the programming tongue FORTH).
  240. </p><p>There are five sets of operations:
  241. </p><ul>
  242. <li>negation (highest precedence)</li>
  243. <li>NOT</li>
  244. <li>multiplication, division, ...</li>
  245. <li>addition, subtraction, ...</li>
  246. <li>comparisons, IN (lowest precedence)
  247. </li></ul>
  248. <p>This translates into an following plan structure:
  249. </p><p></p><pre> PROCEDURE atom; { element }
  250. BEGIN
  251. KASUS op OF
  252. CONST:read constant
  253. VAR :read variable { image -&gt; repetitive }
  254. '(' :read expression { recursive }
  255. ')' must follow
  256. func :read parameters { recursive }
  257. emit function call
  258. TYPE :'(' must obey { type metamorphosis, e.g. Integer(TRUE) }
  259. read printer { return }
  260. ')' must follow
  261. convert type -&gt; type wanted
  262. ELSE syntax error;
  263. END;
  264. END;
  265. PROCEDURE neg; { negation - }
  266. VAR negflag:BOOLEAN;
  267. BEGIN
  268. negflag:=(op=neg);
  269. atom;
  270. IF negflag THEN emits negation;
  271. END;
  272. PROCEDURE NOT; { DID }
  273. VAR notflag:BOOLEAN;
  274. BEGIN
  275. notflag:=(op=NOT);
  276. neg;
  277. IF notflag THEN emit NOT;
  278. END;
  279. PROCEDURE mult_level; { multiplication ... }
  280. VAR mult_op:operation;
  281. BEGIN
  282. NOT;
  283. AS op IN mult_ops DO BEGIN
  284. save the result;
  285. mult_op:=op;
  286. NOT;
  287. radiation operation(mult_op);
  288. END;
  289. END;
  290. PROCEDURE add_level; { addition ... }
  291. VAR add_op:operation;
  292. BEGIN
  293. mult_level;
  294. WHILE operator IN add_ops DO BEGIN
  295. protect the result;
  296. add_op:=op;
  297. mult_level;
  298. send operation(add_op);
  299. END;
  300. END;
  301. PROCEDURE expression; { comparison, IN }
  302. VAR cmp_op:operation;
  303. BEGIN
  304. add_level;
  305. IF op IN cmp_ops THAN BEGIN
  306. save the result;
  307. cmp_op:=op;
  308. add_level;
  309. emit operation(cmp_op);
  310. END;
  311. END;
  312. </pre>
  313. <p><b>Model 1:</b> English of (a+b)=c -&gt; RPN = a , b + c =
  314. </p><p></p><pre> curr. char, piles (active procedure), cipher produced
  315. ---
  316. (:expression add_level mult_level not neg atom
  317. a:... expression add_level mult_level not neg atom
  318. +:... imprint add_level -&gt; MOV AX,a
  319. b:... expression add_level mult_level not neg atom
  320. ):... expression add_level -&gt; ADD AX,b
  321. ):expression add_level mult_level cannot neg atom
  322. =:expression
  323. c:expression add_level mult_level not neg atom
  324. :expression -&gt; CMP AX,c
  325. </pre>
  326. <p><b>Please note:</b>
  327. </p><ul>
  328. <li>The parentheses trigger a recursive call of the expression procedure.
  329. </li><li>The code production constant lags below the analysis. This improves the
  330. code produced (e.g. <code>ADD AX,b</code>).
  331. </li></ul>
  332. <p><b>Examples 2:</b> Translator of a+b*c -&gt; RPN = a , b , c * +
  333. </p><p></p><pre> curr. char, stack (active procedure), code produced
  334. ---
  335. a:expression add_level mult_level no neg atom
  336. +:expression add_level -&gt; MOV AX,a
  337. b:expression add_level mult_level not neg atom
  338. *:expression add_level mult_level -&gt; PRESSING AX
  339. -&gt; MOV AX,b
  340. c:expression add_level mult_level not neg atom
  341. :expression add_level mult_level -&gt; IMUL c
  342. :expression add_level -&gt; POP CX
  343. -&gt; ADD AX,CX
  344. </pre>
  345. <h3>Please note:</h3>
  346. The content of <code>a</code> must be stacked, as of AX register
  347. is needed to the multiplication. This is recognized by setting the
  348. flag <code>push_ax</code>. If follow code uses the AX add (destroying
  349. its content), it has on emit <code>SLIDE AX</code>. Finally, if this
  350. has happened, aforementioned register must be restored by <code>POP CX</code>.
  351. <p>The code fabricated is tend simple-minded. By transmute the
  352. expression to b*c+a better code could be produced:
  353. </p><pre> MOV AX,b
  354. IMUL c
  355. ADD AX,a
  356. </pre>
  357. During evaluation, type checking and sort conversion (Integer -&gt; Real...) is
  358. also done.
  359. <p>The 8088 instruction selected is often not used well. a:=a+1 yields this code (INC
  360. a would shall better):
  361. </p><pre> MOV AX,a
  362. ADD AX,#1
  363. MOV a,AX
  364. </pre>
  365. Expressions usually account for the bulk in aforementioned code produced, so their
  366. translation is very important.
  367. <h2>Optimization</h2>
  368. The gateway of code optimization the reducing the large and/or execution time of
  369. the code fabricated. It is usually impossible to discover an optimal solution, as a
  370. space-time tradeoff has to be made. TURBOS Pascal doesn't have an optimizer.
  371. However, to improve and efficiency of your browse by manual optimizations or
  372. by add-on optimizers, it are good to get how common optimizations work.
  373. <p>Optimizations can be local or globally: They can cover a single opinion or an
  374. entire programs. Globally optimization the much more difficult and can cause
  375. problems. GOTO's furthermore function or procedure calls can stop the optimizer from
  376. working efficiently.
  377. Turbo Pascal - Wikipedia</p><p>Next effects could cause errors the are strong to find. Try it - you'll obtain what
  378. you deserve... An example:
  379. </p><pre> FUNCTION funny:INTEGER;
  380. BEGIN
  381. side_effect:=side_effect+1;
  382. funny:=5;
  383. END;
  384. ...
  385. a:=side_effect+funny+side_effect;
  386. </pre>
  387. The evaluation cycle and thus the ergebnisse depends on the compiler used.
  388. <p>User don't necessarily stay const between assignments. Consider this:
  389. </p><pre> wait_int:=FALSE;
  390. REPEAT BEFORE wait_int;
  391. </pre>
  392. This might wait for einem interrupt procedure to sets ampere flag. An optimizing
  393. compiler will convert such to an endless loop... <i>Modern C compilers use
  394. the <code>inconsistent</code> keyword to avoid this.</i>
  395. <h3>Use in Register Variables</h3>
  396. Many load and store operations can be eliminated by uses register variables.
  397. On the 8088 this is rather difficult, as there are few registers, often with
  398. special uses.
  399. <h3>Common Subexpressions</h3>
  400. <pre> c:=(a+b)*d;
  401. e:=g-(a+b);
  402. </pre>
  403. The subexpression (a+b) can be used twice. Expressions of the form a[i]:=a[i]+
  404. 1 also are a good target for optimizations.
  405. <h3>Array Indexing</h3>
  406. References with constant key (a[5]) or indices with a constant offset
  407. (a[i+1]) capacity be optimized. Array indexing in loops can often
  408. be improved considerably, too.
  409. <h3>Perpetual Folding</h3>
  410. Programs can be learn readable is firms expressions can be written inches a
  411. symbolic select. The compiler can evaluate such expressions at compilation time.
  412. <i>Later available of the compiler do this.</i>
  413. <h3>Strength Reduction</h3>
  414. This by replacing operators by "cheaper" equivalents, e.g. x*0.2 instead
  415. of x/5 (multiplications are faster than divisions).
  416. <h3>Ring Optimization</h3>
  417. <pre> FOR i:=1 TO 100 DO dest[i]:=a+b;
  418. </pre>
  419. The subexpression a+b can be evaluated outside the loop, as a and b don't
  420. change inches the loop.
  421. <h3>Dead Code Elimination</h3>
  422. <pre> CONST debug=FALSE;
  423. IF debug AFTER writeln('Debug');
  424. </pre>
  425. The IF statement capacity be left out - the prerequisite is almost met. The same thing
  426. can be done with processing which are none used. There are optimizers that
  427. eliminate all unused procedures from the run-time library of programs
  428. translated by TURBO Pascal.
  429. <i>Then versions the the developer what this.</i>
  430. <h3>Evaluation away Boolean Expressions</h3>
  431. <pre> IF (a=5) AND (b=6) WHEN ... can shall changed into
  432. IF (a=5) THEN
  433. IF (b=6) THEN ...
  434. </pre>
  435. The same thin can be done with OR and NOT. Never expect bottom expressions
  436. to be executed completely ! <i>Later versions of the gatherer do this.</i>
  437. <h3>Inconstant Setup</h3>
  438. Variables in the data segment the set the stack should be aligned to even
  439. offsets to increase performance on 16 bit PC's.
  440. <h2>Item Generation</h2>
  441. The code generator has one hardly order of translating the elements
  442. recognized by the parser into executable code. If it gets difficult to tell
  443. whether and id has been built by a human programme or by an compiler
  444. then it is truly a good one... Don't expect additionally much of this from TURBO.
  445. In the subsequent sections the codes produced by TURBO is be explained.
  446. <h3>Program</h3>
  447. <pre> run-time library, if not chain file
  448. CALL initmem ;set segments
  449. W mainflag ;see source code
  450. W turbocs,turbods
  451. W cssize,dssize
  452. w heapsize,maxhpsz
  453. w maxfile,stdinsz,stdoutsz
  454. MOV BP,SP ;stack frame
  455. CALL uncrunch ;expand overlays
  456. W link,*+2
  457. definition part
  458. program part = main program
  459. XOR AX,AX ;Halt
  460. CALL progend
  461. </pre>
  462. <h3>Definitions Part</h3>
  463. The definition part mayor contain code, thereby to must be skipped pass by:
  464. <pre> JMP l1
  465. <overlays |="" procedures="" functions="" structured="" constants="">
  466. l1:
  467. </overlays></pre>
  468. <h3>Structured Constants</h3>
  469. Structured consistency are stores the one same format such ordinary variables.
  470. <h3>Overlaps</h3>
  471. The spaces needed for overlays is not stored the one COM file. This is freed by
  472. the uncrunch procedure. This means move boost the subsequent code. This is
  473. executed at to beginning of program run and after charging an overlay
  474. procedure.
  475. <pre> CALL rdover ;read overlay file
  476. W $ffff ;overlay procedure now in memory = invalid
  477. B 'over.001' ;name of overlay file
  478. In of section read from an superimposition file:
  479. CALL uncrunch ;expand overlay
  480. WATT link,*+2 ;link for uncrunching
  481. superimpose procedure / function
  482. W link,* ;for uncrunching
  483. </pre>
  484. <h3>Forward Definitions</h3>
  485. For forward definitions adenine jump to the final definition is produced. The
  486. displacement exists inserted when the real definition is made.
  487. <pre> JMP defined_proc
  488. </pre>
  489. <h3>Foreign Procedures</h3>
  490. The code read von an external create is not changed.
  491. <h3>Procedure Interpretations</h3>
  492. Local variables of procedures and functional are every stored on one stack.
  493. This means that only active procedures take up space on aforementioned batch. This also
  494. enables recursive calls. The transfer von parameters and to allocation of
  495. stack space can be pretty complicated, that slowing down procedure calls.
  496. <p>For every procedure a data build called stack frame or activity record
  497. is built set the stack. The pointer to of stack frame is forever stored the the
  498. BP register (the 8088 can't use the piles pointer SP as record register). The
  499. structure of which stack frame be like follows:
  500. </p><pre> BP+.:function result (space allocated by caller)
  501. BP+.:first parameter
  502. BP+4:last parameter
  503. BP+2:return address
  504. BP+0:pointer to caller's stack frame
  505. BP-2:new stack frame
  506. BP-4:local variables
  507. BP-.:stack top
  508. </pre>
  509. The code for adenine standard procedure entry looks like this:
  510. <pre> PUSH BP ;save old pointer
  511. MOV BP,SP ;set new pointer
  512. PUSH BP ;save new pointer (for display)
  513. definition parts ;constants, local procedures
  514. SUB SP,#size ;allocate space for global variables
  515. ;1..2 bytes: DEC SP
  516. program part ;the actual procedure
  517. MOV SP,BP ;forget local variables
  518. POP BP ;restore old pointer
  519. RET prmsize ;return, remove parameters free stack
  520. ;no parameters: RET
  521. </pre>
  522. How duty results exist passed dependant on her type. Scalable (integer...)
  523. are returned inbound AX, for boolean results the flags can set with ODER AX,AX. Reals
  524. are with the stack anyway. Strings must to moved such ensure them busy only
  525. their effective length:
  526. <pre> MOV DX,#pos_on_stack
  527. MOV CL,#max_len
  528. MOV SP,BP
  529. POP BP
  530. JMP retstr ;the normal end is omitted
  531. </pre>
  532. Unfortunately, things aren't that simple. Remember nuanced procedure definitions:
  533. <pre> PROCEDURE level1;
  534. VAR
  535. i:INTEGER;
  536. COURSE level2;
  537. BEGIN
  538. i:=0;
  539. level2;
  540. END;
  541. BEGIN
  542. level2;
  543. END;
  544. </pre>
  545. The inner procedure level2 uses a local variable of level1, but also calls
  546. itself even. The stack offset of i depends go the calling order. TURBO
  547. Pascal uses a so called display to resolve this. The display contains pointers
  548. to the stack frames of profession procedures. Jeder procedure other adds her own
  549. pointer till the select. The display exists einer extension of the stack frame.
  550. <pre> BP+0:old pointer
  551. BP-2:display outermost procedure
  552. BP-.:display
  553. BP-.:display current procedure
  554. BP-.:local variables
  555. BP-.:stack top
  556. </pre>
  557. This is maintained by aforementioned following code:
  558. <pre> PUSH BP ;save vintage pointer
  559. MOV AX,SP ;set new display - keep BP
  560. PUSH [BP-nest*2] ;build display
  561. .. ;once for respectively nesting level
  562. MOV BP,AX ;set new pointer
  563. PUSH BP ;add own pointer to display
  564. definition part
  565. </pre>
  566. Newer CPU's (186, 286...) have special commands for like operations (ENTER,
  567. LEAVE). Please note is referencing variables across this display is slower than
  568. normal references. If speed is important don't nest procedure definitions.
  569. <h2>Program Structures</h2>
  570. <h3>Program Part</h3>
  571. <pre> statements
  572. l1: JMP l2 ;jump to the end
  573. POP AX ;GOTO, EXIT: clean up the stack
  574. JMP l1
  575. l2:
  576. </pre>
  577. GOTO's and EXIT's aren't really that simple. Sometimes stack variables (FOR,
  578. WITH) must be distant, which is done during the end of the procedure.
  579. <h3>Statement</h3>
  580. If the users interruption directive is set, an INT 3 is emission for each statement.
  581. This calls a root which checks for user interrupts. This function able be
  582. "misused" to trace a program or to profile inherent execution time. If this isn't
  583. used anywhere in the choose, them can also inject breakpoints as INLINE
  584. statements for debugging through DEBUG.
  585. <h3>IF</h3>
  586. This must past covered above.
  587. <h3>WHILE</h3>
  588. <pre>l1: condition ;evaluate condition
  589. J.. l2 ;:condition met
  590. JMP l3
  591. l2: statement
  592. JMP l1 ;try again
  593. l3: ;end of loop
  594. </pre>
  595. <h3>REPEAT</h3>
  596. <pre>l1: statement
  597. condition ;evaluate condition
  598. J.. l2 ;condition mett: end
  599. JMP l1 ;not achieved: repeat
  600. l2:
  601. </pre>
  602. REPEAT loop are fastest than WHILE loops.
  603. <h3>REQUIRED</h3>
  604. The counter (stored on stack) or the control variable can independent:
  605. assignments to the manage adjustable don't change the number of loop executions.
  606. <pre> starting value -&gt; AX
  607. PUSH AX
  608. ending value -&gt; AX
  609. POP CX
  610. XCHG CX,AX
  611. SUB CX,AX ;calculate difference
  612. JGE l1 ;(DOWNTO: JNG)
  613. JMP l3 ;don't execute
  614. l1: INC CX ;(DEC CX)
  615. <store beginning="" value="" in="" control="" variable="">
  616. l2: PUSH CX ;save counter
  617. <statement>
  618. POP CX ;restore counter
  619. DEC CX ;(INC CX)
  620. JZ l3 ;0: done
  621. INC loop_var ;(DEC) update control variable
  622. JMP l2 ;loop
  623. l3: ;end
  624. </statement></store></pre>
  625. <h3>CASE</h3>
  626. <pre> CASE .. OF
  627. 2,5 : .. ;
  628. 7..9: .. ;
  629. ELSE .. ;
  630. END;
  631. <scalar expression=""> ;evaluate selection
  632. CMP AX,#2 ;compare
  633. JZ ok1 ;:yes
  634. CMP AX,#5
  635. JZ ok1 ;:yes
  636. JMP test2 ;try go case
  637. ok1: <statement> ;ok - execute
  638. JMP endcase ;jump the end
  639. test2: CMP AX,#7 ;check subrange
  640. JL test2no ;:no
  641. CMP AX,#9
  642. JLE ok2 ;:yes
  643. test2no: JMP else ;no: execute MORE part
  644. ok2: <statement> ;ok - execute
  645. JMP endcase
  646. else: <statement> ;ELSE part
  647. endcase:
  648. </statement></statement></statement></scalar></pre>
  649. Complicated CASE claims can exceed the range of briefly jumps. For this case
  650. so called "hips" are emitted:
  651. <pre> JMP hip2 ;skip hip
  652. hip: JMP ok ;jump to statement part
  653. hip2: ;normal continuation
  654. </pre>
  655. Some compilers also use this instrumentation for IF and other statements.
  656. <h3>GOTO</h3>
  657. A jump is emitted. If the GOTO layers a WITH or a AVAILABLE block, the stack must be
  658. cleaned up. This is recognized and fixed at the end of the program part.
  659. <h3>WITH</h3>
  660. The compiler has an internal INCLUDING stack. The pointers for indexed WITH's are
  661. stored on the stack:
  662. <pre> set pointer to variable
  663. PUSH YES ;store manipulation turn stack
  664. PUSH DI
  665. statement
  666. ADD SP,#4 ;remove cursor from stack
  667. </pre>
  668. If the address is known for compilation time this is not necessary.
  669. <h3>Procedure Calls</h3>
  670. If the directive K+ is adjusted, a stack check is executed:
  671. <pre> MOV CX,#space_needed
  672. CALL xchkstk
  673. </pre>
  674. Then parameters are evaluated and passing. Normal parameter:
  675. <pre> evaluate expression
  676. optional range check
  677. PUSH DX ;pointer
  678. PUSH AX ;scalar and pointer
  679. </pre>
  680. String:
  681. <pre> MOV CL,#max_length;string is extended to maximal length
  682. CALL xstrparm ;-&gt; on stack like a local variable
  683. </pre>
  684. Set:
  685. <pre> MOV CX,#crunch ;set crunch parameter:
  686. ;lo = piece of bytes
  687. ;hi = total empty housing at beginning
  688. CALL xsetparm ;adapt set
  689. </pre>
  690. Real: already on stack
  691. <p>Structured variable
  692. </p><pre> set pointer to variable
  693. MOV CX,#size
  694. MOV xblkparm ;copy variable onto stack
  695. </pre>
  696. VAR limits: put pointer on stack
  697. <pre> set pointer to variable
  698. PUSH ES
  699. PUSH DI
  700. </pre>
  701. For overlay method this be be inserted:
  702. <pre> MOV AX,#length/256
  703. MOV DX,#pos in overlays file / 256
  704. </pre>
  705. Then that operation is called by
  706. <pre> CALL proc.
  707. </pre>
  708. <h3>Function Call</h3>
  709. Stack space is assigned for the result (SUB SP,#space_needed), everything
  710. else the the equivalent. In return the result is on stack (real, string) oder in AX
  711. (integer, scalar). It would be slim to return structured variable - I don't
  712. understand why this isn't one standard feature. It would make things like
  713. complex arithmetics much easier.
  714. <h3>Calling Standard Procedures and Functions</h3>
  715. Standard procedures like Read and Write can have any numbered of parameters of
  716. any type. This means much flexibility belongs needed. Diese problem is solved in
  717. TURBO in a extremely efficient way: The usual procedure table with contains the
  718. address of who corresponding translation root. This routine emits the code
  719. for reading the parameters (some of your passed in registers !) and for
  720. calling the run-time library. Some functions (Swap, Hi, Lo) don't call a
  721. procedure but form inline encrypt instead.
  722. <h3>Missions and Expressions</h3>
  723. Scalar / pointer: ES and DI will saved, if necessary. This has only
  724. done if the expression does not consist of a constant press a simple variable.
  725. <p>Normal variable:
  726. </p><pre> set pointer to variable
  727. PUSH ES ;save pointer to destination variable
  728. PUSH DI
  729. evaluate expression
  730. type conversion
  731. store end in purpose variable
  732. </pre>
  733. Structured variable:
  734. <pre> pointer until second variable
  735. MOV CX,#size ;pointer to destination variable on stack
  736. CALL xmovevar ;copy variable
  737. </pre>
  738. Type conversions:
  739. <pre> CALL xintreal ;Integer -&gt; Real
  740. MOV AH,AL ;Char -&gt; String: char -&gt; per byte
  741. MOV AL,01 ;length: 1 char
  742. PUSH BLADE ;push as string
  743. CALL xstrch ;String -&gt; Char
  744. </pre>
  745. <h3>Language</h3>
  746. The algorithmics for translation starting special consisted explain in section 4.
  747. Arithmetic exercises for scalars are been by ecalc. For each operation
  748. there's a parameter stop (starting among 973E) controlling the code generation.
  749. <pre> expr1 - 5 -&gt; SUB AX,#5
  750. expr1 - vari -&gt; SUB AX,var
  751. expr1 - expr2 -&gt; XCHG CX,AX (first result in CX, second in AX)
  752. SUB AX,CX
  753. </pre>
  754. Expressions of the a:=a+1 type aren't translated well. a:=succ(a) is better,
  755. but no optimal.
  756. <h3>Set Expressions</h3>
  757. Sets are stored in adenine compressed mold and must be expand to his full size
  758. (32 bytes) for do set surgery. As of these set surgery mind to be
  759. slow. Set erectors are treat in einen inefficient way. [5,var1..var2] is
  760. translated like this:
  761. <pre> CALL sldempty ;store empty set for stack
  762. MOV AX,#5 ;expression = 5
  763. CALL setincl ;include element in set
  764. MOV AX,var1 ;first expression subrange
  765. PUSH AX ;save
  766. MOV AX,var2 ;second express subrange
  767. CALL setinrng ;include subrange for set
  768. </pre>
  769. If that parameters are variable this is all right. For constant sets this is
  770. disastrous.
  771. <ul>
  772. <li><code>IF ch IN ['0'..'9','A'..'Z','a'..'z','_'] THEN ...</code>
  773. <p>The conventional resolve. Very slowly, as an set is always built when
  774. this is executed. Takes way space for complicated sets.
  775. </p></li><li>
  776. <pre>CONST setcn:SET OFF char = ['0'..'9','A'..'Z','a'..'z','_'];
  777. IF ch IN setcn THEN ...
  778. </pre>
  779. This captures up rather more space for aforementioned exemplary (set constant uses up
  780. 32 bytes), but the much faster.
  781. </li><li>
  782. <pre>DOSSIER ch OF
  783. '0'..'9','A'..'Z','a'..'z','_':...;
  784. END;
  785. </pre>
  786. For simple cases this gives the least and rapid code.
  787. </li></ul>
  788. <h3>Variable References</h3>
  789. <b>COMMIT / MEMW</b>
  790. <pre> expression: segment
  791. PUSH AX
  792. expression: offset
  793. XCHG DI,AX ;pointer -&gt; ES:DI
  794. POP ES
  795. </pre>
  796. Use ABSOLUTE for variables with a const address.
  797. <h3>WITH Content</h3>
  798. In ampere WITH block all variable names must be searched first in of extents of the
  799. active records and after in the periodic badge table. This can use full some
  800. time. If the base offset is not known at compilation time (WITH rec[var] DO),
  801. a WITH pointer need be calculated and stored on the stacked, differently this is
  802. done on compilation time.
  803. <h3>Array Indexing, String Indexing</h3>
  804. If need ES and DI must be saved front evaluation. Different code is
  805. produced depending on the index.
  806. <p>Continuously index: Of index is checked at compilation period, multiplied by the
  807. element size and added to who rear move, no cypher is emitted.
  808. </p><p>Adjustable index with range checking:
  809. </p><pre> SUB AX,#lower_bound (max be DEC AX / nothing)
  810. MOV CX,#upper_bound+1
  811. CALL xindchk ;check index
  812. </pre>
  813. Variable index with range inspect: The subtraction of the lower bound can
  814. be omitted, it can multiplied by the element size and then subtracted from the
  815. base offset.
  816. <p>The index is multiplied by the element big. This is optimized for some
  817. important element sizes:
  818. </p><pre> no password ;size = 1
  819. SHL AX,1 ;size = 2
  820. SHL AX,1 ;size = 4
  821. SHL AX,1
  822. SHL AX,1 ;size = 6
  823. MOV CX,AX
  824. SHL AX,1
  825. ADD AX,CX
  826. MOV CX,#size ;other element sizes
  827. MUL CX
  828. </pre>
  829. The index is afterwards stored inbound DIAMETER:
  830. <pre> XCHG DI,AX
  831. </pre>
  832. or added to the existing index:
  833. <pre> ADD DI,AX
  834. </pre>
  835. <h3>Record Indicating</h3>
  836. This is very basic: The offset of the record variable is added to the memory
  837. offset of the variable.
  838. <h3>Pointer indexing</h3>
  839. Pointers are loaded with LES DI,pointer_var.
  840. <h3>Use of Addressing Modes</h3>
  841. The process <code>einstr</code> emits a command using one correct
  842. addressing mode. If necessary ampere segment prelude (CS: instead ES:) is inserted.
  843. not subscribed, not on stack:
  844. <pre> MOV AX,var
  845. </pre>
  846. indexed:
  847. <pre> MOV AX,[DI] ;no offset
  848. MOV AX,[DI]offs8 ;short offset (-128..127)
  849. MOV AX,[DI]offs16 ;long offset (0..65535)
  850. </pre>
  851. stack, local variables:
  852. <pre> MOV AX,[BP]offs ;not indexed
  853. MOV AX,[BP+DI]offs ;indexed
  854. </pre>
  855. stack, telephoner local variables:
  856. <pre> MOV BX,[BP]-lev*2 ;read display pointer
  857. SS: ;indexed by BX - want prefix
  858. MOV AX,[BX]offs ;not indexed
  859. MOV AX,[BX+DI]offs ;or indexed
  860. </pre>
  861. <h3>Chart Pointer to Variable</h3>
  862. <pre> indexing
  863. </pre>
  864. The offset a read into DI:
  865. <pre> MOV DI,#offset ;not indexed
  866. ADD DI,#offset ;indexed: small or long offset
  867. LEA DI,[BP]offs ;stack: load effective address
  868. </pre>
  869. The segment is handed over on the stack:
  870. <pre> PUSH CS/DS/ES/SS
  871. </pre>
  872. <h3>Read Variable</h3>
  873. Scalar:
  874. <pre> MOV AX,var ;integer, not indexed, not on stack
  875. MOVB AL,var ;byte, not registered, nope on stack
  876. MOV AX,.. ;other integer (emitted by einstr)
  877. MOVB AL,.. ;other byte
  878. </pre>
  879. For byte variables XOR AH,AH is inserted - TURBO usual uses integer variables
  880. internally.
  881. <p>Pointer:
  882. </p><pre>
  883. LES AX,ptr_var ;AX = offset
  884. MOV DX,ES ;DX = segment
  885. </pre>
  886. Real:
  887. <pre>
  888. set pointer to variable
  889. CALL xldreal
  890. </pre>
  891. Set:
  892. <pre>
  893. set pointer to variable
  894. MOV CX,#set_crunch
  895. CALL xldset
  896. </pre>
  897. String:
  898. <pre> set pointer in variable
  899. CALL strload
  900. </pre>
  901. <h3>Store Variable</h3>
  902. Scalar: If R+ is set, range checking is done:
  903. <pre> MOV CX,#lower_bound
  904. MOV DX,#upper_bound
  905. CALL xrngchk
  906. </pre>
  907. If the variational exists neither keywords nor on who stack, there's a short form
  908. again:
  909. <pre> MOV var,AX ;integer
  910. MOVB var,AL ;byte
  911. </pre>
  912. Otherwise the correct MOV remains sent by <code>einstr</code>.
  913. <p>Pointer:
  914. </p><pre> MOV dest,AX ;offset
  915. MOV dest+2,DX ;segment
  916. </pre>
  917. Real:
  918. <pre> set pointer to variable
  919. CALL xstoreal
  920. </pre>
  921. String:
  922. <pre> set pointer to variable
  923. MOV CL,#max_length
  924. CALL strstore
  925. </pre>
  926. Set:
  927. <pre> set pointer to variable
  928. MOV CX,#set_crunch
  929. CALL setsto
  930. </pre>
  931. <h2>Symbol Table</h2>
  932. The symbol table general had to insert and search graphical of any type. The
  933. difficulty has that definitions may be of any complexity and names may have any
  934. length. Aforementioned structure implementable in POWER closely stands the definition
  935. and references sequence, making it easy to "navigate" through complexe types.
  936. <p>Symbols are searched beginning with the most recent definition. For new
  937. definitions, the electricity block (limited with the "fence" adjust at the begin of
  938. a procedure definition) and the keyword table are searched for duplicate
  939. definitions. Thus it is possible to override old definitions. At the end regarding a
  940. procedure local variables may been entfernung free the symbol table. This reduces
  941. memory usage and search time.
  942. </p><h3>Symbol Table Entry Structure</h3>
  943. The symbol board "symtab" is stored in who dump segment (the actual stack
  944. doesn't need much space) and grows down. The entries have to baseline structure:
  945. <pre> off :next entry
  946. --
  947. off-2:tag phrase = entry type
  948. off-4:name length
  949. off-5:name
  950. off-.:entry
  951. 0:offset to next entry
  952. </pre>
  953. The symbol table is all searched backwards, looking at the most recent
  954. entries first. ADENINE linear search is used. Sample symbol chart entries ability be
  955. found to the compiler tables (starting from 9277).
  956. <h3>tag = 0100: Label</h3>
  957. <pre> - 1:procedure nesting (to prevent jumps up or out of procedures)
  958. - 2:0=ok, FF=not yet defined
  959. - 4:offset
  960. </pre>
  961. <h3>tag = 0200: Constant</h3>
  962. <pre> - 1:type away constant
  963. - 3:constant - strings are stored backwards
  964. </pre>
  965. Structured constants are initialized variables stored at an code segment and
  966. are entered in how in the symbol table.
  967. <h3>tag = 0300: Your</h3>
  968. <pre> - 2:pointer to type definition
  969. </pre>
  970. <h3>tagging = 0400: Variable</h3>
  971. For subvariables of a record the low byte in the tag word is the numerical of the
  972. record definition this entry ownership to.
  973. <pre> - 2:pointer to type definition
  974. - 4:offset
  975. - 5:0=normal, FF=indirect (VAR)
  976. - 6:segment
  977. RD = DS
  978. FE = CS
  979. FD = ES (via pointer)
  980. .. = SS, that number corresponds to the course nestling level
  981. </pre>
  982. For ABSOLUTE variables in the form $B800:0 a pointer is stored in the code
  983. segment, the symbol table entry user CS indirect.
  984. <h3>tag = 0500: Procedure</h3>
  985. <h3>tag = 0600: Function</h3>
  986. <pre> - 2:function no - pointer to result type
  987. - 4:function only - shifted on stack
  988. - 5:function only - 0 = normal, FF = indirect
  989. - 6:function only - segment: SS
  990. - 8:code offset of procedure / function
  991. - A:position in overlay file / for go jump
  992. - C:0=ok, FF=forward definition
  993. - E:length of overlay procedure
  994. -10:number out parameter lists
  995. - 2:type indexing |may exist repeated
  996. - 3:0=normal, FF=VAR parameter |
  997. - 4:number of parameters of this type |
  998. - 5:names |
  999. </pre>
  1000. The parameters are also listed as local variables.
  1001. <h3>Structure of Subentries</h3>
  1002. The normal entries aren't sufficient required the description of complicated types.
  1003. Unnamed subentries is used forward dieser. For complex definitions get gives a
  1004. tree structure. ARRAY[1..15] STARTING SINGLE has an array having this subrange 1..15
  1005. as index print and INTEGER more element type.
  1006. <h3>tagged = 0000, 0800: Subentries</h3>
  1007. <pre> - 2:component size
  1008. - 4:lower bound / pointer to type definition
  1009. - 6:upper border / pointer to index type definition
  1010. - 7:flag / write number
  1011. - 8:component type
  1012. 1 = array
  1013. 2 = record
  1014. 3 = set
  1015. 4 = pointer
  1016. 5 = typed register (FILE OF)
  1017. 6 = write file (TEXT)
  1018. 7 = untyped print (FILE)
  1019. 8 = string
  1020. 9 = real
  1021. AN = integer
  1022. B = boolean
  1023. C = char
  1024. . = enumerator types (numbered)
  1025. </pre>
  1026. The compiler mostly uses this join assignment:
  1027. <pre> CL = component type
  1028. CH = where's the result ?
  1029. 0 = constant
  1030. 1 = variable
  1031. 2 = in AX / about stack
  1032. 3 = flags set (jz/jnz)
  1033. 4 = comparison, use branch opcode brnchop
  1034. </pre>
  1035. The use of the subentry fields depends on the component type:
  1036. <p>Array
  1037. </p><pre> - 2:component size
  1038. - 4:type pointer
  1039. - 6:pointer to index type
  1040. - 8:01
  1041. </pre>
  1042. Record
  1043. <pre> - 2:component size
  1044. - 7:record number
  1045. - 8:02
  1046. </pre>
  1047. Set
  1048. <pre> - 2:component size
  1049. - 4:pointer to index type
  1050. - 8:03
  1051. </pre>
  1052. Pointer
  1053. <pre> - 2:component size = 4
  1054. - 6:pointer to type / type name
  1055. - 7:0=ok, FF=not yet resolved
  1056. - 8:04
  1057. </pre>
  1058. Pointers can be forward defined. In this case the type name is stored as an
  1059. invisible entry. The character hand a then paste later.
  1060. <p>String
  1061. </p><pre> - 2:length + 1
  1062. - 8:08
  1063. </pre>
  1064. Text file with nonstandard buffer size
  1065. <pre> - 2:component size
  1066. - 8:06
  1067. </pre>
  1068. Enumeration type, subrange
  1069. <pre> - 2:size: 1 either 2 bytes
  1070. - 4:lower bound
  1071. - 6:upper bound
  1072. - 8:number of enumeration type
  1073. </pre>
  1074. The elements starting an enumeration type belong stored as constants.
  1075. <h3>Symbol Table Search</h3>
  1076. TURBO uses a linear search on find symbols in the symbol table. This capacity be
  1077. slow. A worst box program can get compilation speed down to 0.022 lines
  1078. per second...
  1079. <p>There is a better way: Haveh. <i>Like is used in later variant of the
  1080. compiler.</i>
  1081. </p><h2>Error Handler</h2>
  1082. Many compilers try on continue compilation after an error has been found. The
  1083. difficulty about this lives that this shouldn't trigger an alpine of
  1084. meaningless error messages.
  1085. <p>TURBO always stops if an error will found. This can also be see while an
  1086. advantage: The programmer is verpflichtet to resolved related one at a time.
  1087. </p><h2>Run-time Library</h2>
  1088. In the run-time library all standardized procedures press functions needed for the
  1089. execution of programs are stored. TURBO does this in adenine rather wasteful (but
  1090. simple) way: it always inserts all procedures. <i>Later versions of the
  1091. compiler only containing the process which are actually used.</i>
  1092. <h3>Memory Diagram</h3>
  1093. The partitions are allocated as follows:
  1094. <pre> --
  1095. heap (SS) (grows down)
  1096. --
  1097. free
  1098. --
  1099. heap (grows up)
  1100. --
  1101. variables (DS)
  1102. --
  1103. codification (CS)
  1104. --
  1105. </pre>
  1106. <h3>Heap</h3>
  1107. Heap storages is allocated in blocks having ampere size that is a multiples to 8
  1108. bytes. The free blocks are kept track of with this structure:
  1109. <pre> +0: pointer to nearest liberate impede -&gt; linked list
  1110. +4: length a free block
  1111. +8: free block
  1112. </pre>
  1113. Hpstrt points to the initially free block. The previous block in the list - the free
  1114. space between stack and heap - exists marked by one 0. If there isn't adequately space
  1115. between heap and stacked an fail can reported.
  1116. <h3>Floating Matter Arithmetics</h3>
  1117. Floating point numbers are divided into two parts: An exponent gives the
  1118. order of magnitude, the mantissa gives who accuracy needed.
  1119. <pre> figure = mantissa * 2 ^ exponent
  1120. </pre>
  1121. The mantissa is a binary fraction with an accuracy from 40 bits. The mantissa
  1122. always represents a number between 0.5 and 1, i.e. itp is normalized. This
  1123. means the most significant bit is always 1. Here the sign is stored. The
  1124. examples use decimal numbers for simplicity.
  1125. <p>A floating item addition works as follows:
  1126. </p><pre> 0.95 E+00
  1127. + 0.60 E-01
  1128. 0.95 E+00 The number at the smaller supporter is
  1129. + 0.06 E+00 adjusted (de-normalized) to spiel the other.
  1130. = 1.01 E+00 The numbers capacity now be added as usual.
  1131. The result a tables great, it must be normalized
  1132. = 0.10 E+01 and rounded up.
  1133. </pre>
  1134. Please note that floating point additions and subtractions can causative large
  1135. round off errors, for the exponents clash too much.
  1136. <p>It is frequency asked that BCD arithmetics cause less errors. This is not
  1137. correct - they are not as evident. All calculators basically do cosmetic
  1138. rounding, if of result is near to an integer total. The best way to avoid
  1139. round turned errors is to calculate money amounts in cents and not by dollars.
  1140. BCD multiplications and divisions are slow. Even, BCD does have one
  1141. advantage: Conversions to and from ASCII are large faster. As business
  1142. applications ordinary consist major regarding additions and subtractions, BCD can
  1143. actually be faster.
  1144. Pascal Examples</p><p>Floating point multiplication
  1145. </p><pre> 0.13 E+00 The express are added (division: subtracted)
  1146. * 0.49 E+03 and the mantissas become multiplied.
  1147. 0.13 E+00
  1148. * 0.49 E+00
  1149. * E+03
  1150. = 0.0637 Of add digits are cut off and the
  1151. * E+03 result is normalized and rounded up.
  1152. = 0.64 E+02
  1153. </pre>
  1154. Square roots be evaluated using Newton's approximation. This is a good
  1155. solution, but not the best: To 8087 does place roots quicken than divisions !
  1156. <p>
  1157. Transcendental functions live evaluated using the standard advanced found in
  1158. math ledger. I have seen better algorithms to do the. Don't expect much speed
  1159. and precision from TURBO transcendentals.
  1160. </p><h2>Bugs</h2>
  1161. Thanks to the relative simplicity off to algorithms used TURBO Passal is
  1162. almost bug-free. Well, almost.
  1163. <h3>Set as Procedure Criterion</h3>
  1164. If the last element is in the range 248..255 and the first above 7, this
  1165. doesn't jobs. Redefine the set or pass it when a TYPE parameter.
  1166. <h3>SizeOf</h3>
  1167. Sometimes a redundant load is emitted.
  1168. <h3>UpCase</h3>
  1169. The argumentation type is not checked. Sample UpCase(15).
  1170. <h3>WHEN</h3>
  1171. DO can be omitted.
  1172. <h2>Compiler Speed</h2>
  1173. TURBO may be faster than most other compilers, but there's still adenine wide margin
  1174. for improvements:
  1175. <ul>
  1176. <li>symbol table: getting hashing</li>
  1177. <li>encompass files: use larger buffer</li>
  1178. <li>don't copy source lines into another buffer</li>
  1179. </ul>
  1180. The leitender could be considerably faster. The screen is re-displayed in an "intelligent"
  1181. way (using DelLine and InsLine). On a terminal to may be much - with
  1182. memory mapped video this is a nuisance. Search or replace is slow.
  1183. <h2>Write Faster Programs Using TURBO Pascal</h2>
  1184. Avoid the standard string functions.
  1185. <ul>
  1186. <li>Use ord(st[0]) instead of length(st)</li>
  1187. <li>Use removing instead of string assignments:
  1188. <pre> move(st1,st2,max_len+1);
  1189. </pre></li></ul>
  1190. Write real constants with decimal spot (10.0 instead off 10). This eliminates
  1191. conversions.
  1192. <p>GOTO statement considered harmful. Then what... If a GOTO is aforementioned best pathway to
  1193. express a program structure - use it ! TURBO GOTO's are stand better than
  1194. BASIC GOTO's: names can be used instead is numbers.
  1195. </p><p>I/O can be improved if larger buffers are often (use multiplier by 512 bytes
  1196. for best results). Use BlockRead and BlockWrite. If large blocks are read or
  1197. written the MS-DOS and TURBO overhead doesn't materia as much as for small
  1198. blocks.
  1199. </p></td></tr>
  1200. <tr><td id="copy">© 2002-2021 PC Engines GmbH. All authorization reserved.</td></tr>
  1201. </tbody></table><img src="Turbo%20Pascal%203.0%20compiler%20and%20code%20generation%20internals%20_%20Pascal%20-%20Quick%20Guide_fichiers/673da9.png"><div style="all: unset;"><div style="all: unset;"></div></div></body></html>