Binario en el asm de los PIC

Foro dedicado a la emulación de sistemas clásicos en el PC o en otros sistemas.
REHome
Amstrad PCW 8256
Amstrad PCW 8256
Mensajes: 145
Registrado: 19 Abr 2013, 22:01
Sistema Favorito: Spectrum +2
primer_sistema: Spectrum +2
Gracias dadas: 3 veces
Gracias recibidas: 2 veces

Re: Binario en el asm de los PIC

Mensajepor REHome » 16 Ago 2017, 13:09

Buenas:

No se porqué pensé que te iba bien el Java, por eso se hizo así, ajajjajajajaja. En cuanto al Perls, no lo entiendo, aprendí en su día por obligación Python y me olvidé.

Se puede usar uno estandar como el C/C++, también uso C# y se puede usar el VB .net para los que le vengan bien.

Me sorprende que con Perl haces todo en pocas líneas comparado con otros lenguajes, impresionante.

Receurdo que mi idea no es dedicarme hacer un descompilador así sin más, hago uno con un lenguaje, el mejor que nos adaptemos para poder introducir números binarios de 16 bits y muestra los códigos en ensamblador. Se que PIC16F84A mueve 14 bits, por si acaso quiera en el futuro manejar los PIC18F por eso los dejo en 16 bits para leer.

Estaba trasteando con C# lo de introducir datos en bianrio, 0 y 1 de 16 dígitos.

Con un lenguaje, hay que emular la electrónica. Por ejemplo,usando la consola de C# introduces este código.
000010001000 0110

Precisamente el de este ejemplo:
Imagen

Y su resultado es 0x0886 en hexadecimal.
Consola-binario.gif
Consola-binario.gif (6.7 KiB) Visto 10382 veces


Código de este programa binario para pruebas C#:

Código: Seleccionar todo

using System;
using System.Linq;

namespace Binario_cs
{
    class Program
    {
        static void Main(string[] args)
        {
            // Título de la ventana.
            Console.Title = "Binaro a ensamblador de PIC16F84A - C#";

            // Muestra texto en pantalla pidiendo que introduzca los datos en binario.
            Console.Write("Introduzca 16 números binarios: ");

            String binario = Console.ReadLine();

            Console.WriteLine();

            if (binario.Count(x => x != '0' & x != '1') == 0 & binario.Length == 16)
            {
                int NumDec = Convert.ToInt32(binario, 2);
                string NumHex = String.Format("0x{0:X4}", NumDec);
                Console.WriteLine("Binario = " + binario);
                Console.WriteLine("Decimal = " + NumDec.ToString());
                Console.WriteLine("Hexadecimal = " + NumHex);
            }
            else
            {
                Console.WriteLine("Número incorrecto");
            }
            Console.ReadKey();
        }
    }
}


Aquí abajo el código en C# que antes era en Java. Introduces el valor 0x0886 y muestra el ensamblador del PIC esta instrucción MOVF PORTB, F. El 0x0886 en hexadecimal es exactamente lo mismo que este binario 000010001000 0110.

Código Descompila en C#:

Código: Seleccionar todo

using System;

namespace Descompilar
{
    class Program01
    {
        static void Main(string[] args)
        {
            Console.Title = "Descompila con Chago - C#";

            descompilar(new TroceadoEnBits(0x0886)); // 0x0886
        }

        static void print(String cadena)
        {
            // System.out.println(cadena);
            Console.WriteLine(cadena);
            Console.ReadKey(); // Pulse cualquier tecla para salir.
        }

        static String direccion(int operando)
        {
            String registro = "";
            switch (operando)
            {
                // -----Bank0------------------
                case 0x0: registro = "INDF"; break;
                case 0x1: registro = "TMR0"; break;
                case 0x2: registro = "PCL"; break;
                case 0x3: registro = "STATUS"; break;
                case 0x4: registro = "FSR"; break;
                case 0x5: registro = "PORTA"; break;
                case 0x6: registro = "PORTB"; break;
                //chago aqui vete completando la tabla de REGISTER FILE MAP
                case 0x8: registro = "EEDATA"; break;
                case 0x9: registro = "EEADR"; break;
                case 0xA: registro = "PCLATH"; break;
                case 0xB: registro = "INTCON"; break;
                //-----Bank1------------------
                case 0x81: registro = "OPTION_REG"; break;
                case 0x85: registro = "TRISA"; break;
                case 0x86: registro = "TRISB"; break;
                case 0x88: registro = "EECON1"; break;
                case 0x89: registro = "EECON2"; break;

                default:
                    // registro = Integer.toHexString(operando);
                    registro =  Convert.ToString(operando);
                    break;
            }
            return registro;
        }

