| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796 |
- (* programme comment‚ et expliqu‚ dans le livre *)
- (* LE DESASSEMBLEUR 8086 COLIBRI, publi‚ par *)
- (* L'INSTITUT PASCAL: *)
- (* 26 Rue Lamartine, 75009 PARIS *)
- (* Tel: (1) 42.85.10.82 *)
- begin
- l_bit_mot:= l_code_operation and 1;
- l_bit_direction:= (l_code_operation and 2) shr 1;
- l_bits_registre:= l_code_operation and 7;
- l_bit_registre_mot:= (l_code_operation and 8) shr 3;
- case l_code_operation of
- $37: met('aaa ');
- $D5: begin
- met('aad');
- lis_octet_suivant(l_operande);
- if l_operande<> $0A
- then met(' ???_1');
- end;
- $D4: begin
- met('aam');
- lis_octet_suivant(l_operande);
- if l_operande<> $0A
- then met(' ???_2');
- end;
- $3F: met('aas');
- $10..$15: begin
- met('adc ');
- case l_code_operation of
- $10..$13 : traite_direction_mot;
- $14 : begin
- met('al, ');
- met_operande_un_octet;
- end;
- $15 : begin
- met('ax, ');
- met_operande_un_mot;
- end;
- end;
- end;
- $00..$05: begin
- met('add ');
- case l_code_operation of
- $00..$03 : traite_direction_mot;
- $04..$05 : traite_accumulateur_immediat;
- end;
- end;
- $20..$25: begin
- met('and ');
- case l_code_operation of
- $20..$23 : traite_direction_mot;
- $24..$25 : traite_accumulateur_immediat;
- end;
- end;
- $9A, $E8: begin
- met('call ');
- case l_code_operation of
- $9A : begin
- lis_entier_suivant(l_adresse);
- l_chaine:= f_entier_hexadecimal(l_adresse);
- lis_entier_suivant(l_adresse);
- l_chaine2:= f_entier_hexadecimal(l_adresse);
- met3(l_chaine2, ':', l_chaine);
- end;
- $E8 : begin
- lis_entier_suivant(l_adresse);
- met(f_ajoute_label_call(adresse+ l_adresse));
- end;
- end;
- end;
- $98: met('cbw');
- $F8: met('clc');
- $FC: met('cld');
- $FA: met('cli');
- $F5: met('cmc');
- $38..$3D: begin
- met('cmp ');
- case l_code_operation of
- $38..$3B: traite_direction_mot;
- $3C: begin
- traite_accumulateur_immediat;
- if l_operande in [$0..$7E]
- then affiche_caractere;
- end;
- $3D: traite_accumulateur_immediat;
- end;
- end;
- $A6: met('cmps b');
- $A7: met('cmps w');
- $99: met('cwd');
- $27: met('daa');
- $2F: met('das');
- $48..$4F: begin
- met('dec ');
- traite_fin_registre;
- end;
- $D8..$DF: begin
- met('esc ');
- lis_octet_mode;
- traite_registre(l_chaine);
- met(l_chaine);
- end;
- $F6..$F7: begin
- lis_octet_mode;
- if l_bit_mot= 0
- then begin
- case l_registre of
- 0 : begin
- met('test ');
- traite_bit_mot;
- met(', ');
- met_operande_un_octet;
- end;
- 1 : begin
- met('???_3');
- end;
- 2 : begin
- met('not ');
- traite_bit_mot;
- end;
- 3 : begin
- met('neg ');
- traite_bit_mot;
- end;
- 4 : begin
- met('mul al, ');
- traite_mode;
- end;
- 5 : begin
- met('imul al, ');
- traite_mode;
- end;
- 6 : begin
- met('div al, ');
- traite_mode;
- end;
- 7 : begin
- met('idiv al, ');
- traite_mode;
- end;
- end;
- end
- else begin
- case l_registre of
- 0 : begin
- met('test ');
- traite_bit_mot;
- met(', ');
- met_operande_un_mot;
- end;
- 1 : begin
- met('???_4');
- end;
- 2 : begin
- met('not ');
- traite_bit_mot;
- end;
- 3 : begin
- met('neg ');
- traite_bit_mot;
- end;
- 4 : begin
- met('mul ax, ');
- traite_mode;
- end;
- 5 : begin
- met('imul ax, ');
- traite_mode;
- end;
- 6 : begin
- met('div ax, ');
- traite_mode;
- end;
- 7 : begin
- met('idiv ax, ');
- traite_mode;
- end;
- end;
- end;
- end;
- $FE..$FF: begin
- lis_octet_mode;
- if l_bit_mot= 0
- then begin
- case l_registre of
- 0 : begin
- met('inc b ');
- traite_mode;
- end;
- 1 : begin
- met('dec b ');
- traite_registre(l_chaine);
- met(l_chaine);
- end;
- else begin
- met('???_5');
- end;
- end;
- end
- else begin
- case l_registre of
- 0 : begin
- met('inc w ');
- traite_mode;
- end;
- 1 : begin
- met('dec w ');
- traite_registre(l_chaine);
- met(l_chaine);
- end;
- 2 : begin
- traite_registre(l_chaine);
- met2('call ', l_chaine);
- end;
- 3 : begin
- traite_registre(l_chaine);
- met2('call ', l_chaine);
- end;
- 4 : begin
- met('jmp_ra ');
- traite_bit_mot;
- end ;
- 5 : begin
- met('jmp_er ');
- traite_bit_mot;
- end;
- 6 : begin
- met('push ');
- traite_bit_mot;
- end;
- 7 : met('???_7');
- end;
- end;
- end;
- $F4: met('hlt');
- $80..$82: begin
- lis_octet_mode;
- case l_registre of
- 0 : met('add ');
- 1 : met('or ');
- 2 : met('adc ');
- 3 : met('sbb ');
- 4 : met('and ');
- 5 : met('sub ');
- 6 : met('xor ');
- 7 : met('cmp ');
- end;
- traite_mode;
- met(', ');
- met_operande(l_bit_mot);
- end;
- $83: begin
- lis_octet_mode;
- case l_registre of
- 0 : met('add ');
- 1 : met('or ');
- 2 : met('adc ');
- 3 : met('sbb ');
- 4 : met('and ');
- 5 : met('sub ');
- 6 : met('xor ');
- 7 : met('cmp ');
- end;
- traite_mode;
- met(', ');
- met_operande(0);
- end;
- $E4..$E5,
- $EC..$ED: begin
- met('in ');
- case l_code_operation of
- $EC : met('al, dx');
- $ED : met('ax, dx');
- $E4..$E5 : traite_accumulateur_immediat;
- end;
- end;
- $40..$47: begin
- met('inc ');
- traite_fin_registre;
- end;
- $CC: met('int 3');
- $CD: begin
- met('int ');
- met_operande_un_octet;
- commente_interruption;
- end;
- $CE: met('into');
- $CF: met('iret');
- $72: begin
- met('jb ');
- met_operande_relatif_un_octet;
- end;
- $76: begin
- met('jbe ');
- met_operande_relatif_un_octet;
- end;
- $E3: begin
- met('jcxz ');
- met_operande_relatif_un_octet;
- end;
- $74: begin
- met('je ');
- met_operande_relatif_un_octet;
- end;
- $7C: begin
- met('jl ');
- met_operande_relatif_un_octet;
- end;
- $7E: begin
- met('jle ');
- met_operande_relatif_un_octet;
- end;
- $E9..$EB: begin
- if l_code_operation= $EB
- then met('jmp_s ')
- else met('jmp ');
- case l_code_operation of
- $E9 : met_operande_relatif_un_mot;
- $EA : begin
- met_operande_un_mot;
- met(':');
- met_operande_un_mot;
- end;
- $EB : begin
- met_operande_relatif_un_octet;
- end;
- end;
- end;
- $73: begin
- met('jnc ');
- met_operande_relatif_un_octet;
- end;
- $77: begin
- met('jnbe ');
- met_operande_relatif_un_octet;
- end;
- $75: begin
- met('jnz ');
- met_operande_relatif_un_octet;
- end;
- $7D: begin
- met('jnl ');
- met_operande_relatif_un_octet;
- end;
- $7F: begin
- met('jnle ');
- met_operande_relatif_un_octet;
- end;
- $71: begin
- met('jno ');
- met_operande_relatif_un_octet;
- end;
- $7B: begin
- met('jnp ');
- met_operande_relatif_un_octet;
- end;
- $79: begin
- met('jns ');
- met_operande_relatif_un_octet;
- end;
- $70: begin
- met('jo ');
- met_operande_relatif_un_octet;
- end;
- $7A: begin
- met('jp ');
- met_operande_relatif_un_octet;
- end;
- $78: begin
- met('js ');
- met_operande_relatif_un_octet;
- end;
- $9F: met('lahf ');
- $C5: begin
- met('lds ');
- lis_octet_mode;
- decode_registre(1, l_registre, l_chaine);
- met2(l_chaine, ', ');
- traite_registre(l_chaine);
- met(l_chaine);
- end;
- $8D: begin
- met('lea ');
- lis_octet_mode;
- decode_registre(1, l_registre, l_chaine);
- met2(l_chaine, ', ');
- traite_registre(l_chaine);
- met(l_chaine);
- end;
- $C4: begin
- met('les ');
- lis_octet_mode;
- decode_registre(1, l_registre, l_chaine);
- met2(l_chaine, ', ');
- traite_registre(l_chaine);
- met(l_chaine);
- end;
- $F0: met('lock');
- $AC: met('lods b');
- $AD: met('lods w');
- $E2: begin
- met('loop ');
- met_operande_relatif_un_octet;
- end;
- $E0: begin
- met('loopnz ');
- met_operande_relatif_un_octet;
- end;
- $E1: begin
- met('loopz ');
- met_operande_relatif_un_octet;
- end;
- $88..$8C, $8E,
- $A0..$A3,
- $B0..$BF,
- $C6..$C7: begin
- met('mov ');
- case l_code_operation of
- $88..$8B : begin
- traite_registre_registre_memoire;
- end;
- $8C : begin
- lis_octet_mode;
- if l_registre> 3
- then met('???_9')
- else begin
- l_bit_mot:= 1;
- traite_registre(l_chaine);
- met2(l_chaine, ', ');
- case l_registre of
- 0 : met('es');
- 1 : met('cs');
- 2 : met('ss');
- 3 : met('ds');
- end;
- end;
- end;
- $8E : begin
- lis_octet_mode;
- if l_registre> 3
- then met('???_9')
- else begin
- l_bit_mot:= 1;
- traite_registre(l_chaine);
- case l_registre of
- 0 : met('es, ');
- 1 : met('cs, ');
- 2 : met('ss, ');
- 3 : met('ds, ');
- end;
- met(l_chaine);
- end;
- end;
- $A0 : begin
- met('al, [');
- met_operande_un_mot;
- met(']');
- end;
- $A1 : begin
- met('ax, [');
- met_operande_un_mot;
- met(']');
- end;
- $A2 : begin
- met('[');
- met_operande_un_mot;
- met('], al');
- end;
- $A3 : begin
- met('[');
- met_operande_un_mot;
- met('], ax');
- end;
- $B0..$BF : begin
- decode_registre(l_bit_registre_mot, l_bits_registre, l_chaine);
- met2(l_chaine, ', ');
- met_operande(l_bit_registre_mot);
- recupere_valeur_stockee_dans_registre;
- end;
- $C6..$C7 : begin
- lis_octet_mode;
- traite_registre(l_chaine);
- met2(l_chaine, ', ');
- met_operande(l_bit_mot);
- end;
- end;
- end;
- $A4: met('movs b');
- $A5: met('movs w');
- $90: met('nop');
- $08..$0B,
- $0C..$0D: begin
- met('or ');
- case l_code_operation of
- $08..$0B : traite_direction_mot;
- $0C..$0D : traite_accumulateur_immediat;
- end;
- end;
- $E6..$E7,
- $EE..$EF: begin
- met('out ');
- case l_code_operation of
- $EE : met('dx, al');
- $EF : met('dx, ax');
- $E6..$E7 : traite_accumulateur_immediat;
- end;
- end;
- $07, $17, $1F,
- $58..$5F, $8F: begin
- met('pop ');
- case l_code_operation of
- $58..$5F : traite_fin_registre;
- $8F: begin
- lis_octet_mode;
- if l_registre<> 0
- then met('???_10')
- else begin
- traite_registre(l_chaine);
- met(l_chaine);
- end;
- end;
- $07: met('es');
- $17: met('ss');
- $1F: met('ds');
- end;
- end;
- $9D: met('popf');
- $06, $0E, $1E,
- $16, $50..$57: begin
- met('push ');
- case l_code_operation of
- $06 : met('es');
- $0E : met('cs');
- $16 : met('ss');
- $1E : met('ds');
- $50..$57: traite_fin_registre;
- end;
- end;
- $9C: met('push_f');
- $F2: met('rep');
- $F3: met('rep_z');
- $C2..$C3,
- $CA..$CB: begin
- met('ret ');
- case l_code_operation of
- $C2 : begin
- lis_entier_suivant(l_adresse);
- met2(f_entier_hexadecimal(l_adresse) , ' ; intra');
- end;
- $C3 : ;
- $CA : begin
- lis_entier_suivant(l_adresse);
- met2(f_entier_hexadecimal(l_adresse) , ' ; inter');
- end;
- $CB : met(' ; inter seg');
- end;
- end;
- $9E: met('sahf');
- $18..$1D: begin
- met('sbb ');
- case l_code_operation of
- $18..$1B : traite_direction_mot;
- $1C..$1B : traite_accumulateur_immediat;
- end;
- end;
- $AE: met('scas b');
- $AF: met('scas w');
- $26, $2E,
- $36, $3E: begin
- met('seg ');
- case l_code_operation of
- $26 : met('es');
- $2E : met('cs');
- $36 : met('ss');
- $3E : met('ds');
- end;
- end;
- $D0..$D3: begin
- lis_octet_mode;
- case l_registre of
- 0 : met('rol ');
- 1 : met('ror ');
- 2 : met('rcl ');
- 3 : met('rcr ');
- 4 : met('shl ');
- 5 : met('shr ');
- 6 : met('???_11');
- 7 : met('sar ');
- end;
- if l_registre <> 6
- then begin
- traite_registre(l_chaine);
- met(l_chaine);
- if l_bit_direction= 1
- then met(', cl')
- else met(', 1');
- end;
- end;
- $F9: met('stc');
- $FB: met('sti');
- $FD: met('std');
- $AA: met('stos b');
- $AB: met('stos w');
- $28..$2D: begin
- met('sub ');
- case l_code_operation of
- $28..$2B : traite_direction_mot;
- $2C..$2D : traite_accumulateur_immediat;
- end;
- end;
- $84..$85,
- $A8..$A9: begin
- met('test ');
- case l_code_operation of
- $84..$85 : begin
- l_bit_direction:= 1;
- traite_registre_registre_memoire;
- end;
- $A8..$A9 : traite_accumulateur_immediat;
- end;
- end;
- $9B: met('wait');
- $86..$87,
- $91..$97: begin
- met('xchg ');
- case l_code_operation of
- $86..$87 : begin
- lis_octet_mode;
- traite_registre(l_chaine);
- decode_registre(l_bit_mot, l_registre, l_chaine2);
- met3(l_chaine2, ', ', l_chaine)
- end;
- $91..$97 : traite_fin_registre;
- end;
- end;
- $D7: met('xlat');
- $30..$35: begin
- met('xor ');
- case l_code_operation of
- $30..$33: begin
- traite_direction_mot;
- if (l_code_operation= $32) and (l_chaine= l_chaine2) then
- if l_chaine= 'ah' then l_ah_precedent:= 0 else
- if l_chaine= 'al' then l_al_precedent:= 0 else
- if l_chaine= 'bl' then l_bl_precedent:= 0 else
- if l_chaine= 'bh' then l_bh_precedent:= 0 else
- if l_chaine= 'cl' then l_cl_precedent:= 0 else
- if l_chaine= 'ch' then l_ch_precedent:= 0 else
- if l_chaine= 'dl' then l_dl_precedent:= 0 else
- if l_chaine= 'dh' then l_dh_precedent:= 0;
- end;
- $34..$35: traite_accumulateur_immediat;
- end;
- end;
- $0F, $60..$6F,
- $C0..$C1,
- $C8..$C9,
- $D6, $F1:met('???_?');
- end;
- end;
- procedure affiche_debut_de_ligne;
- var l_pt_commentaire: t_pt_commentaire;
- l_commentaire: string127;
- begin
- writeln(sortie);
- if b_avec_octets_hexadecimaux
- then write(sortie, f_entier_hexadecimal(adresse_debut_ligne), ' ');
- l_pt_commentaire:= racine_commentaire;
- while l_pt_commentaire<> nil do
- begin
- cherche_commentaire(adresse_debut_ligne, 'D', l_pt_commentaire,
- l_commentaire);
- if l_commentaire<> ''
- then begin
- if b_avec_octets_hexadecimaux
- then write(sortie, '': 22);
- writeln(sortie, l_commentaire);
- if b_avec_octets_hexadecimaux
- then write(sortie, f_entier_hexadecimal(adresse_debut_ligne), ' ');
- end;
- end;
- l_pt_commentaire:= racine_commentaire;
- while l_pt_commentaire<> nil do
- begin
- cherche_commentaire(adresse_debut_ligne, 'M', l_pt_commentaire,
- l_commentaire);
- if l_commentaire<> ''
- then begin
- if b_avec_octets_hexadecimaux
- then write(sortie, '': 22);
- if nom_debut_ligne[1]<> ' '
- then begin
- write(sortie, nom_debut_ligne);
- nom_debut_ligne:= ' ';
- end
- else write(sortie, '': 15);
- writeln(sortie, ' ', l_commentaire);
- if b_avec_octets_hexadecimaux
- then write(sortie, f_entier_hexadecimal(adresse_debut_ligne), ' ');
- end;
- end;
- end;
- procedure affiche_instruction;
- var l_indice: integer;
- l_pt_commentaire: t_pt_commentaire;
- l_commentaire: string127;
- begin
- if b_avec_octets_hexadecimaux
- then begin
- for l_indice:= adresse- adresse_debut_ligne to 7 do
- write(sortie, ' ');
- write(sortie, ' ', numero_ligne:4, ' ');
- end;
- write(sortie, nom_debut_ligne, ' ', l_ligne);
- l_pt_commentaire:= racine_commentaire;
- while l_pt_commentaire<> nil do
- begin
- cherche_commentaire(adresse_debut_ligne, 'F', l_pt_commentaire,
- l_commentaire);
- if l_commentaire<> ''
- then write(sortie, l_commentaire);
- end;
- if (l_code_operation in [$C2, $C3, $CA, $CB, $E9, $EA, $EB, $CF])
- or ((l_code_operation in [$FE..$FF])
- and ((l_code_operation and $38)<> 0))
- then writeln(sortie);
- end;
- begin
- adresse:= p_adresse_debut;
- l_al_precedent:= 0;
- l_ah_precedent:= 0;
- l_ax_precedent:= 0;
- l_bl_precedent:= 0;
- l_bh_precedent:= 0;
- l_bx_precedent:= 0;
- l_cl_precedent:= 0;
- l_ch_precedent:= 0;
- l_cx_precedent:= 0;
- l_dl_precedent:= 0;
- l_dh_precedent:= 0;
- l_dx_precedent:= 0;
- while adresse<= p_adresse_fin do
- begin
- l_ligne:= '';
- adresse_debut_ligne:= adresse;
- nom_debut_ligne:= f_label_debut_ligne(adresse);
- affiche_debut_de_ligne;
- lis_octet_suivant(l_code_operation);
- decode_instruction;
- affiche_instruction;
- numero_ligne:= numero_ligne+ 1;
- if b_stop_ecran and (numero_ligne mod 20= 0)
- then begin
- read(kbd, choix1); writeln(choix1);
- if upcase(choix1)= 'Q'
- then adresse:= adresse_fin+ 1;
- end;
- end;
- writeln(sortie);
- if p_adresse_fin+ 1- adresse<> 0
- then begin
- writeln;
- write('dernier octet d‚sassembl‚: ', f_entier_hexadecimal(adresse- 1));
- writeln(' <> adresse fin: ', f_entier_hexadecimal(p_adresse_fin));
- end;
- end;
|