ILABELS.PAS 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. (* programme comment‚ et expliqu‚ dans le livre *)
  2. (* LE DESASSEMBLEUR 8086 COLIBRI, publi‚ par *)
  3. (* L'INSTITUT PASCAL: *)
  4. (* 26 Rue Lamartine, 75009 PARIS *)
  5. (* Tel: (1) 42.85.10.82 *)
  6. procedure ouvre_fichier_labels;
  7. begin
  8. b_fichier_labels_ouvert:= true;
  9. (*$i-*)
  10. assign(fichier_labels, nom_fichier_labels);
  11. reset(fichier_labels);
  12. (*$i+*)
  13. if ioresult<> 0
  14. then begin
  15. write('pas de fichier ', nom_fichier_labels, ' Cr‚er ? ');
  16. choix1:= f_lis_commande(['C', 'Q']);
  17. if choix1= 'C'
  18. then begin
  19. assign(fichier_labels, nom_fichier_labels);
  20. rewrite(fichier_labels);
  21. end
  22. else b_fichier_labels_ouvert:= false;
  23. end
  24. else writeln('a ouvert le fichier ', nom_fichier_labels);
  25. end;
  26. procedure ajoute_fin_fichier_labels(p_adresse: integer; p_type_label: t_type_label);
  27. begin
  28. if not b_fichier_labels_ouvert
  29. then exit;
  30. fiche_label.adresse:= p_adresse;
  31. fiche_label.type_label:= p_type_label;
  32. fiche_label.nom:= '';
  33. seek(fichier_labels, filesize(fichier_labels));
  34. write(fichier_labels, fiche_label);
  35. end;
  36. procedure modifie_type_fiche_labels(p_numero_fiche: integer; p_type_label: t_type_label);
  37. var l_fiche_label: t_fiche_label;
  38. begin
  39. if not b_fichier_labels_ouvert
  40. then exit;
  41. seek(fichier_labels, p_numero_fiche);
  42. read(fichier_labels, l_fiche_label);
  43. l_fiche_label.type_label:= p_type_label;
  44. seek(fichier_labels, p_numero_fiche);
  45. write(fichier_labels, l_fiche_label);
  46. end;
  47. procedure modifie_fiche_labels(p_numero_fiche: integer;
  48. p_nom: string15; p_type_label: t_type_label);
  49. var l_fiche_label: t_fiche_label;
  50. begin
  51. if not b_fichier_labels_ouvert
  52. then exit;
  53. seek(fichier_labels, p_numero_fiche);
  54. read(fichier_labels, l_fiche_label);
  55. l_fiche_label.nom:= p_nom;
  56. l_fiche_label.type_label:= p_type_label;
  57. seek(fichier_labels, p_numero_fiche);
  58. write(fichier_labels, l_fiche_label);
  59. end;
  60. function f_normalise_label(p_nom: string15): string15;
  61. var l_indice: integer;
  62. begin
  63. for l_indice:= length(p_nom)+ 1 to 15 do
  64. p_nom:= concat(p_nom, ' ');
  65. f_normalise_label:= p_nom;
  66. end;
  67. procedure ajoute_reference(p_pointeur: t_pointeur_label);
  68. var l_pt_auxiliaire: t_pointeur_reference;
  69. begin
  70. new(l_pt_auxiliaire);
  71. l_pt_auxiliaire^.adresse:= adresse_debut_ligne;
  72. l_pt_auxiliaire^.suivante:= nil;
  73. if p_pointeur^.pt_reference= nil
  74. then
  75. p_pointeur^.pt_reference:= l_pt_auxiliaire
  76. else
  77. p_pointeur^.pt_derniere_reference^.suivante:= l_pt_auxiliaire;
  78. p_pointeur^.pt_derniere_reference:= l_pt_auxiliaire;
  79. end;
  80. function f_construis_label(p_adresse: integer; p_type_label: t_type_label): string15;
  81. var l_label: string15;
  82. begin
  83. l_label:= concat('C__', f_entier_hexadecimal(p_adresse), ' ');
  84. case p_type_label of
  85. call_valide_instruction : l_label[2]:= 'i';
  86. call_valide : ;
  87. call_instruction : begin
  88. l_label[1]:= 'c';
  89. l_label[2]:= 'i';
  90. end;
  91. call : l_label[1]:= 'c';
  92. relatif_instruction : begin
  93. l_label[1]:= 'r';
  94. l_label[2]:= 'i';
  95. end;
  96. relatif : l_label[1]:= 'r';
  97. end;
  98. f_construis_label:= l_label;
  99. end;
  100. function f_ajoute_label_call(p_adresse: integer): string15;
  101. var l_type_label: t_type_label;
  102. procedure teste_apres_ret_jmp;
  103. var l_indice_tampon: integer;
  104. begin
  105. l_indice_tampon:= p_adresse- adresse_debut_tampon;
  106. if (l_indice_tampon- 3> 0) and (l_indice_tampon< $7FFF)
  107. then
  108. if (tampon[l_indice_tampon- 1]= $C3)
  109. or (tampon[l_indice_tampon- 2]= $EB)
  110. or (tampon[l_indice_tampon- 3]= $E9)
  111. or (tampon[l_indice_tampon- 3]= $C2)
  112. then l_type_label:= call_valide
  113. else l_type_label:= call
  114. else l_type_label:= call;
  115. end;
  116. procedure ajoute_label(var pv_pointeur: t_pointeur_label);
  117. procedure modifie_label_deja_entre;
  118. var l_mettre_a_jour: boolean;
  119. begin
  120. l_mettre_a_jour:= false;
  121. if pv_pointeur^.type_label in [relatif_instruction, relatif]
  122. then begin
  123. if pv_pointeur^.type_label= relatif_instruction
  124. then
  125. if l_type_label= call_valide
  126. then l_type_label:= call_valide_instruction
  127. else l_type_label:= call_instruction;
  128. l_mettre_a_jour:= true;
  129. end
  130. else
  131. if (l_type_label= call_valide)
  132. and (pv_pointeur^.type_label= call_instruction)
  133. then begin
  134. l_type_label:= call_valide_instruction;
  135. l_mettre_a_jour:= true;
  136. end;
  137. if l_mettre_a_jour
  138. then begin
  139. if pv_pointeur^.numero_fiche= -1
  140. then begin
  141. pv_pointeur^.numero_fiche:= filesize(fichier_labels);
  142. ajoute_fin_fichier_labels(p_adresse, l_type_label);
  143. end
  144. else modifie_type_fiche_labels(pv_pointeur^.numero_fiche, l_type_label);
  145. pv_pointeur^.type_label:= l_type_label;
  146. end;
  147. end;
  148. begin
  149. if pv_pointeur= nil
  150. then begin
  151. new(pv_pointeur);
  152. pv_pointeur^.adresse:= p_adresse;
  153. pv_pointeur^.type_label:= l_type_label;
  154. pv_pointeur^.nom:= nil;
  155. pv_pointeur^.numero_fiche:= filesize(fichier_labels);
  156. pv_pointeur^.pt_labels_inferieurs:= nil; pv_pointeur^.pt_labels_superieurs:= nil;
  157. pv_pointeur^.pt_reference:= nil;
  158. if b_reference_label
  159. then ajoute_reference(pv_pointeur);
  160. ajoute_fin_fichier_labels(p_adresse, l_type_label);
  161. f_ajoute_label_call:= f_construis_label(p_adresse, l_type_label);
  162. end
  163. else
  164. if p_adresse< pv_pointeur^.adresse
  165. then ajoute_label(pv_pointeur^.pt_labels_inferieurs)
  166. else
  167. if p_adresse> pv_pointeur^.adresse
  168. then ajoute_label(pv_pointeur^.pt_labels_superieurs)
  169. else begin
  170. if b_reference_label
  171. then ajoute_reference(pv_pointeur);
  172. if pv_pointeur^.nom= nil
  173. then begin
  174. modifie_label_deja_entre;
  175. f_ajoute_label_call:= f_construis_label(p_adresse,
  176. pv_pointeur^.type_label);
  177. end
  178. else f_ajoute_label_call:= f_normalise_label(pv_pointeur^.nom^);
  179. end;
  180. end;
  181. begin
  182. teste_apres_ret_jmp;
  183. ajoute_label(racine_label);
  184. end;
  185. function f_ajoute_label_relatif(p_adresse: integer): string15;
  186. procedure ajoute_label(var pv_pointeur: t_pointeur_label);
  187. begin
  188. if pv_pointeur= nil
  189. then begin
  190. new(pv_pointeur);
  191. pv_pointeur^.adresse:= p_adresse;
  192. pv_pointeur^.type_label:= relatif;
  193. pv_pointeur^.nom:= nil;
  194. pv_pointeur^.numero_fiche:= -1;
  195. pv_pointeur^.pt_labels_inferieurs:= nil; pv_pointeur^.pt_labels_superieurs:= nil;
  196. pv_pointeur^.pt_reference:= nil;
  197. if b_reference_label
  198. then ajoute_reference(pv_pointeur);
  199. f_ajoute_label_relatif:= f_construis_label(p_adresse, relatif);
  200. end
  201. else
  202. if p_adresse< pv_pointeur^.adresse
  203. then ajoute_label(pv_pointeur^.pt_labels_inferieurs)
  204. else
  205. if p_adresse> pv_pointeur^.adresse
  206. then ajoute_label(pv_pointeur^.pt_labels_superieurs)
  207. else begin
  208. if b_reference_label
  209. then ajoute_reference(pv_pointeur);
  210. if pv_pointeur^.nom= nil
  211. then f_ajoute_label_relatif:=
  212. f_construis_label(p_adresse,
  213. pv_pointeur^.type_label)
  214. else f_ajoute_label_relatif:= f_normalise_label(pv_pointeur^.nom^);
  215. end;
  216. end;
  217. begin
  218. ajoute_label(racine_label);
  219. end;
  220. function f_label_debut_ligne(p_adresse: integer): string15;
  221. var l_pt_courant: t_pointeur_label;
  222. procedure modifie_label_deja_entre;
  223. begin
  224. case l_pt_courant^.type_label of
  225. call_valide : begin
  226. l_pt_courant^.type_label:= call_valide_instruction;
  227. modifie_type_fiche_labels(l_pt_courant^.numero_fiche,
  228. call_valide_instruction);
  229. end;
  230. call : begin
  231. l_pt_courant^.type_label:= call_instruction;
  232. modifie_type_fiche_labels(l_pt_courant^.numero_fiche,
  233. call_instruction);
  234. end;
  235. relatif : begin
  236. l_pt_courant^.type_label:= relatif_instruction;
  237. ajoute_fin_fichier_labels(p_adresse, relatif_instruction);
  238. end;
  239. end;
  240. end;
  241. begin
  242. l_pt_courant:= racine_label;
  243. while (l_pt_courant<> nil) and (l_pt_courant^.adresse<> p_adresse) do
  244. if p_adresse< l_pt_courant^.adresse
  245. then l_pt_courant:= l_pt_courant^.pt_labels_inferieurs
  246. else
  247. if p_adresse> l_pt_courant^.adresse
  248. then l_pt_courant:= l_pt_courant^.pt_labels_superieurs;
  249. if l_pt_courant= nil
  250. then begin
  251. f_label_debut_ligne:= ' '
  252. end
  253. else begin
  254. if l_pt_courant^.nom= nil
  255. then begin
  256. modifie_label_deja_entre;
  257. f_label_debut_ligne:= f_construis_label(p_adresse,
  258. l_pt_courant^.type_label);
  259. end
  260. else
  261. f_label_debut_ligne:= f_normalise_label(l_pt_courant^.nom^);
  262. end;
  263. end;
  264. procedure ajoute_label_donnees(p_adresse: integer;
  265. var pv_pointeur: t_pointeur_label;
  266. p_ajoute_reference: boolean;
  267. var pv_nom: string15;
  268. p_octet_mot: t_octet_mot);
  269. procedure ajoute(var pv_pointeur: t_pointeur_label);
  270. begin
  271. if pv_pointeur= nil
  272. then begin
  273. new(pv_pointeur);
  274. pv_pointeur^.adresse:= p_adresse;
  275. pv_pointeur^.type_label:= utilisateur_donnee;
  276. pv_pointeur^.nom:= nil;
  277. pv_pointeur^.numero_fiche:= -1;
  278. pv_pointeur^.pt_labels_inferieurs:= nil; pv_pointeur^.pt_labels_superieurs:= nil;
  279. pv_pointeur^.pt_reference:= nil;
  280. if p_ajoute_reference
  281. then ajoute_reference(pv_pointeur);
  282. if p_octet_mot= octet
  283. then pv_nom:= concat('$', f_octet_hexadecimal(p_adresse))
  284. else pv_nom:= concat('$', f_entier_hexadecimal(p_adresse));
  285. end
  286. else
  287. if p_adresse< pv_pointeur^.adresse
  288. then ajoute(pv_pointeur^.pt_labels_inferieurs)
  289. else
  290. if p_adresse> pv_pointeur^.adresse
  291. then ajoute(pv_pointeur^.pt_labels_superieurs)
  292. else begin
  293. if pv_pointeur^.nom<> nil
  294. then pv_nom:= pv_pointeur^.nom^
  295. else
  296. if p_octet_mot= octet
  297. then pv_nom:= concat('$', f_octet_hexadecimal(p_adresse))
  298. else pv_nom:= concat('$', f_entier_hexadecimal(p_adresse));
  299. if p_ajoute_reference
  300. then ajoute_reference(pv_pointeur);
  301. end;
  302. end;
  303. begin
  304. ajoute(pv_pointeur);
  305. end;
  306. procedure charge_fichier_labels;
  307. var l_label_minimum, l_label_maximum: integer;
  308. l_choix: char;
  309. procedure charge_labels;
  310. var l_numero_fiche, l_nombre_fiches_chargees, adresse: integer;
  311. procedure ajoute_label(var pv_pointeur: t_pointeur_label);
  312. procedure traite_deja;
  313. begin
  314. if pv_pointeur^.nom<> nil
  315. then begin
  316. if (fiche_label.nom<> pv_pointeur^.nom^)
  317. then begin
  318. with pv_pointeur^ do
  319. write(numero_fiche:4, nom^, ' et ');
  320. write(l_numero_fiche:4, fiche_label.nom, ' incoh‚rents');;
  321. stop; writeln; exit;
  322. end;
  323. end
  324. else
  325. if fiche_label.nom<> ''
  326. then begin
  327. new(pv_pointeur^.nom);
  328. with pv_pointeur^ do
  329. begin
  330. nom^:= fiche_label.nom;
  331. modifie_fiche_labels(numero_fiche, nom^, type_label);
  332. end;
  333. end;
  334. if fiche_label.type_label> pv_pointeur^.type_label
  335. then
  336. with pv_pointeur^ do
  337. begin
  338. type_label:= fiche_label.type_label;
  339. modifie_type_fiche_labels(numero_fiche, type_label);
  340. end;
  341. modifie_type_fiche_labels(l_numero_fiche, deja);
  342. end;
  343. begin
  344. if pv_pointeur= nil
  345. then begin
  346. new(pv_pointeur);
  347. with pv_pointeur^ do
  348. begin
  349. adresse:= fiche_label.adresse;
  350. numero_fiche:= l_numero_fiche;
  351. type_label:= fiche_label.type_label;
  352. if fiche_label.nom= ''
  353. then nom:= nil
  354. else begin
  355. new(nom);
  356. nom^:= fiche_label.nom;
  357. end;
  358. pt_labels_inferieurs:= nil; pt_labels_superieurs:= nil;
  359. pt_reference:= nil;
  360. l_nombre_fiches_chargees:= l_nombre_fiches_chargees+ 1;
  361. end;
  362. end
  363. else
  364. if fiche_label.adresse< pv_pointeur^.adresse
  365. then ajoute_label(pv_pointeur^.pt_labels_inferieurs)
  366. else
  367. if fiche_label.adresse> pv_pointeur^.adresse
  368. then ajoute_label(pv_pointeur^.pt_labels_superieurs)
  369. else traite_deja;
  370. end;
  371. begin
  372. writeln('charge ', filesize(fichier_labels), ' fiches');
  373. seek(fichier_labels, 0);
  374. l_numero_fiche:= 0;
  375. l_nombre_fiches_chargees:= 0;
  376. while not eof(fichier_labels) do
  377. begin
  378. write('.');
  379. read(fichier_labels, fiche_label);
  380. if fiche_label.type_label<= deja
  381. then begin
  382. if (fiche_label.adresse-$8000>= l_label_minimum-$8000)
  383. and (fiche_label.adresse-$8000<= l_label_maximum- $8000)
  384. then begin
  385. if fiche_label.type_label= utilisateur_donnee
  386. then ajoute_label(racine_donnees)
  387. else
  388. if (fiche_label.type_label<= utilisateur_code)
  389. then ajoute_label(racine_label);
  390. end
  391. end;
  392. l_numero_fiche:= l_numero_fiche+ 1;
  393. end;
  394. writeln(' a charg‚: ', l_nombre_fiches_chargees);
  395. end;
  396. begin
  397. if not b_fichier_labels_ouvert
  398. then begin
  399. writeln('fichier de labels ', nom_fichier_labels, ' pas ouvert');
  400. exit;
  401. end;
  402. l_label_minimum:= $0; l_label_maximum:= $FFFF;
  403. repeat
  404. writeln;
  405. write('de $', f_entier_hexadecimal(l_label_minimum));
  406. writeln(' … $', f_entier_hexadecimal(l_label_maximum));
  407. write('Minimum, mAximum, charge laBels, Quitte ? ');
  408. l_choix:= f_lis_commande(['B', 'C', 'M', 'A', 'Q', ' ', k_return]);
  409. writeln;
  410. case l_choix of
  411. 'A' : begin
  412. writeln; write('adresse maximum: <$1234> ? $');
  413. lis_entier_hexadecimal(29, wherey, l_label_maximum);
  414. end;
  415. 'B', 'C' : charge_labels;
  416. 'M' : begin
  417. writeln; write('adresse minimum: <$5678> ? $');
  418. lis_entier_hexadecimal(29, wherey, l_label_minimum);
  419. end;
  420. end;
  421. until l_choix in ['B', 'Q', 'C'];
  422. writeln;
  423. end;
  424. procedure liste_labels;
  425. type t_liste= (tous, que_code, que_donnees, que_immediats, que_noms);
  426. procedure liste_les_labels(p_type_liste: t_liste;
  427. p1_pointeur: t_pointeur_label);
  428. procedure liste_label(p_pointeur: t_pointeur_label);
  429. procedure liste_references;
  430. var l_numero_reference: integer;
  431. l_pt_courant: t_pointeur_reference;
  432. begin
  433. l_pt_courant:= p_pointeur^.pt_reference;
  434. if l_pt_courant= nil
  435. then writeln(sortie)
  436. else begin
  437. l_numero_reference:= 0;
  438. while l_pt_courant<> nil do
  439. begin
  440. if ((l_numero_reference mod 8)= 0) and (l_numero_reference<> 0)
  441. then write(sortie, '':23);
  442. write(sortie, ' ', f_entier_hexadecimal(l_pt_courant^.adresse));
  443. l_pt_courant:= l_pt_courant^.suivante;
  444. l_numero_reference:= l_numero_reference+ 1;
  445. if l_numero_reference mod 8= 0
  446. then writeln(sortie);
  447. end;
  448. if l_numero_reference mod 8<> 0
  449. then writeln(sortie);
  450. end;
  451. end;
  452. begin
  453. if p_pointeur<> nil
  454. then begin
  455. liste_label(p_pointeur^.pt_labels_inferieurs);
  456. if (p_type_liste= tous)
  457. or ((p_type_liste= que_code) and (p1_pointeur= racine_label))
  458. or ((p_type_liste= que_donnees) and (p1_pointeur= racine_donnees))
  459. or ((p_type_liste= que_immediats) and (p1_pointeur= racine_immediat))
  460. or ((p_type_liste= que_noms) and (p_pointeur^.nom<> nil))
  461. then begin
  462. write(sortie, '$', f_entier_hexadecimal(p_pointeur^.adresse), ' ');
  463. case p_pointeur^.type_label of
  464. call_valide_instruction : write(sortie, 'Ci');
  465. call_valide : write(sortie, 'C ');
  466. call_instruction : write(sortie, 'ci');
  467. call : write(sortie, 'c ');
  468. relatif_instruction : write(sortie, 'ri');
  469. relatif : write(sortie, 'r ');
  470. utilisateur_code : write(sortie, 'uc');
  471. utilisateur_donnee : write(sortie, 'ud');
  472. else write(sortie, ' ');
  473. end;
  474. if p_pointeur^.nom= nil
  475. then write(sortie, '': 16)
  476. else write(sortie, ' ', f_normalise_label(p_pointeur^.nom^));
  477. liste_references;
  478. end;
  479. liste_label(p_pointeur^.pt_labels_superieurs);
  480. end;
  481. end;
  482. begin
  483. liste_label(p1_pointeur);
  484. end;
  485. procedure genere_equates(p_pointeur: t_pointeur_label);
  486. begin
  487. if p_pointeur<> nil
  488. then begin
  489. genere_equates(p_pointeur^.pt_labels_inferieurs);
  490. if p_pointeur^.nom<> nil
  491. then begin
  492. write(sortie, f_normalise_label(p_pointeur^.nom^));
  493. write(sortie, ' equ $');
  494. write(sortie, f_entier_hexadecimal(p_pointeur^.adresse));
  495. writeln(sortie);
  496. end;
  497. genere_equates(p_pointeur^.pt_labels_superieurs);
  498. end;
  499. end;
  500. begin
  501. writeln;
  502. writeln('liste: Tous, Code, Donn‚es, Imm‚diats, Noms');
  503. write('G‚n‚re fichier equates pour r‚assemblage ? ');
  504. choix1:= f_lis_commande(['T', 'C', 'D', 'I', 'G', 'N', 'Q', ' ']);
  505. writeln(sortie);
  506. case choix1 of
  507. 'D' : liste_les_labels(que_donnees, racine_donnees);
  508. 'G' : genere_equates(racine_label);
  509. 'I' : liste_les_labels(que_immediats, racine_immediat);
  510. 'N' : begin
  511. liste_les_labels(que_noms, racine_label);
  512. writeln(sortie);
  513. liste_les_labels(que_noms, racine_donnees);
  514. end;
  515. 'T' : begin
  516. writeln(sortie);
  517. liste_les_labels(tous, racine_label);
  518. writeln(sortie);
  519. liste_les_labels(tous, racine_donnees);
  520. writeln(sortie);
  521. liste_les_labels(tous, racine_immediat);
  522. end;
  523. end;
  524. writeln(sortie);
  525. end;