        static void descompilar(TroceadoEnBits opcode)
        {
            int bits1312 = opcode.dameRango(12, 12);// (0x3000 & opcode) >> 12;      // extraemos los dos bits superiores

            String operando;

            switch (bits1312)
            {
                case 0:
                    // en este caso, el tercer nibble es la operación, el bit 7 es la suboperación o destino, y el resto, el operando
                    int nibble3 = opcode.dameRango(8, 11);//(0x0f00 & opcode) >> 8;
                    int bit7 = opcode.dameRango(7, 7);//(0x0080 & opcode) >> 7;
                    operando = direccion(opcode.dameRango(0, 6)); //direccion(0x007f & opcode);
                    String reg = "";
                    switch (bit7)
                    {
                        case 0: reg = ", W "; break;
                        case 1: reg = ", F "; break;
                    }

                    switch (nibble3)
                    {

                        case 0x0:
                            switch (bit7)
                            {
                                case 1: print("MOVWF " + operando); break;
                                case 0:
                                    // aquí pueden ocurrir varios casos, según el primer nibble
                                    int nibble1 = opcode.dameRango(0, 3);// (0x000f & opcode);
                                    switch (nibble1)
                                    {
                                        case 0x0: print("NOP"); break;
                                        case 0x4: print("CLRWDT"); break;
                                        case 0x9: print("RETFIE"); break;
                                        case 0x8: print("RETURN"); break;
                                        case 0x3: print("SLEEP"); break;
                                    }
                                    break;
                            }
                            break;
                        case 0x1:
                            switch (bit7)
                            {
                                case 0: print("CLRW"); break;
                                case 1: print("CLRF " + operando); break;
                            }
                            break;
                        case 0x2: print("SUBWF " + operando + reg); break;
                        case 0x3: print("DECF " + operando + reg); break;
                        case 0x4: print("IORWF " + operando + reg); break;
                        case 0x5: print("ANDWF " + operando + reg); break;
                        case 0x6: print("XORWF " + operando + reg); break;
                        case 0x7: print("ADDWF " + operando + reg); break;
                        case 0x8: print("MOVF " + operando + reg); break;
                        case 0x9: print("COMF " + operando + reg); break;
                        case 0xA: print("INCF " + operando + reg); break;
                        case 0xB: print("DECFSZ " + operando + reg); break;
                        case 0xC: print("RRF " + operando + reg); break;
                        case 0xD: print("RLF " + operando + reg); break;
                        case 0xE: print("SWAPF " + operando + reg); break;
                        case 0xF: print("INCFSZ " + operando + reg); break;
                    }
                    break;
                case 1:
                    // en este caso, los bits 12 y 11 es la suboperación, los bits 8, 9 y 10 es el número de bit, y el resto, el operandojj
                    int subop = opcode.dameRango(8, 10);//(0x0c00 & opcode) >> 10;
                    int bit = opcode.dameRango(7, 9);//(0x0380 & opcode) >> 7;
                    operando = opcode.dameRangoHex(0, 6);//Integer.toHexString(0x007f & opcode);

                    switch (subop)
                    {
                        case 0x0: print("BCF " + operando + bit); break;
                        case 0x1: print("BSF " + operando + bit); break;
                        case 0x2: print("BTFSC " + operando + bit); break;
                        case 0x3: print("BTFSS " + operando + bit); break;
                    }
                    break;
                case 2:
                    // ver el bit 12. El resto es el operando
                    int bit11 = opcode.dameRango(11, 11);//(0x0800 & opcode) >> 11;
                    operando = opcode.dameRangoHex(0, 10);//Integer.toHexString(0x07ff & opcode);

                    switch (bit11)
                    {
                        case 0: print("CALL " + operando); break;
                        case 1: print("GOTO " + operando); break;
                    }
                    break;
                case 3:
                    // el tercer nibble es la suboperación, y el resto, el operando
                    nibble3 = opcode.dameRango(8, 11);//(0x0f00 & opcode) >> 8;
                    operando = direccion(opcode.dameRango(0, 7));//direccion(0x00ff & opcode);

                    switch (nibble3)
                    {
                        case 0:
                        case 1:
                        case 2:
                        case 3: print("MOVLW " + operando); break;
                        case 4:
                        case 5:
                        case 6:
                        case 7: print("RETLW " + operando); break;
                        case 8: print("IORLW " + operando); break;
                        case 9: print("ANDLW " + operando); break;
                        case 0xa: print("XORLW " + operando); break;

                        case 0xb:
                        case 0xc:
                            //cc no sé que pasa con 0xd
                            print("SUBLW " + operando);
                            break;
                        case 0xe:
                        case 0xf:
                            print("ADDLW " + operando);
                            break;
                    }
                    break;
            }
        }
    }
}


Clase TroceadoEnBits.cs:

Código: Seleccionar todo

using System;

namespace Descompilar
{
    class TroceadoEnBits
    {
        int bits;

        public TroceadoEnBits(int bits)
        {
            // super();
            this.bits = bits;
        }

        public int getBits()
        {
            return bits;
        }

        public void setBits(int bits)
        {
            this.bits = bits;
        }

        public int dameRango(int ini, int fin)
        {
            if ((ini < 0 || ini > 13) || (fin < 0 || fin > 13)) throw new ArgumentException("ini y/o fin no pueden ser menores que 0 ni mayores que 13");

            int[] desde = new int[14], hasta = new int[14];
            // int desde[] = new int[14], hasta[] = new int[14];
            desde[0] = 0x3fff; hasta[0] = 0x1;
            desde[1] = 0x3ffe; hasta[1] = 0x3;
            desde[2] = 0x3ffc; hasta[2] = 0x7;
            desde[3] = 0x3ff8; hasta[3] = 0xf;
            desde[4] = 0x3ff0; hasta[4] = 0x1f;
            desde[5] = 0x3fe0; hasta[5] = 0x3f;
            desde[6] = 0x3fc0; hasta[6] = 0x7f;
            desde[7] = 0x3f80; hasta[7] = 0xff;
            desde[8] = 0x3f00; hasta[8] = 0x1ff;
            desde[9] = 0x3e00; hasta[9] = 0x3ff;
            desde[10] = 0x3c00; hasta[10] = 0x7ff;
            desde[11] = 0x3800; hasta[11] = 0xfff;
            desde[12] = 0x3000; hasta[12] = 0x1fff;
            desde[13] = 0x2000; hasta[13] = 0x3fff;
            return (desde[ini] & hasta[fin] & bits) >> ini;
        }

        public String dameRangoHex(int ini, int fin)
        {
            // return Integer.toHexString(dameRango(ini, fin)); // Manera Chago en Java.
            // return Convert.ToString(dameRango(ini,fin)); // Manera Acaymo en C#.
            return dameRango(ini, fin).ToString("X4"); // Manera de un forero en C#.
        }
    }
}


Cuando funcione al 100 % en el ordenador de sobremesa, hay que adapatarlo al código de Arduino y colocar sus entradas digitales físicas y Led, también se incluirán los Led de estados, como los estados.
bbbbbbbbbbbbbbb8.png
bbbbbbbbbbbbbbb8.png (2.12 KiB) Visto 10382 veces


Imagen
Toda esa electrónica me la ahorraré.

Antes que se me olvide, dejar la lista de instrucciones que puede ayudar.
https://en.wikipedia.org/wiki/PIC_instruction_listings

explorer escribió:Y algunos en código C.


Si haz visto una Web del lenguaje que sea, si es C, mejor que mejor, le hecharé un ojo. Creo que el ejemplo que pusiste en C de la página anterior tiene fallitos. Cuantas más págians de estas haya mejor, la verdad, me cuesta encontrarlas. Ejemplos en C o otro lenguaje sobre compilar.

Saludos.

REHome
Amstrad PCW 8256
Amstrad PCW 8256
Mensajes: 145
Registrado: 19 Abr 2013, 22:01
Sistema Favorito: Spectrum +2
primer_sistema: Spectrum +2
Gracias dadas: 3 veces
Gracias recibidas: 2 veces

Re: Binario en el asm de los PIC

Mensajepor REHome » 16 Ago 2017, 23:37

Hola de nuevo:

Hice el código en C#. Hay que introducir los datos en binario, 16 dógitos entre unos y ceros. Te da el valor hexadecimal y el código del ensamblador para el PIC16F84A.

