Desensamblador
Descripción del contenido de la página
Desensamblador de Z80 escrito en Sinclair BASIC.
Etiquetas:
Este sencillo desensamblador para ZX Spectrum pertenece al baúl de los recuerdos (y de los experimentos) de 1985, aunque su primera versión, que no conservo, es de un año antes.
Se puede definir una dirección virtual diferente de la real; y la salida puede dirigirse a la impresora.
Pantallazos
Pantalla de inicio:
Ejemplo del final del desensamblado de la ROM de la ZX Spectrum, hasta el primer comando RET
:
Código fuente
1 REM DESENSAMBLADOR
2 REM Copyright (C) 1984,1985 Marcos Cruz (http://programandala.net)
3 REM Licencia/Permesilo/License: http://programandala.net/lp
4 REM 1984-09 V.1
5 REM 1985-07 V.2
10 GO SUB VAL "500"
20 POKE VAL "23617",CODE " GO TO ": CLOSE #VAL "2": PRINT #SGN PI;"PULSA UNA TECLA": PAUSE PI-PI: CLS : INPUT "DIRECCION REAL="; LINE H$: INPUT "DIRECCION VIRTUAL="; LINE V$: IF V$="" THEN LET V$=H$
25 IF H$(SGN PI)="#" THEN LET DIR=PI-PI: FOR C=LEN H$ TO 2 STEP VAL "-1": LET DIR=DIR+(CODE H$(C)-CODE "0"-(VAL "7"*(CODE H$(C)>CODE "@")))*VAL "16"^(LEN H$-C): NEXT C: GO TO 35
30 LET DIR=VAL H$
35 IF V$(SGN PI)="#" THEN LET POS=PI-PI: FOR C=LEN V$ TO 2 STEP VAL "-1": LET POS=POS+(CODE V$(C)-CODE "0"-(VAL "7"*(CODE V$(C)>CODE "@")))*VAL "16"^(LEN V$-C): NEXT C: GO TO 50
40 LET POS=VAL V$
50 INPUT "PARAR AL ENCONTRAR RET "; LINE H$: LET RUT=H$="S": INPUT "IMPRESORA "; LINE H$: LET IMP=H$="S": IF IMP THEN OPEN #VAL "2","P"
60 POKE 23692,255: LET B=PEEK DIR: IF B=203 THEN GO TO RUTC
70 IF B=221 THEN LET P$="IX": GO TO RUTD
80 IF B=237 THEN GO TO RUTE
90 IF B=253 THEN LET P$="IX": GO TO RUTD
100 GO TO RUTN
110 IF INKEY$=" STOP " THEN LET DAT2=PI-PI: GO TO VAL "20"
120 IF INKEY$=" " THEN GO TO 120
130 LET DIR=DIR+SUM: LET POS=POS+SUM: GO TO 60
170 LET H$=""
180 LET H$=H$+A$(INT (N/16)+1)+A$(N-INT (N/16)*16+1): RETURN
190 LET N=INT (NN/256): GO SUB HEXN: LET N=NN-INT (NN/256)*256: GO SUB HEXN+10:IF DAT THEN LET DEC=NN: LET DAT2=1: LET DAT=0
195 RETURN
200 FOR L=1 TO LEN T$: IF T$(L)="/" THEN LET T$=T$( TO L-1)+"#"+H$+T$(L+1 TO ):GO TO PRINT
210 NEXT L
220 LET NN=POS: GO SUB HEXNN: LET L$=H$: LET H$="": FOR C=DIR TO DIR+SUM-1: LET N=PEEK C: GO SUB HEXN+10: NEXT C: IF IMP THEN PRINT TAB (25-LEN STR$ POS);POS;" ";
225 PRINT "#";L$;" ";H$;B$(LEN H$ TO );T$;: IF IMP AND DAT2 THEN PRINT "; ";DEC: LET DAT2=0: GO TO 228
227 PRINT
228 IF B-1=201 THEN IF RUT THEN GO TO 20
229 GO TO 110
230 LET B=B+1: IF N$(B,1)>"2" THEN LET SUM=1: LET T$=N$(B): GO TO PRINT
240 IF N$(B,1)="1" THEN LET N=PEEK (DIR+1): GO SUB HEXN: LET SUM=2: LET T$=N$(B,2 TO ): GO TO PRINTD
250 IF N$(B,1)="2" THEN LET DAT=1: LET NN=PEEK (DIR+1)+256*PEEK (DIR+2): GO SUB HEXNN: LET SUM=3: LET T$=N$(B,2 TO ): GO TO PRINTD
260 LET B=PEEK (DIR+1): LET SUM=2: IF B>191 THEN LET T$=C$(10)+CHR$ INT ((B-192)/8+48)+","+C$(19+(B-(192+INT ((B-192)/8+1)*8))): GO TO PRINT
270 IF B>127 THEN LET T$=C$(9)+CHR$ INT ((B-128)/8+48)+","+C$(19+(B-(128+INT ((B-128)/8+1)*8))): GO TO PRINT
280 IF B>63 THEN LET T$=C$(8)+CHR$ INT ((B-64)/8+48)+","+C$(19+(B-(64+INT (((B-64)/8)+1)*8))): GO TO PRINT
290 IF B>55 THEN LET T$=C$(7)+C$(19+(B-(56+INT ((B-56)/8+1)*8))): GO TO PRINT
300 IF B>39 THEN LET T$=C$(6)+C$(19+(B-(40+INT ((B-40)/8+1)*8))): GO TO PRINT
310 IF B>31 THEN LET T$=C$(5)+C$(19+(B-(32+INT ((B-32)/8+1)*8))): GO TO PRINT
320 IF B>23 THEN LET T$=C$(4)+C$(19+(B-(24+INT ((B-24)/8+1)*8))): GO TO PRINT
330 IF B>15 THEN LET T$=C$(3)+C$(19+(B-(16+INT ((B-16)/8+1)*8))): GO TO PRINT
340 IF B>7 THEN LET T$=C$(2)+C$(19+(B-(8+INT ((B-8)/8+1)*8))): GO TO PRINT
350 LET T$=C$(1)+C$(19+(B-INT ((B/8)+1)*8)): GO TO PRINT
360 LET EA=1: LET EZ=39: LET P=DIR+1: LET B=PEEK P: IF B=203 THEN LET EA=40: LET EZ=70: LET P=DIR+3
370 FOR C=EA TO EZ: IF PEEK P=D(C) THEN GO TO 390*(D(C)<>54)+790*(D(C)=54)
380 NEXT C: LET C=C-1
390 LET T$=D$(C,2 TO ): IF D$(C,1)>"2" THEN LET T$=D$(C): LET SUM=2: GO TO 420:GO TO PRINT
400 IF D$(C,1)="1" THEN LET N=PEEK (DIR+2): GO SUB HEXN: LET SUM=3+(PEEK (DIR+2)=203): GO TO 420
410 IF D$(C,1)="2" THEN LET N=PEEK (DIR+2)+256*PEEK (DIR+3): GO SUB HEXNN: LET SUM=4
420 FOR C=1 TO LEN T$: IF T$(C)="*" THEN LET T$=T$( TO C-1)+P$+T$(C+1 TO ):
430 NEXT C: GO TO PRINTD
440 LET N=PEEK (DIR+1): GO SUB HEXN: LET T$="LD ("+P$+"+"+H$+"),": LET N=PEEK (DIR+2): GO SUB HEXN: LET T$=T$+H$: GO TO PRINT
450 LET B=PEEK (DIR+1): FOR C=1 TO 54: IF E(C)=B THEN GO TO 470
460 NEXT C: LET C=C-1
470 IF E$(C,1)>"2" THEN LET T$=E$(C): GO TO PRINT
480 IF E$(C,1)="1" THEN LET T$=E$(C,2 TO ): LET SUM=3: LET N=PEEK (DIR+2): GO SUB HEXN: GO TO PRINTD
490 IF E$(C,1)="2" THEN LET DAT=1: LET T$=E$(C,2 TO ): LET SUM=4: LET NN=PEEK (DIR+2)+256*PEEK (DIR+3): GO SUB HEXNN: GO TO PRINTD
500 LET DAT=PI-PI: LET DAT2=DAT: PAPER VAL "7": BORDER VAL "7": INK PI-PI: CLS : PRINT INVERSE SGN PI;"DESENSAMBLADOR"'' INVERSE PI-PI;"POR_MARCOS_CRUZ"'"SEPTIEMBRE_DE_1984"'"JULIO_DE_1985"''"INTRODUCE_LA_DIRECCION_DE"'"COMIENZO_CON_'#'_DELANTE_SI_ES"'"H
EXADECIMAL"
510 PRINT '"ESPACIO => PAUSA"'"SYMBOL SHIFHT+A => PARAR";AT VAL "21",PI-PI; INVERSE SGN PI;"ESPERA POR FAVOR"
520 POKE VAL "23658",VAL "8": LET B$=" ": LET PRINT=CODE " BRIGHT ": LET PRINTD=CODE ">=": LET RUTE=VAL "450": LET RUTD=VAL "360": LET RUTC=VAL "260": LET RUTN=CODE " NEW ": LET HEXN=CODE "SCREEN$ ": LET HEXNN=CODE "PEEK ": LET A$="0123456789ABCDE
F"
530 DIM N$(VAL "256",VAL "11"): DIM C$(VAL "18",VAL "4"): DIM D$(CODE "F",VAL "13"): DIM D(CODE "F"): DIM E$(CODE "6",VAL "10"): DIM E(CODE "6")
540 FOR N=SGN PI TO VAL "256": READ N$(N): NEXT N: FOR N=SGN PI TO VAL "18": READ C$(N): NEXT N: FOR N=SGN PI TO CODE "F": READ D$(N): NEXT N: FOR N=SGN PI TO CODE "F": READ D(N): NEXT N: FOR N=SGN PI TO CODE "6": READ E$(N): NEXT N: FOR N=SGN PI TO CODE
"6": READ E(N): NEXT N
550 RETURN
560 DATA "NOP","2LD BC,/","LD (BC),A","INC BC","INC B","DEC B","1LD B,/","RLCA","EX AF,AF'","ADD HL,BC","LD A,(BC)","DEC BC","INC C","DEC C","1LD C,/","RRCA","1DJNZ /","2LD DE,/","LD (DE),A","INC DE","INC D","DEC D","1LD D,/","RLA","1JR /","ADD HL,DE","L
D A,(DE)","DEC DE","INC E","DEC E","1LD E,/","RRA","1JR NZ,/","2LD HL,/","2LD (/),HL","INC HL","INC H","DEC H"
570 DATA "1LD H,/","DAA","1JR Z,/","ADD HL,HL","2LD HL,(/)","DEC HL","INC L","DEC L","1LD L,/","CPL","1JR NC,/","2LD SP,/","2LD (/),A","INC SP","INC (HL)","DEC (HL)","1LD (HL),/","SCF","1JR C,/","ADD HL,SP","2LD A,(/)","DEC SP","INC A","DEC A","1LD A,/",
"CCF","LD B,B","LD B,C","LD B,D","LD B,E","LD B,H","LD B,L","LD B,(HL)","LD B,A","LD C,B","LD C,C","LD C,D","LD C,E","LD C,H","LD C,L","LD C,(HL)","LD C,A"
580 DATA "LD D,B","LD D,C","LD D,D","LD D,E","LD D,H","LD D,L","LD D,(HL)","LD D,A","LD E,B","LD E,C","LD E,D","LD E,E","LD E,H","LD E,L","LD E,(HL)","LD E,A","LD H,B","LD H,C","LD H,D","LD H,E","LD H,H","LD H,L","LD H,(HL)","LD H,A","LD L,B","LD L,C","L
D L,D","LD L,E","LD L,H","LD L,L","LD L,(HL)","LD L,A","LD (HL),B","LD (HL),C","LD (HL),D","LD (HL),E","LD (HL),H","LD (HL),L","HALT","LD (HL),A","LD A,B","LD A,C","LD A,D","LD A,E","LD A,H","LD A,L","LD A,(HL)","LD A,A"
590 DATA "ADD A,B","ADD A,C","ADD A,D","ADD A,E","ADD A,H","ADD A,L","ADD A,(HL)","ADD A,A","ADC A,B","ADC A,C","ADC A,D","ADC A,E","ADC A,H","ADC A,L","ADC A,(HL)","ADC A,A","SUB B","SUB C","SUB D","SUB E","SUB H","SUB L","SUB (HL)","SUB A","SBC A,B","S
BC A,C","SBC A,D","SBC A,E","SBC A,H","SBC A,L","SBC A,(HL)","SBC A,A","AND B","AND C","AND D","AND E","AND H","AND L","AND (HL)","AND A","XOR B","XOR C","XOR D","XOR E","XOR H","XOR L","XOR (HL)","XOR A","OR B","OR C","OR D","OR E","OR H","OR L","OR (HL)
","OR A","CP B","CP C","CP D","CP E","CP H","CP L","CP (HL)","CP A"
600 DATA "RET NZ","POP BC","2JP NZ,/","2JP /","2CALL NZ,/","PUSH BC","1ADD A,/","RST 00","RET Z","RET"+CHR$ 13+";","2JP Z,/","","2CALL Z,/","2CALL /","1ADC A,/","RST 08","RET NC","POP DE","2JP NC,/","1OUT (/),A","2CALL NC,/","PUSH DE","1SUB /","RST 10","
RET C","EXX","2JP C,/","1IN A,(/)","2CALL C,/","","1SBC A,/","RST 18","RET PO","POP HL","2JP PO,/","EX (SP),HL","2CALL PO,/","PUSH HL","1AND /","RST 20","RET PE","JP (HL)","2JP PE,/","EX DE,HL","2CALL PE,/","","1XOR /","RST 28","RET P","POP AF","2JP P,/",
"DI"
610 DATA "2CALL P,/","PUSH AF","1OR /","RST 30","RET M","LD SP,HL","2JP M,/","EI","2CALL M,/","","1CP /","RST 38"
620 DATA "RLC","RRC","RL","RR","SLA","SRA","SRL","BIT","RES","SET","B","C","D","E","H","L","(HL)","A"
630 DATA "ADD *,BC","ADD *,DE","2LD *,/","2LD (/),*","INC *","ADD *,*","2LD *,(/)","DEC *","1INC (*+/)","1DEC (*+/)","","ADD *,SP","1LD B,(*+/)","1LD C,(*+/)","1LD D,(*+/)","1LD E,(*+/)","1LD H,(*+/)","1LD L,(*+/)","1LD (*+/),B","1LD (*+/),C","1LD (*+/),
D","1LD (*+/),E","1LD (*+/),H","1LD (*+/),L","1LD (*+/),A","1LD A,(*+/)"
640 DATA "1ADD A,(*+/)","1ADC A,(*+/)","1SUB A,(*+/)","1SBC A,(*+/)","1AND (*+/)","1XOR (*+/)","1OR (*+/)","1CP (*+/)","POP *","EX (SP),*","PUSH *","JP (*)","LD SP,*","1RLC (*+/)","1RRC (*+/)","1RL (*+/)","1RR (*+/)","1SLA (*+/)","1SRA (*+/)","1SRL (*+/)
","1BIT 0,(*+/)","1BIT 1,(*+/)","1BIT 2,(*+/)","1BIT 3,(*+/)","1BIT 4,(*+/)","1BIT 5,(*+/)","1BIT 6,(*+/)","1BIT 7,(*+/)"
650 DATA "1RES 0,(*+/)","1RES 1,(*+/)","1RES 2,(*+/)","1RES 3,(*+/)","1RES 4,(*+/)","1RES 5,(*+/)","1RES 6,(*+/)","1RES 7,(*+/)","1SET 0,(*+/)","1SET 1,(*+/)","1SET 2,(*+/)","1SET 3,(*+/)","1SET 4,(*+/)","1SET 5,(*+/)","1SET 6,(*+/)","1SET 7,(*+/)"
660 DATA 9,25,33,34,35,41,42,43,52,53,54,57,70,78,86,94,102,110,112,113,114,115,116,117,119,126,134,142,150,158,166,174,182,190,225,227,229,233,249,6,14,22,30,38,46,62,70,78,86,94,102,110,118,126,134,142,150,158,166,174,182,190,198,206,214,222,230,238,24
6,254
670 DATA "IN B,(C)","OUT (C),B","SBC HL,BC","2LD (/),BC","NEG","RETN","IM 0","LD I,A","IN C,(C)","OUT (C),C","ADC HL,BC","2LD BC,(/)","RETI","IN D,(C)","OUT (C),D","SBC HL,DE","2LD (/),DE","IM 1","LD A,I","IN E,(C)","OUT (C),E","ADC HL,DE","2LD DE,(/)","
IM 2","IN H,(C)","OUT (C),H","SBC HL,HL","RRD","IN L,(C)","OUT (C),L"
680 DATA "ADC HL,HL","RLD","SBC HL,SP","2LD (/),SP","IN A,(C)","OUT (C),A","ADC HL,SP","2LD SP,(/)","LDI","CPI","INI","OUTI","LDD","CPD","IND","OUTD","LDIR","CPDIR","INIR","OTIR","LDDR","CPDR","INDR","OTDR"
690 DATA 64,65,66,67,68,69,70,71,72,73,74,75,77,80,81,82,83,86,87,88,89,90,91,94,96,97,98,103,104,105,106,111,114,115,120,121,122,123,160,161,162,163,168,169,170,171,128,129,130,131,136,137,138,139
700 CLEAR : SAVE "D-ENSAMBLA" LINE 1: RUN
Ejemplo de resultado
El código desensamblado puede desviarse a la impresora. El resultado tiene este aspecto:
0 #0000 F3 DI
1 #0001 AF XOR A
2 #0002 11FFFF LD DE,#FFFF ; 65535
5 #0005 C3CB11 JP #11CB ; 4555
8 #0008 2A5D5C LD HL,(#5C5D) ; 23645
11 #000B 225F5C LD (#5C5F),HL ; 23647
14 #000E 1843 JR #43
16 #0010 C3F215 JP #15F2 ; 5618
19 #0013 FF RST 38
20 #0014 FF RST 38
21 #0015 FF RST 38
22 #0016 FF RST 38
23 #0017 FF RST 38
24 #0018 2A5D5C LD HL,(#5C5D) ; 23645
27 #001B 7E LD A,(HL)
28 #001C CD7D00 CALL #007D ; 125
31 #001F D0 RET NC
32 #0020 CD7400 CALL #0074 ; 116
35 #0023 18F7 JR #F7
37 #0025 FF RST 38
38 #0026 FF RST 38
39 #0027 FF RST 38
40 #0028 C35B33 JP #335B ; 13147
43 #002B FF RST 38
44 #002C FF RST 38
45 #002D FF RST 38
46 #002E FF RST 38
47 #002F FF RST 38
48 #0030 C5 PUSH BC
49 #0031 2A615C LD HL,(#5C61) ; 23649
52 #0034 E5 PUSH HL
53 #0035 C39E16 JP #169E ; 5790
56 #0038 F5 PUSH AF
57 #0039 E5 PUSH HL
58 #003A 2A785C LD HL,(#5C78) ; 23672
61 #003D 23 INC HL
62 #003E 22785C LD (#5C78),HL ; 23672
65 #0041 7C LD A,H
66 #0042 B5 OR L
67 #0043 2003 JR NZ,#03
69 #0045 FD3440 INC (IX+#40)
72 #0048 C5 PUSH BC
73 #0049 D5 PUSH DE
74 #004A CD6E38 CALL #386E ; 14446
77 #004D D1 POP DE
78 #004E C1 POP BC
79 #004F E1 POP HL
80 #0050 F1 POP AF
81 #0051 FB EI
82 #0052 C9 RET
;