Ya tenemos resuelto el problema del Hardware, y conocemos como vamos a controlar las señales provenientes del microprocesador y la paca prototipo. Para ello he puesto los esquemas de las tarjetas y las funciones que darán el interface con las tarjetas.
Ahora podemos ponernos al meollo de la cuestión. El entrono del depurador.
Al menos debe de contener las siguientes características.
- Debe de tener una ventana de datos de memoria, en la que se puedan modificar y visualizar estos.
- Debe de ser capaz de mostrar el programa desensambaldo.
- Debe mostrar los registros del microprocesador.
- Debe de tener modo de ejecución continuo, paso a paso y puntos de ruptura.
- Debe de se amigable, aunque lo estemos realizando en DOS y en Ensamblador.
El hecho de usar ensamblador y no utilizar un entorno gráfico, fue debido en su momento a la necesidad de velocidad. Ahora, aunque los ordenadores son más rápidos, la velocidad nunca bien mal.
¿Por qué tanta necesidad de velocidad? Porque el traceo lo hace el ordenador directamente. Es el ordenador el que da los pulsos de reloj, para ir ejecutando las instrucciones, y además entre pulsos va a tomar datos de la placa a través de los buses. Por ello, si queremos tracear a una buena velocidad, necesitamos que el manejo del Hard sea lo más rápido posible. Necesitamos que la interpretación del código, el desensamblado también, y sobre todo necesitamos que la respuesta en pantalla sea instantanea.
Es por ese motivo que la función Puts y Printf, que en su momento ya he puesto en el blog, no esté hecha mediante llamadas al DOS, sino mediante volcado directo a pantalla.
Para empezar el depurador, por lo tanto, voy a comenzar por la rutina principal. La que desensambla.
Para realizar el desensamblador de una forma muy rápida y con poco código, creo una tabla de desensamblado, en la cuál asignaremos un a serie de datos a cada código que encontremos en código máquina.
Así mediante una tabla de indexado, llamada Tabla, accederemos a una tabla de interpretación de código. Cuando leamos un byte de código máquina, usaremos Tabla localizar el formato de la instrución que codifica.
A través de ese puntero recorreremos la lista correspondiente de datos de la instrucción, que nos indicará:
- Byte 0 = tipo instrucción
- 0 ---- inmediato (1 byte)
- 1 ---- texto + num 8 bits (2 bytes)
- 2 ---- texto + num 16 bits (3 bytes)
- 3 ---- texto + num 8bits + texto
- 4 ---- texto + num 16 bits + texto
- 5 ---- texto + num 8 bits relativo + texto + num 8 bits
- 6 ---- texto + num 8 bits relativo
- 7 ---- texto + num 8 bits relativo + texto
- 8 ---- texto + num 8bits + texto + num 8 bits
- 9 ---- texto + num 8 bits + texto + num 8 bits relativo
- 10 ---- texto + num 11bits (2 bytes)
- 11 ---- texto + num 8 bits ref_bit
- 12 ---- texto + num 8 bits ref_bit + texto
- 13 ---- texto + num 8 bits ref_bit + texto + num 8 bits relativo
- 0ffh ---- nueva tabla INSTRUCCION COMPUESTA
- byte 1 = Ciclos de reloj de la instrución
- byte 2= numero de bytes de la instrucción
- byte 3 en adelante = Nemónico
Estas macros son INSTRUC y TABLA_INST. La primera crea la etiqueta con los valores del contador de TABLA_INST y esta última lleva la cuenta del bucle, en este caso 100h, colocando delante un nemónico inicial "I", que es enviado en todas las llamadas posteriores a INSTRUC, para que lo coloque delante del número del contador.
Esta función interpretará el código de insgtrucción indicando el formato que debe usarse en la lectura de los siguientes bytes. Para ello, interpreta el código de instrucción y devuelve un puntero a la cadena de interpretación. Esta cadena contiene la estructura de textos que han de colocarse, insertando entre medias los datos que correspondan.
Por lo tanto esta función es subrutina de una de mayor nivel que desensamblará la instrucción completa.
Este interprete es un proceso muy sencillo que he utilizado en otros lenguajes para desensamblar otros códigos máquina, resultando muy eficaz y sencillo de programar.
Esta función no solo servirá para reconocer la instrucción al presentaral en pantalla o listarla. Sino mucho más importante será usada por las rutinas de ejecución para conocer el numero de pulsos de reloj de cada instrucción de ensamblador, y poder así ejecutar la instrucción por completo.
INTERPRETA.ASM
; Copyright (C) 2013 José Ángel Moneo Fernández ; This program is free software: you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation, either version 3 of the License, or ; (at your option) any later version. ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; You should have received a copy of the GNU General Public License ; along with this program. If not, see <http://www.gnu.org/licenses/
include main.mac
include stdio.mac
include window.mac
include 8051.mac
include 48iocent.mac
public _interpreta
;definición de instrución en la tabla
INSTRUC MACRO ETI,X
IFDEF ETI&X
DB X
DW ETI&X
ENDIF
endm
;macro para definir tabla de instrucciones
TABLA_INST MACRO ETI
LB=0
REPT 100h
INSTRUC ETI,%LB
LB=LB+1
ENDM
ENDM
DIR_RESET EQU 0
.model compact,pascal
.data
;CONTROL
;Lista de instrucciones
; estructura de la entrada en la tabla
;byte 0 =tipo instruciión
;0 inmediato (1 byte)
;1 texto + num 8 bits (2 bytes)
;2 texto + num 16 bits (3 bytes)
;3 texto + num 8bits + texto
;4 texto + num 16 bits + texto
;5 texto + num 8 bits relativo + texto + num 8 bits
;6 texto + num 8 bits relativo
;7 texto + num 8 bits relativo + texto
;8 texto + num 8bits + texto + num 8 bits
;9 texto + num 8 bits + texto + num 8 bits relativo
;10 texto + num 11bits (2 bytes)
;11 texto + num 8 bits ref_bit
;12 texto + num 8 bits ref_bit + texto
;13 texto + num 8 bits ref_bit + texto + num 8 bits relativo
;0ffh nueva tabla INSTRUCCION COMPUESTA
;byte 1 = Ciclos de reloj de la instrución
;byte 2= numero de bytes de la instruciión
;Resto hasta "0" Nemónico
I0 DB 0,12,1,"NOP",0
I1 DB 10,24,2,"AJMP ",0
I2 DB 2,24,3,"LJMP ",0
I3 DB 0,12,1,"RR A",0
I4 DB 0,12,1,"INC A",0
I5 DB 1,12,2,"INC ",0
I6 DB 0,12,1,"INC @R0",0
I7 DB 0,12,1,"INC @R1",0
I8 DB 0,12,1,"INC R0",0
I9 DB 0,12,1,"INC R1",0
I10 DB 0,12,1,"INC R2",0
I11 DB 0,12,1,"INC R3",0
I12 DB 0,12,1,"INC R4",0
I13 DB 0,12,1,"INC R5",0
I14 DB 0,12,1,"INC R6",0
I15 DB 0,12,1,"INC R7",0
I16 DB 13,24,3,"JBC ",0,",",0
I17 db 10,24,2,"ACALL ",0
I18 DB 2,24,3,"LCALL ",0
I19 DB 0,12,1,"RRC A",0
I20 DB 0,12,1,"DEC A",0
I21 DB 1,12,2,"DEC ",0
I22 DB 0,12,1,"DEC @R0",0
I23 DB 0,12,1,"DEC @R1",0
I24 DB 0,12,1,"DEC R0",0
I25 DB 0,12,1,"DEC R1",0
I26 DB 0,12,1,"DEC R2",0
I27 DB 0,12,1,"DEC R3",0
I28 DB 0,12,1,"DEC R4",0
I29 DB 0,12,1,"DEC R5",0
I30 DB 0,12,1,"DEC R6",0
I31 DB 0,12,1,"DEC R7",0
I32 DB 13,24,3,"JB ",0,",",0
I33 DB 10,24,2,"AJMP ",0
I34 DB 0,24,1,"RET",0
I35 DB 0,12,1,"RL A",0
I36 DB 1,12,2,"ADD A,#",0
I37 DB 1,12,2,"ADD A,",0
I38 DB 0,12,1,"ADD A,@R0",0
I39 DB 0,12,1,"ADD A,@R1",0
I40 DB 0,12,1,"ADD A,R0",0
I41 DB 0,12,1,"ADD A,R1",0
I42 DB 0,12,1,"ADD A,R2",0
I43 DB 0,12,1,"ADD A,R3",0
I44 DB 0,12,1,"ADD A,R4",0
I45 DB 0,12,1,"ADD A,R5",0
I46 DB 0,12,1,"ADD A,R6",0
I47 DB 0,12,1,"ADD A,R7",0
I48 DB 13,24,3,"JNB ",0,",",0
I49 db 10,24,2,"ACALL ",0
I50 DB 0,24,1,"RETI",0
I51 DB 0,12,1,"RLC A",0
I52 DB 1,12,2,"ADDC A,#",0
I53 DB 1,12,2,"ADDC A,",0
I54 DB 0,12,1,"ADDC A,@R0",0
I55 DB 0,12,1,"ADDC A,@R1",0
I56 DB 0,12,1,"ADDC A,R0",0
I57 DB 0,12,1,"ADDC A,R1",0
I58 DB 0,12,1,"ADDC A,R2",0
I59 DB 0,12,1,"ADDC A,R3",0
I60 DB 0,12,1,"ADDC A,R4",0
I61 DB 0,12,1,"ADDC A,R5",0
I62 DB 0,12,1,"ADDC A,R6",0
I63 DB 0,12,1,"ADDC A,R7",0
I64 DB 13,24,3,"JC ",0,",",0
I65 db 10,24,2,"AJMP ",0
I66 DB 3,12,2,"ORL ",0,",A",0
I67 DB 8,24,3,"ORL ",0,",#",0
I68 DB 1,12,2,"ORL A,#",0
I69 DB 1,12,2,"ORL A,",0
I70 DB 0,12,1,"ORL A,@R0",0
I71 DB 0,12,1,"ORL A,@R1",0
I72 DB 0,12,1,"ORL A,R0",0
I73 DB 0,12,1,"ORL A,R1",0
I74 DB 0,12,1,"ORL A,R2",0
I75 DB 0,12,1,"ORL A,R3",0
I76 DB 0,12,1,"ORL A,R4",0
I77 DB 0,12,1,"ORL A,R5",0
I78 DB 0,12,1,"ORL A,R6",0
I79 DB 0,12,1,"ORL A,R7",0
I80 DB 13,24,3,"JNC ",0,",",0
I81 db 10,24,2,"ACALL ",0
I82 DB 3,12,2,"ANL ",0,",A",0
I83 DB 8,24,3,"ANL ",0,",#",0
I84 DB 1,12,2,"ANL A,#",0
I85 DB 1,12,2,"ANL A,",0
I86 DB 0,12,1,"ANL A,@R0",0
I87 DB 0,12,1,"ANL A,@R1",0
I88 DB 0,12,1,"ANL A,R0",0
I89 DB 0,12,1,"ANL A,R1",0
I90 DB 0,12,1,"ANL A,R2",0
I91 DB 0,12,1,"ANL A,R3",0
I92 DB 0,12,1,"ANL A,R4",0
I93 DB 0,12,1,"ANL A,R5",0
I94 DB 0,12,1,"ANL A,R6",0
I95 DB 0,12,1,"ANL A,R7",0
I96 DB 13,24,3,"JZ ",0,",",0
I97 db 10,24,2,"AJMP ",0
I98 DB 3,12,2,"XRL ",0,",A",0
I99 DB 8,24,3,"XRL ",0,",#",0
I100 DB 1,12,2,"XRL A,#",0
I101 DB 1,12,2,"XRL A,",0
I102 DB 0,12,1,"XRL A,@R0",0
I103 DB 0,12,1,"XRL A,@R1",0
I104 DB 0,12,1,"XRL A,R0",0
I105 DB 0,12,1,"XRL A,R1",0
I106 DB 0,12,1,"XRL A,R2",0
I107 DB 0,12,1,"XRL A,R3",0
I108 DB 0,12,1,"XRL A,R4",0
I109 DB 0,12,1,"XRL A,R5",0
I110 DB 0,12,1,"XRL A,R6",0
I111 DB 0,12,1,"XRL A,R7",0
I112 DB 13,24,3,"JNZ ",0,",",0
I113 db 10,24,2,"ACALL ",0
I114 DB 11,24,2,"ORL C,",0
I115 DB 0,24,1,"JMP @A+DPTR",0
I116 DB 1,12,2,"MOV A,#",0
I117 DB 8,24,3,"MOV ",0,",#",0
I118 DB 1,12,2,"MOV @R0,#",0
I119 DB 1,12,2,"MOV @R1,#",0
I120 DB 1,12,2,"MOV R0,#",0
I121 DB 1,12,2,"MOV R1,#",0
I122 DB 1,12,2,"MOV R2,#",0
I123 DB 1,12,2,"MOV R3,#",0
I124 DB 1,12,2,"MOV R4,#",0
I125 DB 1,12,2,"MOV R5,#",0
I126 DB 1,12,2,"MOV R6,#",0
I127 DB 1,12,2,"MOV R7,#",0
I128 DB 6,24,2,"SJMP ",0
I129 db 10,24,2,"AJMP ",0
I130 DB 11,24,2,"ANL C,",0
I131 DB 0,24,1,"MOVC A,@A+PC",0
I132 DB 0,48,1,"DIV AB",0
I133 DB 8,24,3,"MOV ",0,",",0
I134 DB 3,24,3,"MOV ",0,",@R0",0
I135 DB 3,24,3,"MOV ",0,",@R1",0
I136 DB 3,24,3,"MOV ",0,",R0",0
I137 DB 3,24,3,"MOV ",0,",R1",0
I138 DB 3,24,3,"MOV ",0,",R2",0
I139 DB 3,24,3,"MOV ",0,",R3",0
I140 DB 3,24,3,"MOV ",0,",R4",0
I141 DB 3,24,3,"MOV ",0,",R5",0
I142 DB 3,24,3,"MOV ",0,",R6",0
I143 DB 3,24,3,"MOV ",0,",R7",0
I144 DB 2,24,3,"MOV DPTR,#",0
I145 db 10,24,0,"ACALL ",0
I146 DB 12,24,0,"MOV ",0,",C",0
I147 DB 0,24,0,"MOVC A,@A+PC",0
I148 DB 1,12,0,"SUBB A,#",0
I149 DB 1,12,0,"SUBB A,",0
I150 DB 0,12,0,"SUBB A,@R0",0
I151 DB 0,12,0,"SUBB A,@R1",0
I152 DB 0,12,0,"SUBB A,R0",0
I153 DB 0,12,0,"SUBB A,R1",0
I154 DB 0,12,0,"SUBB A,R2",0
I155 DB 0,12,0,"SUBB A,R3",0
I156 DB 0,12,0,"SUBB A,R4",0
I157 DB 0,12,0,"SUBB A,R5",0
I158 DB 0,12,0,"SUBB A,R6",0
I159 DB 0,12,0,"SUBB A,R7",0
I160 DB 11,24,0,"ORL C,/",0
I161 db 10,24,0,"AJMP ",0
I162 DB 11,24,0,"MOV C,",0
I163 DB 0,24,0,"INC DPTR",0
I164 DB 0,48,0,"MUL AB",0
I165 DB 0,12,0,"????",0
I166 DB 1,12,0,"MOV @R0,",0
I167 DB 1,12,0,"MOV @R1,",0
I168 DB 1,12,0,"MOV R0,",0
I169 DB 1,12,0,"MOV R1,",0
I170 DB 1,12,0,"MOV R2,",0
I171 DB 1,12,0,"MOV R3,",0
I172 DB 1,12,0,"MOV R4,",0
I173 DB 1,12,0,"MOV R5,",0
I174 DB 1,12,0,"MOV R6,",0
I175 DB 1,12,0,"MOV R7,",0
I176 DB 11,24,0,"ANL C,/",0
I177 db 10,24,0,"ACALL ",0
I178 DB 11,12,0,"CPL ",0
I179 DB 0,12,0,"CPL C",0
I180 DB 9,24,0,"CJNE A,#",0,",",0
I181 DB 9,24,0,"CJNE A,",0,",",0
I182 DB 9,24,0,"CJNE @R0,#",0,",",0
I183 DB 9,24,0,"CJNE @R1,#",0,",",0
I184 DB 9,24,0,"CJNE R0,#",0,",",0
I185 DB 9,24,0,"CJNE R1,#",0,",",0
I186 DB 9,24,0,"CJNE R2,#",0,",",0
I187 DB 9,24,0,"CJNE R3,#",0,",",0
I188 DB 9,24,0,"CJNE R4,#",0,",",0
I189 DB 9,24,0,"CJNE R5,#",0,",",0
I190 DB 9,24,0,"CJNE R6,#",0,",",0
I191 DB 9,24,0,"CJNE R7,#",0,",",0
I192 DB 1,24,0,"PUSH ",0
I193 db 10,24,0,"AJMP ",0
I194 DB 11,12,0,"CLR ",0
I195 DB 0,12,0,"CLR C",0
I196 DB 0,12,0,"SWAP A",0
I197 DB 1,12,0,"XCH A,",0
I198 DB 0,12,0,"XCH A,@R0",0
I199 DB 0,12,0,"XCH A,@R1",0
I200 DB 0,12,0,"XCH A,R0",0
I201 DB 0,12,0,"XCH A,R1",0
I202 DB 0,12,0,"XCH A,R2",0
I203 DB 0,12,0,"XCH A,R3",0
I204 DB 0,12,0,"XCH A,R4",0
I205 DB 0,12,0,"XCH A,R5",0
I206 DB 0,12,0,"XCH A,R6",0
I207 DB 0,12,0,"XCH A,R7",0
I208 DB 1,24,0,"POP ",0
I209 db 10,24,0,"ACALL ",0
I210 DB 11,12,0,"SETB ",0
I211 DB 0,12,0,"SETB C",0
I212 DB 0,12,0,"DA A",0
I213 DB 9,24,0,"DJNZ ",0,",",0
I214 DB 0,12,0,"XCHD A,@R0",0
I215 DB 0,12,0,"XCHD A,@R1",0
I216 DB 6,24,0,"DJNE R0,",0,",",0
I217 DB 6,24,0,"DJNE R1,",0,",",0
I218 DB 6,24,0,"DJNE R2,",0,",",0
I219 DB 6,24,0,"DJNE R3,",0,",",0
I220 DB 6,24,0,"DJNE R4,",0,",",0
I221 DB 6,24,0,"DJNE R5,",0,",",0
I222 DB 6,24,0,"DJNE R6,",0,",",0
I223 DB 6,24,0,"DJNE R7,",0,",",0
I224 DB 0,24,0,"MOVX A,@DPTR",0
I225 db 10,24,0,"AJMP ",0
I226 DB 0,24,0,"MOVX A,@R0",0
I227 DB 0,24,0,"MOVX A,@R1",0
I228 DB 0,12,0,"CLR A",0
I229 DB 1,12,0,"MOV A,",0
I230 DB 0,12,0,"MOV A,@R0",0
I231 DB 0,12,0,"MOV A,@R1",0
I232 DB 0,12,0,"MOV A,R0",0
I233 DB 0,12,0,"MOV A,R1",0
I234 DB 0,12,0,"MOV A,R2",0
I235 DB 0,12,0,"MOV A,R3",0
I236 DB 0,12,0,"MOV A,R4",0
I237 DB 0,12,0,"MOV A,R5",0
I238 DB 0,12,0,"MOV A,R6",0
I239 DB 0,12,0,"MOV A,R7",0
I240 DB 0,24,0,"MOV @DPTR,A",0
I241 db 10,24,0,"ACALL ",0
I242 DB 0,24,0,"MOVX @R0,A",0
I243 DB 0,24,0,"MOVX @R1,A",0
I244 DB 0,12,0,"CPL A",0
I245 DB 3,12,0,"MOV ",0,",A",0
I246 DB 0,12,0,"MOV @R0,A",0
I247 DB 0,12,0,"MOV @R1,A",0
I248 DB 0,12,0,"MOV R0,A",0
I249 DB 0,12,0,"MOV R1,A",0
I250 DB 0,12,0,"MOV R2,A",0
I251 DB 0,12,0,"MOV R3,A",0
I252 DB 0,12,0,"MOV R4,A",0
I253 DB 0,12,0,"MOV R5,A",0
I254 DB 0,12,0,"MOV R6,A",0
I255 DB 0,12,0,"MOV R7,A",0
Tabla LABEL BYTE
Tabla_inst I ;tabla a lista de instrucciones
db 0ffh ;localizador final tabla
no_conocido db 0,0,0,"????",0 ; codigo no desensamblable
nada db 0
.code
_interpreta proc uses si bx
;se indicará en DX direccion de la
;instruccion a decodificar y devolverá
;en ax la direccion de la lista de interpretado
mov si,offset Tabla
busca_mas:
leeinst
inc dx
busca:
cmp al,[si]
jz localizado
jb n_conoc
cmp byte ptr [si],0ffh
jz n_conoc
add si,3
jmp busca
n_conoc:
mov bx,offset no_conocido
jmp fin
localizado:
mov bx,[si+1] ;se lee la direccion de la instruccion
mov al,[bx] ;de la secuencia se lee el indicador
cmp al,0ffh ;indicador de instruccion compuesta
jne fin
mov si,[BX+1]
jmp busca_mas
fin:
mov ax,bx
ret
_interpreta endp
end
No hay comentarios:
Publicar un comentario
Si tienes algún comentario, duda o sugerencia, o si quieres aportar algún código creado a partir de las librerías expuestas aquí, por favor, indícamelo.