Consola-binario2.gif
Consola-binario2.gif (21.43 KiB) Visto 10365 veces


Descompilar v0.01.zip
(4.23 KiB) Descargado 371 veces


Puedes probar y contar sus experiencias.

Sigo buscando más Web aunque sea ruso donde encontrar ejemplos de como descompilar el PIC16F84A o el que sea. Si sabes algo, lo publicaas por aquí. Muchas gracias por leer.

Saludos.

Avatar de Usuario
explorer
MSX Turbo R
MSX Turbo R
Mensajes: 398
Registrado: 11 May 2014, 17:10
Sistema Favorito: Atari ST
primer_sistema: Atari 800XL/600XL
consola_favorita: Atari 2600
Primera consola: Atari 2600
Ubicación: Valladolid, España
Gracias dadas: 2 veces
Gracias recibidas: 138 veces
Contactar:

Re: Binario en el asm de los PIC

Mensajepor explorer » 17 Ago 2017, 22:25

Pues... entras en Google y pones "microchip pic disassembler source" y salen algunos resultados. Por ejemplo, aquí:

vPICdisasm is a Microchip PIC firmware disassembler that supports the Baseline, Mid-Range, and Mid-Range Enhanced 8-bit PIC cores. This single-pass disassembler can read Intel HEX8 and Motorola S-Record formatted files containing valid PIC program binaries.

Está el código fuente. Quitando la parte de la lectura del archivo .hex, ya tienes el código para hacer la transformación de binario a ensamblador.

REHome
Amstrad PCW 8256
Amstrad PCW 8256
Mensajes: 145
Registrado: 19 Abr 2013, 22:01
Sistema Favorito: Spectrum +2
primer_sistema: Spectrum +2
Gracias dadas: 3 veces
Gracias recibidas: 2 veces

Re: Binario en el asm de los PIC

Mensajepor REHome » 18 Ago 2017, 11:57

Hola:

Mirando por el aire descompilador, está hecho en C/C++. Voy a hecharlo andar con Visual Studio Community 2017 para estudiarlo como se comporta.

Cuando le coja el truco, lo adaptaré a C#.

Muchas gracias por la información. Más adeñante te cuento.

Si encuentran otro por si acaso, mejor que mejor. Seguiré también buscando por mi cuenta, parece ser que este descompilador es el mejor que haz visto y he visto.

Saludos.

REHome
Amstrad PCW 8256
Amstrad PCW 8256
Mensajes: 145
Registrado: 19 Abr 2013, 22:01
Sistema Favorito: Spectrum +2
primer_sistema: Spectrum +2
Gracias dadas: 3 veces
Gracias recibidas: 2 veces

Re: Binario en el asm de los PIC

Mensajepor REHome » 19 Ago 2017, 23:26

Hola:

Un pequeño avance.
El enlace que pasaste es para Linux.
He usado C++ Builder de esta manera:

Hola, se compila muy fácil, no es más que C:

Crea un nuevo proyecto de tipo "Console Application". Luego como no nos interesa el "main" que se crea, quitamos el File1.c del proyecto (Menú: Project -> Remove from project...) y salvamos el proyecto en el mismo directorio donde están los otros archivos.

Vamos a necesitar el archivo "getopt.h" que suele venir con los compiladores en Linux, lo podemos descargar desde el siguiente enlace y lo copiamos en el directorio del proyecto:

https://raw.githubusercontent.com/skandhurkat/Getopt-for-Visual-Studio/master/getopt.h

Por si acaso se pierda el enlace.

Código: Seleccionar todo

#ifndef __GETOPT_H__
/**
 * DISCLAIMER
 * This file is part of the mingw-w64 runtime package.
 *
 * The mingw-w64 runtime package and its code is distributed in the hope that it
 * will be useful but WITHOUT ANY WARRANTY.  ALL WARRANTIES, EXPRESSED OR
 * IMPLIED ARE HEREBY DISCLAIMED.  This includes but is not limited to
 * warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
 /*
 * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * Sponsored in part by the Defense Advanced Research Projects
 * Agency (DARPA) and Air Force Research Laboratory, Air Force
 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
 */
/*-
 * Copyright (c) 2000 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Dieter Baron and Thomas Klausner.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#pragma warning(disable:4996);

#define __GETOPT_H__

/* All the headers include this file. */
#include <crtdefs.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <windows.h>

