DESASSEM.PAS 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  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. (*$r+*)
  7. (*$b-*)
  8. program desassemble;
  9. const k_return= #13;
  10. type string2= string[2];
  11. string4= string[4];
  12. string15= string[15];
  13. string21= string[41];
  14. string64= string[64];
  15. string80= string[80];
  16. string127= string[127];
  17. t_set_of_char= set of char;
  18. t_fiche_zones= record
  19. debut: integer;
  20. type_zone: char;
  21. end;
  22. t_pt_zone= ^t_cellule_zone;
  23. t_cellule_zone= record
  24. debut: integer;
  25. type_zone: char;
  26. pt_superieurs, pt_inferieurs: t_pt_zone;
  27. end;
  28. t_type_label= (call_valide_instruction, call_valide,
  29. call_instruction, call,
  30. relatif_instruction, relatif,
  31. utilisateur_code,
  32. utilisateur_donnee,
  33. deja, efface);
  34. t_fiche_label= record
  35. adresse: integer;
  36. type_label: t_type_label;
  37. nom: string15;
  38. end;
  39. t_pointeur_reference= ^t_cellule_reference;
  40. t_cellule_reference= record
  41. adresse: integer;
  42. suivante: t_pointeur_reference;
  43. end;
  44. t_pointeur_nom= ^string15;
  45. t_pointeur_label= ^t_cellule_label;
  46. t_cellule_label= record
  47. adresse: integer;
  48. type_label: t_type_label;
  49. nom: t_pointeur_nom;
  50. numero_fiche: integer;
  51. pt_labels_inferieurs, pt_labels_superieurs: t_pointeur_label;
  52. pt_reference, pt_derniere_reference: t_pointeur_reference;
  53. end;
  54. t_fiche_commentaire= record
  55. adresse: integer;
  56. position_commentaire: char;
  57. commentaire: string127;
  58. end;
  59. t_pt_commentaire= ^t_cellule_commentaire;
  60. t_cellule_commentaire= record
  61. adresse: integer;
  62. position_commentaire: char;
  63. numero_fiche: integer;
  64. pt_superieurs, pt_inferieurs: t_pt_commentaire;
  65. end;
  66. t_octet_mot= (octet, mot);
  67. var choix, choix1: char;
  68. nom_fichier_objet: string64;
  69. a_charge_objet: boolean;
  70. adresse_debut, adresse_fin: integer;
  71. tampon: array[$0..$7FFF] of byte;
  72. adresse_debut_tampon, adresse_fin_tampon: integer;
  73. adresse: integer;
  74. numero_ligne: integer;
  75. fichier_zones: file of t_fiche_zones;
  76. nom_fichier_zones: string64;
  77. fiche_zone: t_fiche_zones;
  78. b_fichier_zones_ouvert: boolean;
  79. racine_zone: t_pt_zone;
  80. fichier_labels: file of t_fiche_label;
  81. nom_fichier_labels: string64;
  82. fiche_label: t_fiche_label;
  83. b_fichier_labels_ouvert: boolean;
  84. racine_label, racine_donnees, racine_immediat: t_pointeur_label;
  85. fichier_commentaires: file of t_fiche_commentaire;
  86. nom_fichier_commentaires: string64;
  87. fiche_commentaire: t_fiche_commentaire;
  88. b_fichier_commentaires_ouvert: boolean;
  89. racine_commentaire: t_pt_commentaire;
  90. adresse_debut_ligne: integer;
  91. nom_debut_ligne: string15;
  92. b_reference_label: boolean;
  93. b_reference_donnees: boolean;
  94. b_reference_immediat: boolean;
  95. b_stop_ecran: boolean;
  96. b_avec_octets_hexadecimaux: boolean;
  97. sortie: text;
  98. nom_sortie: string64;
  99. (*$i iutilita.pas *)
  100. (*$i iobjet.pas *)
  101. (*$i izones.pas *)
  102. (*$i ilabels.pas *)
  103. (*$i icomment.pas *)
  104. (*$i igenere.pas *)
  105. (*$i icode1.pas *)
  106. (*$i icode2.pas *)
  107. (*$i icode3.pas *)
  108. (*$i iasciihe.pas *)
  109. procedure entre_options;
  110. begin
  111. writeln;
  112. writeln('liste de r‚f‚rences: Code, Donn‚es, Imm‚diats');
  113. writeln('Stoppe affichage toutes les 25 lignes');
  114. writeln('avec octets Hex, ');
  115. write ('Quitte ? ');
  116. choix1:= f_lis_commande(['B', 'C', 'D', 'H', 'I', 'Q', 'S', 'Z']);
  117. case choix1 of
  118. 'C' : lis_booleen('liste de r‚f‚rence des labels', b_reference_label);
  119. 'D' : lis_booleen('liste de r‚f‚rence des donn‚es', b_reference_donnees);
  120. 'H' : lis_booleen('avec affichage des octets ', b_avec_octets_hexadecimaux);
  121. 'I' : lis_booleen('liste de r‚f‚rence des imm‚diats', b_reference_immediat);
  122. 'S' : lis_booleen('stop ‚cran', b_stop_ecran);
  123. end;
  124. end;
  125. procedure entre_noms_fichiers;
  126. begin
  127. writeln;
  128. write('nom: Code objet, Labels, Zones, ommenTaires ? ');
  129. choix1:= f_lis_commande(['C', 'L', 'T', 'Q', 'Z']);
  130. case choix1 of
  131. 'T' : begin
  132. write('nom fichier commentaires <commenta.dta> ? ');
  133. readln(nom_fichier_commentaires);
  134. close(fichier_commentaires);
  135. ouvre_fichier_commentaires;
  136. end;
  137. 'L' : begin
  138. write('nom fichier labels <labels.dta> ? ');
  139. readln(nom_fichier_labels);
  140. close(fichier_labels);
  141. ouvre_fichier_labels;
  142. end;
  143. 'C' : begin
  144. write('nom fichier objet <obj.com> ? ');
  145. readln(nom_fichier_objet);
  146. end;
  147. 'Z' : begin
  148. write('nom fichier zones <zones.dta> ? ');
  149. readln(nom_fichier_zones);
  150. close(fichier_zones);
  151. ouvre_fichier_zones;
  152. end;
  153. end;
  154. end;
  155. procedure desassemblage_une_zone;
  156. var l_commande, l_commande_precedente: char;
  157. procedure ajoute_zone(p_type_zone: char);
  158. begin
  159. p_type_zone:= chr(ord(p_type_zone)+ 32);
  160. ajoute_fiche_zone(adresse_debut, p_type_zone);
  161. if filesize(fichier_zones)= 1
  162. then ajoute_fiche_zone(adresse_fin, p_type_zone);
  163. if adresse_fin+ 1<= adresse_fin_tampon
  164. then begin
  165. adresse_debut:= adresse_fin+ 1;
  166. adresse_fin:= adresse_fin+ 1;
  167. end;
  168. end;
  169. begin
  170. numero_ligne:= 0;
  171. if adresse_debut<> 0
  172. then begin
  173. writeln;
  174. writeln('entrer les adresses r‚elles <$876B> ');
  175. writeln;
  176. end;
  177. l_commande_precedente:= ' ';
  178. repeat
  179. entre_debut_fin('Code, Ascii, Hex, ajoute Zones, Quitte ');
  180. l_commande:= f_lis_commande(['C', 'A', 'H', 'Z', ' ', k_return, 'Q']);
  181. case l_commande of
  182. 'A' : desassemble_ascii(adresse_debut, adresse_fin);
  183. 'C' : desassemble_code(adresse_debut, adresse_fin);
  184. 'Z' : if l_commande_precedente in ['C', 'A', 'H']
  185. then ajoute_zone(l_commande_precedente);
  186. 'H' : desassemble_hex(adresse_debut, adresse_fin);
  187. end;
  188. if l_commande in ['A', 'C', 'H']
  189. then begin
  190. l_commande_precedente:= l_commande;
  191. write('Ajouter cette plage au fichier zones ? ');
  192. read(kbd, choix1); writeln(choix1);
  193. if upcase(choix1)= 'A'
  194. then ajoute_zone(l_commande);
  195. end;
  196. l_commande_precedente:= l_commande;
  197. until l_commande= 'Q';
  198. end;
  199. procedure desassemblage_automatique;
  200. var l_stop_ecran: boolean;
  201. procedure desassemble_les_zones;
  202. var l_debut_precedent: integer;
  203. l_type_zone_precedent: char;
  204. l_premiere_adresse: boolean;
  205. procedure desassemble_la_zone(p_adresse_debut, p_adresse_fin: integer;
  206. p_type_zone: char);
  207. begin
  208. case p_type_zone of
  209. 'a' : desassemble_ascii(p_adresse_debut, p_adresse_fin);
  210. 'c' : desassemble_code(p_adresse_debut, p_adresse_fin);
  211. 'h' : desassemble_hex(p_adresse_debut, p_adresse_fin);
  212. end;
  213. end;
  214. procedure cherche_et_desassemble(p_pt_zone: t_pt_zone);
  215. begin
  216. if p_pt_zone<> nil
  217. then begin
  218. cherche_et_desassemble(p_pt_zone^.pt_inferieurs);
  219. with p_pt_zone^ do
  220. begin
  221. if (debut- $8000>= adresse_debut- $8000)
  222. and (debut- 1- $8000<= adresse_fin- $8000)
  223. then begin
  224. if l_premiere_adresse
  225. then l_premiere_adresse:= false
  226. else desassemble_la_zone(l_debut_precedent, debut- 1,
  227. l_type_zone_precedent);
  228. l_debut_precedent:= debut;
  229. l_type_zone_precedent:= type_zone;
  230. end;
  231. end;
  232. cherche_et_desassemble(p_pt_zone^.pt_superieurs);
  233. end;
  234. end;
  235. begin
  236. l_premiere_adresse:= true;
  237. cherche_et_desassemble(racine_zone);
  238. if l_debut_precedent- 1- $8000<= adresse_fin- $8000
  239. then desassemble_la_zone(l_debut_precedent, adresse_fin,
  240. l_type_zone_precedent);
  241. end;
  242. begin
  243. if not b_fichier_zones_ouvert and (racine_zone= nil)
  244. then begin
  245. writeln('le fichier ', nom_fichier_zones, ' n''est pas ouvert ',
  246. 'ou pas charg‚');
  247. exit;
  248. end;
  249. numero_ligne:= 0;
  250. l_stop_ecran:= b_stop_ecran;
  251. b_stop_ecran:= false;
  252. entre_debut_fin('');
  253. desassemble_les_zones;
  254. b_stop_ecran:= l_stop_ecran;
  255. end;
  256. procedure desassemble_manuel;
  257. var l_adresse_debut, l_adresse_fin: integer;
  258. l_instruction: string80;
  259. l_chaine2: string2;
  260. l_indice: integer;
  261. begin
  262. writeln('entez une suite hexad‚cimale <CD11C3>');
  263. write('? '); readln(l_instruction);
  264. if odd(length(l_instruction))
  265. then l_instruction:= concat(l_instruction, '0');
  266. l_chaine2:= ' ';
  267. for l_indice:= 0 to length(l_instruction) div 2- 1 do
  268. begin
  269. l_chaine2[1]:= l_instruction[1+ l_indice* 2];
  270. l_chaine2[2]:= l_instruction[1+ l_indice* 2+ 1];
  271. tampon[l_indice]:= f_hexadecimal_octet(l_chaine2);
  272. end;
  273. adresse_debut_tampon:= 0;
  274. l_adresse_debut:= 0;
  275. l_adresse_fin:= length(l_instruction) div 2;
  276. desassemble_code(l_adresse_debut, l_adresse_fin);
  277. end;
  278. procedure listes_diverses;
  279. begin
  280. writeln;
  281. write('liste Code objet, laBels, Zones, commenTaires, Quitte ? ');
  282. choix1:= f_lis_commande(['B', 'C', 'T', 'Z', 'Q']); writeln;
  283. case choix1 of
  284. 'B' : liste_labels;
  285. 'C' : liste_objet;
  286. 'T' : liste_arbre_commentaires(racine_commentaire);
  287. 'Z' : liste_arbre_zones;
  288. end;
  289. end;
  290. procedure initialise;
  291. begin
  292. nom_sortie:= 'con:';
  293. assign(sortie, nom_sortie);
  294. reset(sortie);
  295. nom_fichier_objet:= 'mystere.com';
  296. a_charge_objet:= false;
  297. adresse_debut:= $0100;
  298. adresse_fin:= $80FF;
  299. adresse_debut_tampon:= $0100;
  300. adresse_fin_tampon:= $80FF;
  301. numero_ligne:= 0;
  302. nom_fichier_zones:= 'zones.dta';
  303. ouvre_fichier_zones;
  304. racine_zone:= nil;
  305. nom_fichier_commentaires:= 'commenta.dta';
  306. ouvre_fichier_commentaires;
  307. racine_commentaire:= nil;
  308. nom_fichier_labels:= 'labels.dta';
  309. ouvre_fichier_labels;
  310. racine_label:= nil;
  311. racine_donnees:= nil;
  312. racine_immediat:= nil;
  313. b_reference_donnees:= false;
  314. b_reference_immediat:= false;
  315. b_reference_label:= true;
  316. b_stop_ecran:= false;
  317. b_avec_octets_hexadecimaux:= true;
  318. end;
  319. begin
  320. initialise;
  321. repeat
  322. writeln;
  323. write(nom_fichier_objet, ' $', f_entier_hexadecimal(adresse_debut_tampon));
  324. write('-$', f_entier_hexadecimal(adresse_fin_tampon));
  325. write(' : $', f_entier_hexadecimal(adresse_debut));
  326. write('-$', f_entier_hexadecimal(adresse_fin));
  327. writeln(' -> ', nom_sortie);
  328. if b_fichier_labels_ouvert
  329. then write(nom_fichier_labels, ' [0 … ', filesize(fichier_labels)- 1, '], ');
  330. if b_fichier_zones_ouvert
  331. then write(nom_fichier_zones, ' [0 … ', filesize(fichier_zones)- 1, '] ');
  332. writeln;
  333. affiche_booleen('r‚f labels', b_reference_label); write(', ');
  334. affiche_booleen('r‚f donn‚es', b_reference_donnees); write(', ');
  335. affiche_booleen('r‚f op imm‚', b_reference_immediat); write(', ');
  336. affiche_booleen('octets hex', b_avec_octets_hexadecimaux);
  337. writeln; writeln;
  338. writeln('Charge objet, laBels, Zones, commenTaires, Noms, Options');
  339. writeln('D‚sassemble, Automatique, Manuel');
  340. write ('Sortie, Listes, Quitte ? ');
  341. choix:= f_lis_commande(['A', 'B', 'C', 'D', 'L', 'M', 'N', 'O', 'Q', 'S', 'T', 'Z',
  342. ' ', k_return]);
  343. case choix of
  344. 'A' : if a_charge_objet
  345. then desassemblage_automatique
  346. else affiche_erreur('objet pas charg‚');
  347. 'B' : charge_fichier_labels;
  348. 'C' : charge_objet;
  349. 'D' : if a_charge_objet
  350. then desassemblage_une_zone
  351. else affiche_erreur('objet pas charg‚');
  352. 'L' : listes_diverses;
  353. 'N' : entre_noms_fichiers;
  354. 'M' : desassemble_manuel;
  355. 'O' : entre_options;
  356. 'S' : choisis_sortie;
  357. 'T' : charge_fichier_commentaires;
  358. 'Z' : charge_fichier_zones;
  359. end;
  360. until choix= 'Q';
  361. close(fichier_zones);
  362. close(fichier_labels);
  363. close(sortie);
  364. end.