#ifdef __cplusplus
extern "C" {
#endif

#define   REPLACE_GETOPT      /* use this getopt as the system getopt(3) */

#ifdef REPLACE_GETOPT
int   opterr = 1;      /* if error message should be printed */
int   optind = 1;      /* index into parent argv vector */
int   optopt = '?';      /* character checked for validity */
#undef   optreset      /* see getopt.h */
#define   optreset      __mingw_optreset
int   optreset;      /* reset getopt */
char    *optarg;      /* argument associated with option */
#endif

//extern int optind;      /* index of first non-option in argv      */
//extern int optopt;      /* single option character, as parsed     */
//extern int opterr;      /* flag to enable built-in diagnostics... */
//            /* (user may set to zero, to suppress)    */
//
//extern char *optarg;      /* pointer to argument of current option  */

#define PRINT_ERROR   ((opterr) && (*options != ':'))

#define FLAG_PERMUTE   0x01   /* permute non-options to the end of argv */
#define FLAG_ALLARGS   0x02   /* treat non-options as args to option "-1" */
#define FLAG_LONGONLY   0x04   /* operate as getopt_long_only */

/* return values */
#define   BADCH      (int)'?'
#define   BADARG      ((*options == ':') ? (int)':' : (int)'?')
#define   INORDER    (int)1

#ifndef __CYGWIN__
#define __progname __argv[0]
#else
extern char __declspec(dllimport) *__progname;
#endif

#ifdef __CYGWIN__
static char EMSG[] = "";
#else
#define   EMSG      ""
#endif

static int getopt_internal(int, char * const *, const char *,
            const struct option *, int *, int);
static int parse_long_options(char * const *, const char *,
               const struct option *, int *, int);
static int gcd(int, int);
static void permute_args(int, int, int, char * const *);

static char *place = EMSG; /* option letter processing */

/* XXX: set optreset to 1 rather than these two */
static int nonopt_start = -1; /* first non option argument (for permute) */
static int nonopt_end = -1;   /* first option after non options (for permute) */

/* Error messages */
static const char recargchar[] = "option requires an argument -- %c";
static const char recargstring[] = "option requires an argument -- %s";
static const char ambig[] = "ambiguous option -- %.*s";
static const char noarg[] = "option doesn't take an argument -- %.*s";
static const char illoptchar[] = "unknown option -- %c";
static const char illoptstring[] = "unknown option -- %s";

static void
_vwarnx(const char *fmt,va_list ap)
{
  (void)fprintf(stderr,"%s: ",__progname);
  if (fmt != NULL)
    (void)vfprintf(stderr,fmt,ap);
  (void)fprintf(stderr,"\n");
}

static void
warnx(const char *fmt,...)
{
  va_list ap;
  va_start(ap,fmt);
  _vwarnx(fmt,ap);
  va_end(ap);
}

/*
 * Compute the greatest common divisor of a and b.
 */
static int
gcd(int a, int b)
{
   int c;

   c = a % b;
   while (c != 0) {
      a = b;
      b = c;
      c = a % b;
   }

   return (b);
}

/*
 * Exchange the block from nonopt_start to nonopt_end with the block
 * from nonopt_end to opt_end (keeping the same order of arguments
 * in each block).
 */
static void
permute_args(int panonopt_start, int panonopt_end, int opt_end,
   char * const *nargv)
{
   int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
   char *swap;

   /*
    * compute lengths of blocks and number and size of cycles
    */
   nnonopts = panonopt_end - panonopt_start;
   nopts = opt_end - panonopt_end;
   ncycle = gcd(nnonopts, nopts);
   cyclelen = (opt_end - panonopt_start) / ncycle;

   for (i = 0; i < ncycle; i++) {
      cstart = panonopt_end+i;
      pos = cstart;
      for (j = 0; j < cyclelen; j++) {
         if (pos >= panonopt_end)
            pos -= nnonopts;
         else
            pos += nopts;
         swap = nargv[pos];
         /* LINTED const cast */
         ((char **) nargv)[pos] = nargv[cstart];
         /* LINTED const cast */
         ((char **)nargv)[cstart] = swap;
      }
   }
}

#ifdef REPLACE_GETOPT
/*
 * getopt --
 *   Parse argc/argv argument vector.
 *
 * [eventually this will replace the BSD getopt]
 */
int
getopt(int nargc, char * const *nargv, const char *options)
{

   /*
    * We don't pass FLAG_PERMUTE to getopt_internal() since
    * the BSD getopt(3) (unlike GNU) has never done this.
    *
    * Furthermore, since many privileged programs call getopt()
    * before dropping privileges it makes sense to keep things
    * as simple (and bug-free) as possible.
    */
   return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
}
#endif /* REPLACE_GETOPT */

//extern int getopt(int nargc, char * const *nargv, const char *options);

#ifdef _BSD_SOURCE
/*
 * BSD adds the non-standard `optreset' feature, for reinitialisation
 * of `getopt' parsing.  We support this feature, for applications which
 * proclaim their BSD heritage, before including this header; however,
 * to maintain portability, developers are advised to avoid it.
 */
# define optreset  __mingw_optreset
extern int optreset;
#endif
#ifdef __cplusplus
}
#endif
/*
 * POSIX requires the `getopt' API to be specified in `unistd.h';
 * thus, `unistd.h' includes this header.  However, we do not want
 * to expose the `getopt_long' or `getopt_long_only' APIs, when
 * included in this manner.  Thus, close the standard __GETOPT_H__
 * declarations block, and open an additional __GETOPT_LONG_H__
 * specific block, only when *not* __UNISTD_H_SOURCED__, in which
 * to declare the extended API.
 */
#endif /* !defined(__GETOPT_H__) */

#if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__)
#define __GETOPT_LONG_H__

#ifdef __cplusplus
extern "C" {
#endif

struct option      /* specification for a long form option...   */
{
  const char *name;      /* option name, without leading hyphens */
  int         has_arg;      /* does it take an argument?      */
  int        *flag;      /* where to save its status, or NULL   */
  int         val;      /* its associated status value      */
};

enum          /* permitted values for its `has_arg' field...   */
{
  no_argument = 0,         /* option never takes an argument   */
  required_argument,      /* option always requires an argument   */
  optional_argument      /* option may take an argument      */
};

/*
 * parse_long_options --
 *   Parse long options in argc/argv argument vector.
 * Returns -1 if short_too is set and the option does not match long_options.
 */
static int
parse_long_options(char * const *nargv, const char *options,
   const struct option *long_options, int *idx, int short_too)
{
   char *current_argv, *has_equal;
   size_t current_argv_len;
   int i, ambiguous, match;

#define IDENTICAL_INTERPRETATION(_x, _y)                                \
   (long_options[(_x)].has_arg == long_options[(_y)].has_arg &&    \
    long_options[(_x)].flag == long_options[(_y)].flag &&          \
    long_options[(_x)].val == long_options[(_y)].val)

   current_argv = place;
   match = -1;
   ambiguous = 0;

   optind++;

   if ((has_equal = strchr(current_argv, '=')) != NULL) {
      /* argument found (--option=arg) */
      current_argv_len = has_equal - current_argv;
      has_equal++;
   } else
      current_argv_len = strlen(current_argv);

   for (i = 0; long_options[i].name; i++) {
      /* find matching long option */
      if (strncmp(current_argv, long_options[i].name,
          current_argv_len))
         continue;

      if (strlen(long_options[i].name) == current_argv_len) {
         /* exact match */
         match = i;
         ambiguous = 0;
         break;
      }
      /*
       * If this is a known short option, don't allow
       * a partial match of a single character.
       */
      if (short_too && current_argv_len == 1)
         continue;

      if (match == -1)   /* partial match */
         match = i;
      else if (!IDENTICAL_INTERPRETATION(i, match))
         ambiguous = 1;
   }
   if (ambiguous) {
      /* ambiguous abbreviation */
      if (PRINT_ERROR)
         warnx(ambig, (int)current_argv_len,
              current_argv);
      optopt = 0;
      return (BADCH);
   }
   if (match != -1) {      /* option found */
      if (long_options[match].has_arg == no_argument
          && has_equal) {
         if (PRINT_ERROR)
            warnx(noarg, (int)current_argv_len,
                 current_argv);
         /*
          * XXX: GNU sets optopt to val regardless of flag
          */
         if (long_options[match].flag == NULL)
            optopt = long_options[match].val;
         else
            optopt = 0;
         return (BADARG);
      }
      if (long_options[match].has_arg == required_argument ||
          long_options[match].has_arg == optional_argument) {
         if (has_equal)
            optarg = has_equal;
         else if (long_options[match].has_arg ==
             required_argument) {
            /*
             * optional argument doesn't use next nargv
             */
            optarg = nargv[optind++];
         }
      }
      if ((long_options[match].has_arg == required_argument)
          && (optarg == NULL)) {
         /*
          * Missing argument; leading ':' indicates no error
          * should be generated.
          */
         if (PRINT_ERROR)
            warnx(recargstring,
                current_argv);
         /*
          * XXX: GNU sets optopt to val regardless of flag
          */
         if (long_options[match].flag == NULL)
            optopt = long_options[match].val;
         else
            optopt = 0;
         --optind;
         return (BADARG);
      }
   } else {         /* unknown option */
      if (short_too) {
         --optind;
         return (-1);
      }
      if (PRINT_ERROR)
         warnx(illoptstring, current_argv);
      optopt = 0;
      return (BADCH);
   }
   if (idx)
      *idx = match;
   if (long_options[match].flag) {
      *long_options[match].flag = long_options[match].val;
      return (0);
   } else
      return (long_options[match].val);
#undef IDENTICAL_INTERPRETATION
}

/*
 * getopt_internal --
 *   Parse argc/argv argument vector.  Called by user level routines.
 */
static int
getopt_internal(int nargc, char * const *nargv, const char *options,
   const struct option *long_options, int *idx, int flags)
{
   char *oli;            /* option letter list index */
   int optchar, short_too;
   static int posixly_correct = -1;

   if (options == NULL)
      return (-1);

   /*
    * XXX Some GNU programs (like cvs) set optind to 0 instead of
    * XXX using optreset.  Work around this braindamage.
    */
   if (optind == 0)
      optind = optreset = 1;

   /*
    * Disable GNU extensions if POSIXLY_CORRECT is set or options
    * string begins with a '+'.
    *
    * CV, 2009-12-14: Check POSIXLY_CORRECT anew if optind == 0 or
    *                 optreset != 0 for GNU compatibility.
    */
   if (posixly_correct == -1 || optreset != 0)
      posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
   if (*options == '-')
      flags |= FLAG_ALLARGS;
   else if (posixly_correct || *options == '+')
      flags &= ~FLAG_PERMUTE;
   if (*options == '+' || *options == '-')
      options++;

   optarg = NULL;
   if (optreset)
      nonopt_start = nonopt_end = -1;
start:
   if (optreset || !*place) {      /* update scanning pointer */
      optreset = 0;
      if (optind >= nargc) {          /* end of argument vector */
         place = EMSG;
         if (nonopt_end != -1) {
            /* do permutation, if we have to */
            permute_args(nonopt_start, nonopt_end,
                optind, nargv);
            optind -= nonopt_end - nonopt_start;
         }
         else if (nonopt_start != -1) {
            /*
             * If we skipped non-options, set optind
             * to the first of them.
             */
            optind = nonopt_start;
         }
         nonopt_start = nonopt_end = -1;
         return (-1);
      }
      if (*(place = nargv[optind]) != '-' ||
          (place[1] == '\0' && strchr(options, '-') == NULL)) {
         place = EMSG;      /* found non-option */
         if (flags & FLAG_ALLARGS) {
            /*
             * GNU extension:
             * return non-option as argument to option 1
             */
            optarg = nargv[optind++];
            return (INORDER);
         }
         if (!(flags & FLAG_PERMUTE)) {
            /*
             * If no permutation wanted, stop parsing
             * at first non-option.
             */
            return (-1);
         }
         /* do permutation */
         if (nonopt_start == -1)
            nonopt_start = optind;
         else if (nonopt_end != -1) {
            permute_args(nonopt_start, nonopt_end,
                optind, nargv);
            nonopt_start = optind -
                (nonopt_end - nonopt_start);
            nonopt_end = -1;
         }
         optind++;
         /* process next argument */
         goto start;
      }
      if (nonopt_start != -1 && nonopt_end == -1)
         nonopt_end = optind;

      /*
       * If we have "-" do nothing, if "--" we are done.
       */
      if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
         optind++;
         place = EMSG;
         /*
          * We found an option (--), so if we skipped
          * non-options, we have to permute.
          */
         if (nonopt_end != -1) {
            permute_args(nonopt_start, nonopt_end,
                optind, nargv);
            optind -= nonopt_end - nonopt_start;
         }
         nonopt_start = nonopt_end = -1;
         return (-1);
      }
   }

   /*
    * Check long options if:
    *  1) we were passed some
    *  2) the arg is not just "-"
    *  3) either the arg starts with -- we are getopt_long_only()
    */
   if (long_options != NULL && place != nargv[optind] &&
       (*place == '-' || (flags & FLAG_LONGONLY))) {
      short_too = 0;
      if (*place == '-')
         place++;      /* --foo long option */
      else if (*place != ':' && strchr(options, *place) != NULL)
         short_too = 1;      /* could be short option too */

      optchar = parse_long_options(nargv, options, long_options,
          idx, short_too);
      if (optchar != -1) {
         place = EMSG;
         return (optchar);
      }
   }

   if ((optchar = (int)*place++) == (int)':' ||
       (optchar == (int)'-' && *place != '\0') ||
       (oli = (char*)strchr(options, optchar)) == NULL) {
      /*
       * If the user specified "-" and  '-' isn't listed in
       * options, return -1 (non-option) as per POSIX.
       * Otherwise, it is an unknown option character (or ':').
       */
      if (optchar == (int)'-' && *place == '\0')
         return (-1);
      if (!*place)
         ++optind;
      if (PRINT_ERROR)
         warnx(illoptchar, optchar);
      optopt = optchar;
      return (BADCH);
   }
   if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
      /* -W long-option */
      if (*place)         /* no space */
         /* NOTHING */;
      else if (++optind >= nargc) {   /* no arg */
         place = EMSG;
         if (PRINT_ERROR)
            warnx(recargchar, optchar);
         optopt = optchar;
         return (BADARG);
      } else            /* white space */
         place = nargv[optind];
      optchar = parse_long_options(nargv, options, long_options,
          idx, 0);
      place = EMSG;
      return (optchar);
   }
   if (*++oli != ':') {         /* doesn't take argument */
      if (!*place)
         ++optind;
   } else {            /* takes (optional) argument */
      optarg = NULL;
      if (*place)         /* no white space */
         optarg = place;
      else if (oli[1] != ':') {   /* arg not optional */
         if (++optind >= nargc) {   /* no arg */
            place = EMSG;
            if (PRINT_ERROR)
               warnx(recargchar, optchar);
            optopt = optchar;
            return (BADARG);
         } else
            optarg = nargv[optind];
      }
      place = EMSG;
      ++optind;
   }
   /* dump back option letter */
   return (optchar);
}

/*
 * getopt_long --
 *   Parse argc/argv argument vector.
 */
int
getopt_long(int nargc, char * const *nargv, const char *options,
    const struct option *long_options, int *idx)
{

   return (getopt_internal(nargc, nargv, options, long_options, idx,
       FLAG_PERMUTE));
}

/*
 * getopt_long_only --
 *   Parse argc/argv argument vector.
 */
int
getopt_long_only(int nargc, char * const *nargv, const char *options,
    const struct option *long_options, int *idx)
{

   return (getopt_internal(nargc, nargv, options, long_options, idx,
       FLAG_PERMUTE|FLAG_LONGONLY));
}

//extern int getopt_long(int nargc, char * const *nargv, const char *options,
//    const struct option *long_options, int *idx);
//extern int getopt_long_only(int nargc, char * const *nargv, const char *options,
//    const struct option *long_options, int *idx);
/*
 * Previous MinGW implementation had...
 */
#ifndef HAVE_DECL_GETOPT
/*
 * ...for the long form API only; keep this for compatibility.
 */
# define HAVE_DECL_GETOPT   1
#endif

#ifdef __cplusplus
}
#endif

#endif /* !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) */


Ahora usando "Menú: Project -> Add to Project..." añadimos todos los archivos ".c" a nuestro proyecto, los que están dentro del subdirectorio "libGIS-1.0.5" también.

En el archivo "ui.c" añade la siguiente línea al principio:

#define strcasecmp stricmp

Este es el resultado de ejecutar "vpicdisasm.exe --original PIC16F84A.production.hex":

Código: Seleccionar todo

   0:   16 83      bsf 0x03, 5
   1:   01 86      clrf 0x06
   2:   30 1F      movlw 0x1F
   3:   00 85      movwf 0x05
   4:   12 83      bcf 0x03, 5
   5:   10 06      bcf 0x06, 0
   6:   18 05      btfsc 0x05, 0
   7:   28 06      goto 0x006
   8:   20 36      call 0x036
   9:   18 05      btfsc 0x05, 0
   A:   28 06      goto 0x006
   B:   28 0F      goto 0x00F
   C:   1C 05      btfss 0x05, 0
   D:   28 0C      goto 0x00C
   E:   28 06      goto 0x006
   F:   1C 0C      btfss 0x0C, 0
  10:   28 12      goto 0x012
  11:   28 16      goto 0x016
  12:   10 06      bcf 0x06, 0
  13:   30 01      movlw 0x1
  14:   00 8C      movwf 0x0C
  15:   28 06      goto 0x006
  16:   14 06      bsf 0x06, 0
  17:   01 8C      clrf 0x0C
  18:   28 06      goto 0x006
  19:   00 00      nop
  1A:   00 00      nop
  1B:   00 00      nop
  1C:   00 00      nop
  1D:   00 00      nop
  1E:   00 00      nop
  1F:   00 08      return
  20:   00 00      nop
  21:   30 A4      movlw 0xA4
  22:   28 2C      goto 0x02C
  23:   00 00      nop
  24:   30 40      movlw 0x40
  25:   28 2C      goto 0x02C
  26:   30 1F      movlw 0x1F
  27:   28 2C      goto 0x02C
  28:   00 00      nop
  29:   30 0E      movlw 0xE
  2A:   28 2C      goto 0x02C
  2B:   30 05      movlw 0x5
  2C:   00 8D      movwf 0x0D
  2D:   0B 8D      decfsz 0x0D, F
  2E:   28 2D      goto 0x02D
  2F:   00 08      return
  30:   30 C8      movlw 0xC8
  31:   28 3F      goto 0x03F
  32:   30 64      movlw 0x64
  33:   28 3F      goto 0x03F
  34:   30 32      movlw 0x32
  35:   28 3F      goto 0x03F
  36:   30 14      movlw 0x14
  37:   28 3F      goto 0x03F
  38:   30 0A      movlw 0xA
  39:   28 3F      goto 0x03F
  3A:   30 05      movlw 0x5
  3B:   28 3F      goto 0x03F
  3C:   30 02      movlw 0x2
  3D:   28 3F      goto 0x03F
  3E:   30 01      movlw 0x1
  3F:   00 8E      movwf 0x0E
  40:   30 F9      movlw 0xF9
  41:   00 8D      movwf 0x0D
  42:   00 00      nop
  43:   0B 8D      decfsz 0x0D, F
  44:   28 42      goto 0x042
  45:   0B 8E      decfsz 0x0E, F
  46:   28 40      goto 0x040
  47:   00 08      return
  48:   30 C8      movlw 0xC8
  49:   28 53      goto 0x053
  4A:   30 64      movlw 0x64
  4B:   28 53      goto 0x053
  4C:   30 32      movlw 0x32
  4D:   28 53      goto 0x053
  4E:   30 14      movlw 0x14
  4F:   28 53      goto 0x053
  50:   30 0A      movlw 0xA
  51:   28 53      goto 0x053
  52:   30 05      movlw 0x5
  53:   00 8F      movwf 0x0F
  54:   30 64      movlw 0x64
  55:   00 8E      movwf 0x0E
  56:   30 F9      movlw 0xF9
  57:   00 8D      movwf 0x0D
  58:   00 00      nop
  59:   0B 8D      decfsz 0x0D, F
  5A:   28 58      goto 0x058
  5B:   0B 8E      decfsz 0x0E, F
  5C:   28 56      goto 0x056
  5D:   0B 8F      decfsz 0x0F, F
  5E:   28 54      goto 0x054
  5F:   00 08      return
2007:   3F F1      addlw 0xF1

Responder Con Cita Multi-Respuesta Respuesta rápida a este mensaje
  #7   Agregar a la Reputación de REHome   Reportar Mensaje 
Antiguo Hace 1 Hora


Como puedes ver, te descompila las instrucciones pero no los operando. Cosa que estoy haciendo desde cero con C#. Ahora mismo haciendo diccionarios de los OP CODE de las instrucciones y registros. Solo eso me estoy pegando media vida y del PIC16F84A que no tiene mucho comparado con otros PIC conocidos.

Seguiré informando según voy avanzando. Eso si, lo primero que hago es un descompilador más detallado, que se entienda por el hombre. ;)

Saludos.

BlackHole
Amiga 1200
Amiga 1200
Mensajes: 1442
Registrado: 07 Nov 2009, 11:38
Sistema Favorito: C64
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: Nintendo SNES
Primera consola: Nintendo SNES
Ubicación: Madrid
Gracias dadas: 9 veces
Gracias recibidas: 209 veces

Re: Binario en el asm de los PIC

Mensajepor BlackHole » 20 Ago 2017, 14:12

Pero... ¿eso no es un desensamblador? Yo por descompilador entiendo otra cosa completamente diferente.

Un descompilador supuestamente te debería proporcionar un código fuente en un lenguaje de alto nivel como BASIC o C, ¿no?
No necesariamente el código fuente original, pero sí uno compatible que al recompilar obtuviese un binario que se comportase igual.

Por eso son tan jodidamente difíciles de encontrar y programar...

REHome
Amstrad PCW 8256
Amstrad PCW 8256
Mensajes: 145
Registrado: 19 Abr 2013, 22:01
Sistema Favorito: Spectrum +2
primer_sistema: Spectrum +2
Gracias dadas: 3 veces
Gracias recibidas: 2 veces

Re: Binario en el asm de los PIC

Mensajepor REHome » 20 Ago 2017, 15:43

Exato, es desensamblar.No me he expresado bien.

Es como confundir con simulador con emulador.

Diferencia entre emular y simular:

Simular fingir una cosa.
Ella simuló que hablaba por teléfono con alguien para que los periodistas no la molestaran.
Durante un tiempo simuló no darse cuenta de que él la engañaba.
Ellos siempre simularon ser una pareja feliz.

Emular Imitar lo que otro hace, procurando aventajarlo.
Ejemplo: Lo admiraba tanto que siempre lo emuló. Sentimiento que nos impulsa a rivalizar con algunos o con alguna cosa.
Ejemplo:La emulación es un aliciente muy poderoso para la virtud.


Emulador:
En informática, un emulador es un software que permite ejecutar programas de computadora o videojuegos en una plataforma (arquitectura hardware o sistema operativo) diferente de aquella para la cual fueron escritos originalmente.

Simulador:
El simulador sólo trata de reproducir el comportamiento del programa.

Diferencia entre emulador y simulador

Un simulador, que sólo trata de reproducir el comportamiento del programa, un emulador trata de modelar de forma precisa el dispositivo de manera que este funcione como si estuviese siendo usado en el aparato original.

Estructura:
La mayoría de los emuladores solo emulan una determinada configuración arquitectura de hardware - si el sistema de explotación (o sistema operativo) también se requiere para emular cierto programa entonces ha de ser emulado también. Tanto el sistema de explotación como el programa deben ser interpretados por el emulador, como si estuviese ejecutándose en el equipo original.


Sigo haciendo lista de diccionario en C#, como tarda solo hacer esto. No te puedes equivocar ni un bit.

Primero hacer un desensamblador completo del PIC16F84A. Que desensamble bien. Luego sigo con lo que tenía previsto desde el principio. Sigo diciendo que este requiere mucho, mucho, mucho tiempo.

Les diré cuando siga avanzando. Gracias por la aclaración.

Que tengan buen fin de semana.

Avatar de Usuario
explorer
MSX Turbo R
MSX Turbo R
Mensajes: 398
Registrado: 11 May 2014, 17:10
Sistema Favorito: Atari ST
primer_sistema: Atari 800XL/600XL
consola_favorita: Atari 2600
Primera consola: Atari 2600
Ubicación: Valladolid, España
Gracias dadas: 2 veces
Gracias recibidas: 138 veces
Contactar:

Re: Binario en el asm de los PIC

Mensajepor explorer » 21 Ago 2017, 00:14

Hasta ahora has asumido que

00 10001000 0110

lo puedes desensamblar en

MOVF PORTB, W

Pero... ¿ya sabes que realmente no es tan sencillo?

Esa misma combinación de bits también la puedes desensamblar así:

MOVF TRISB, W

¿Por qué? Pues porque depende del estado del bit 5 (RP0) del registro de estado (dirección 03h). En otras palabras: qué banco esté seleccionado (el PIC16F84A tiene dos bancos).

Ejemplo. Del desensamblado último que has publicado, estas son las primeras líneas:

Código: Seleccionar todo

   0:   16 83      bsf 0x03, 5
   1:   01 86      clrf 0x06
   2:   30 1F      movlw 0x1F
   3:   00 85      movwf 0x05
   4:   12 83      bcf 0x03, 5
   5:   10 06      bcf 0x06, 0

que, haciendo la traducción correcta de los operandos, queda:

Código: Seleccionar todo

   0:   16 83      bsf STATUS, RP0    ; pasar al banco 1
   1:   01 86      clrf TRISB         ; poner todas las líneas de PORTB como salidas
   2:   30 1F      movlw 0x1F         ; poner todas las líneas de PORTA como entradas
   3:   00 85      movwf TRISA
   4:   12 83      bcf STATUS, RP0    ; pasar al banco 0
   5:   10 06      bcf PORTB, 0       ; poner a 0 la salida del bit 0 de PORTB

Observa que en las líneas 1 y 5 se hace referencia a 0x06, pero según estemos en un banco u otro, estaremos hablando de PORTB o TRISB.

REHome
Amstrad PCW 8256
Amstrad PCW 8256
Mensajes: 145
Registrado: 19 Abr 2013, 22:01
Sistema Favorito: Spectrum +2
primer_sistema: Spectrum +2
Gracias dadas: 3 veces
Gracias recibidas: 2 veces

Re: Binario en el asm de los PIC

Mensajepor REHome » 21 Ago 2017, 03:07

Buenas:

Lo que cuentas lo tengo en cuenta, como no voy hacer un emulador, pues...

Poner PORTB directamente es como llamarle TRISB, por eso al configurar los pines de entrada o salida no hace falta mencionar nunca los TRIS, con solo nombrar PORT basta.

No me gusta nada el desemsamblado así:

Código: Seleccionar todo

   0:   16 83      bsf 0x03, 5
   1:   01 86      clrf 0x06
   2:   30 1F      movlw 0x1F
   3:   00 85      movwf 0x05
   4:   12 83      bcf 0x03, 5
   5:   10 06      bcf 0x06, 0


Lo estamos haciendo así:
0: 16 83 bsf STATUS, RP0 ; pasar al banco 1
1: 01 86 clrf TRISB ; poner todas las líneas de PORTB como salidas
2: 30 1F movlw 0x1F ; poner todas las líneas de PORTA como entradas
3: 00 85 movwf TRISA
4: 12 83 bcf STATUS, RP0 ; pasar al banco 0
5: 10 06 bcf PORTB, 0 ; poner a 0 la salida del bit 0 de PORTB


Tal como lo has escrito.

Hay ciertas áres de las instrucciones que debo hacer máscaras pra capturar los bbb del BCF por poner un ejemplo.

Código: Seleccionar todo

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Desplazamiento_bit_Consola_cs
{
    class Program
    {
        static void Main(string[] args)
        {
            // Valor a manipular.
            // 01001010000110 = 01 00bb bfff ffff cogemos las b.
            const int i = 0x1286;  // 01 0010 1000 0110 bin es 1286 en hex.

            int bbb = (i & 0x0380) >> 7; // Máscara 00 0011 1000 0000 bin es 0380 en hex.

            Console.WriteLine("0x{0:X2}",bbb); // Muestra 5 en la pantalla. Bin 101.

            // Siguiendo probando.
            int fffffff = (i & 0x007F) >> 0; // Máscara 00 0000 0111 1111 bin. Hex es 007F.

            Console.WriteLine("0x{0:X2}", fffffff); // Muestra 5 en la pantalla. Bin 101.

            Console.ReadKey(); // Pulsar cualquier tecla para salir.
        }
    }
}


Le voy pillando el truco.

Si tengo esto.

01001010000110

Quiero capturar los 7 bit más bajo.

0100101fffffff

Creo una máscara

0100101fffffff
01001011111111 // Máscara. Hex es 0x007F.
01001010000110 // Me quedo con 00001100 que en hex es 0x06.

int fffffff = (i & 0x007F) >> 0;

En este caso, como el desplazamiento es >> 0, no desplaza nada, obtenemos el 0x06.

¿Me equivoco?

Creando los diccionarios en una lista.

Código: Seleccionar todo

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Descompilar_02_cs
{
    class Instrucciones
    {
        // Diccionarios.
        private Dictionary<int, string> orientadoBytes = new Dictionary<int, string>();
        private Dictionary<int, string> orientadoBits = new Dictionary<int, string>();
        private Dictionary<int, string> controlLiteral = new Dictionary<int, string>();
        private Dictionary<int, string> saltos = new Dictionary<int, string>();

        public Instrucciones()
        {
            // Llamar funcionar.
            Orientado_Bytes();
            Orientado_Bits();
            Control_Literal();
            Saltos();
        }

        #region Llamar conjuntos de instrucciones.
        public string GetorientadoBytes(int value)
        {
            return orientadoBytes[value];
        }

        public string GetorientadoBits(int value)
        {
            return orientadoBits[value];
        }

        public string GetcontrolLiteral(int value)
        {
            return controlLiteral[value];
        }

        public string GetSaltos(int value)
        {
            return saltos[value];
        }

        #endregion

        // OP CODE, códigos de operaciones.
        #region Instrucciones orientadas a registros.
        private void Orientado_Bytes()
        {
            // orientadoBytes[0x00] = MOVWF y NOP  Al descompilar.
            // orientadoBytes[0x01] = CLRF y CLRW  Al descompilar.

            orientadoBytes[0x02] = "SUBWF";     // 00 0010 dfffffff.
            orientadoBytes[0x03] = "DECF";      // 00 0011 dfffffff.
            orientadoBytes[0x04] = "IORWF";     // 00 0100 dfffffff.
            orientadoBytes[0x05] = "ANDWF";     // 00 0101 dfffffff.
            orientadoBytes[0x06] = "XORWF";     // 00 0110 dfffffff.
            orientadoBytes[0x07] = "ADDWF";     // 00 0111 dfffffff.
            orientadoBytes[0x08] = "MOVF";      // 00 1000 dfffffff.
            orientadoBytes[0x09] = "COMF";      // 00 1001 dfffffff.
            orientadoBytes[0x0A] = "INCF";      // 00 1010 dfffffff.
            orientadoBytes[0x0B] = "DECFSZ";    // 00 1011 dfffffff.
            orientadoBytes[0x0C] = "RRF";       // 00 1100 dfffffff.
            orientadoBytes[0x0D] = "RLF";       // 00 1101 dfffffff.
            orientadoBytes[0x0E] = "SWAPF";     // 00 1110 dfffffff.
            orientadoBytes[0x0F] = "INCFSZ";    // 00 1111 dfffffff.
        }
        #endregion

        #region Instrucciones orientadas al bit.

        private void Orientado_Bits()
        {
            orientadoBits[0x04] = "BCF";        // 01 00bb bfffffff.
            orientadoBits[0x05] = "BSF";        // 01 01bb bfffffff.
            orientadoBits[0x06] = "BTFSC";      // 01 10bb bfffffff.
            orientadoBits[0x07] = "BTFSS";      // 01 11bb bfffffff.
        }
        #endregion

        #region Instrucciones literales y control.
        private void Control_Literal()
        {
            controlLiteral[0x1F] = "ADDLW";     // 11 111x kkkk kkkk.
            controlLiteral[0x39] = "ANDLW";     // 11 1001 kkkk kkkk.
            controlLiteral[0x64] = "CLRWDT";    // 00 0000 0110 0100.
            controlLiteral[0x38] = "IORLW";     // 11 1000 kkkk kkkk.
            controlLiteral[0x0C] = "MOVLW";     // 11 00xx kkkk kkkk.
            controlLiteral[0x09] = "RETFIE";    // 00 0000 0000 1001.
            controlLiteral[0x0D] = "RETLW";     // 11 01xx kkkk kkkk.
            controlLiteral[0x08] = "RETURN";    // 00 0000 0000 1000.
            controlLiteral[0x63] = "SLEEP";     // 00 0000 0110 0011.
            controlLiteral[0x1E] = "SUBLW";     // 11 110x kkkk kkkk.
            controlLiteral[0x3A] = "XORLW";     // 11 1010 kkkk kkkk.
        }
        #endregion

        #region Instrucciones de saltos.
        private void Saltos()
        {
            saltos[0x04] = "CALL";              // 10 0kkk kkkk kkkk.
            saltos[0x05] = "GOTO";              // 10 1kkk kkkk kkkk.
        }
        #endregion
    }
}


Saludos.


Volver a “Emuladores”

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 5 invitados