Binario en el asm de los PIC
- explorer
- MSX Turbo R
- Mensajes: 400
- 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
Me refería que el significado de los bits más bajos cambia según sean los bits más altos.
La CALL destino, por ejemplo, que sería
100 kkk kkkk kkkk
La CALL destino, por ejemplo, que sería
100 kkk kkkk kkkk
-
- 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
Ahora que me fijo bien, no solo está las x qu epueden ser 1 ó 0, da igual su valor.
Tanto como las f como las d. Hablando de las k, también están las b.
Pues todo eso hay que tenerlo en cuenta.
00001000 1 000 0110
MOVF H'0006', H'0001'
MOVF PORTB, F
switch(byte)
{
case 0x0886
printf("nemonico fulano");
break;
....
}
Ni más case hay que hacer.
08 son las intrucciones como sabrás y el conjunto del W y F más el PORTB es el 66
case 0x0886.
Fácil por ahora.
Tanto como las f como las d. Hablando de las k, también están las b.
Pues todo eso hay que tenerlo en cuenta.
00001000 1 000 0110
MOVF H'0006', H'0001'
MOVF PORTB, F
switch(byte)
{
case 0x0886
printf("nemonico fulano");
break;
....
}
Ni más case hay que hacer.
08 son las intrucciones como sabrás y el conjunto del W y F más el PORTB es el 66
case 0x0886.
Fácil por ahora.
- explorer
- MSX Turbo R
- Mensajes: 400
- 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
Como las instrucciones tienen 14 bits, yo primero dividiría el problema en sacar los dos bits más altos y luego los cuatro siguientes.
Viendo la tabla 7-2 verás que los dos primeros agrupan las instrucciones en tres grupos. Y los cuatro bits siguientes (a veces, solo dos) definen la instrucción en concreto, dejando el resto de bits para indicar destino y operando.
Viendo la tabla 7-2 verás que los dos primeros agrupan las instrucciones en tres grupos. Y los cuatro bits siguientes (a veces, solo dos) definen la instrucción en concreto, dejando el resto de bits para indicar destino y operando.
- explorer
- MSX Turbo R
- Mensajes: 400
- 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
No sé el lenguaje que vas a usar, pero en una especie de pseudo lenguaje, sería algo así:
Código: Seleccionar todo
bits1413 = (0b11_0000_0000_0000 & opcode) >> 12; // extraemos los dos bits superiores
switch (bits1413) {
case 0b00:
// en este caso, el tercer nibble es la operación, el bit 7 es la suboperación o destino, y el resto, el operando
nibble3 = (0b00_1111_0000_0000 & opcode) >> 8;
bit7 = (0b00_0000_1000_0000 & opcode) >> 7;
operando = (0b00_0000_0111_1111 & opcode);
switch (bit7) {
case 0:
reg = 'W';
break;
case 1;
reg = 'F';
break;
}
switch (nibble3) {
case 0x0:
switch (bit7) {
case 1:
printf("MOVWF %x\n", operando);
break;
case 0;
// aquí pueden ocurrir varios casos, según el primer nibble
nibble1 = (0b00_0000_0000_1111 & opcode);
switch (nibble1) {
case 0x0:
printf("NOP\n");
break;
case 0x4:
printf("CLRWDT\n");
break;
case 0x9:
printf("RETFIE\n");
break;
case 0x8:
printf("RETURN\n");
break;
case 0x3:
printf("SLEEP\n");
break;
}
break;
}
break;
case 0x1:
switch (bit7) {
case 0:
printf("CLRW\n");
break;
case 1;
printf("CLRF %x\n", operando);
break;
}
break;
case 0x2:
printf("SUBWF %x,%c\n", operando, reg);
break;
case 0x3:
printf("DECF %x,%c\n", operando, reg);
break;
case 0x4:
printf("IORWF %x,%c\n", operando, reg);
break;
case 0x5:
printf("ANDWF %x,%c\n", operando, reg);
break;
case 0x6:
printf("XORWF %x,%c\n", operando, reg);
break;
case 0x7:
printf("ADDWF %x,%c\n", operando, reg);
break;
case 0x8:
printf("MOVF %x,%c\n", operando, reg);
break;
case 0x9:
printf("COMF %x,%c\n", operando, reg);
break;
case 0xA:
printf("INCF %x,%c\n", operando, reg);
break;
case 0xB:
printf("DECFSZ %x,%c\n", operando, reg);
break;
case 0xC:
printf("RRF %x,%c\n", operando, reg);
break;
case 0xD:
printf("RLF %x,%c\n", operando, reg);
break;
case 0xE:
printf("SWAPF %x,%c\n", operando, reg);
break;
case 0xF:
printf("INCFSZ %x,%c\n", operando, reg);
break;
}
break;
case 0b01:
// 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 operando
subop = (0b00_1100_0000_0000 & opcode) >> 10;
bit = (0b00_0011_1000_0000 & opcode) >> 7;
operando = (0b00_0000_0111_1111 & opcode);
switch (subop) {
case 0x0;
printf("BCF %x,%d\n", operando, bit);
break;
case 0x1;
printf("BSF %x,%d\n", operando, bit);
break;
case 0x2;
printf("BTFSC %x,%d\n", operando, bit);
break;
case 0x3;
printf("BTFSS %x,%d\n", operando, bit);
break;
}
break;
case 0b10:
// ver el bit 12. El resto es el operando
bit12 = (0b00_1000_0000_0000 & opcode) >> 11;
operando = (0b00_0111_1111_1111 & opcode);
switch (bit12) {
case 0:
printf("CALL %x\n", operando);
break;
case 1:
printf("GOTO %x\n", operando);
break;
}
break;
case 0b11:
// el tercer nibble es la suboperación, y el resto, el operando
nibble3 = (0b00_1111_0000_0000 & opcode) >> 8;
operando = (0b00_0000_1111_1111 & opcode);
switch (nibble3) {
case 0b0000:
case 0b0001:
case 0b0010:
case 0b0011:
printf("MOVLW %x\n", operando);
break;
case 0b0100:
case 0b0101:
case 0b0110:
case 0b0111:
printf("RETLW %x\n", operando);
break;
case 0b1000:
printf("IORLW %x\n", operando);
break;
case 0b1001:
printf("ANDLW %x\n", operando);
break;
case 0b1010:
printf("XORLW %x\n", operando);
break;
case 0b1100:
case 0b1101:
printf("SUBLW %x\n", operando);
break;
case 0b1110:
case 0b1111:
printf("ADDLW %x\n", operando);
break;
}
break;
}
-
- 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
Buenas:
Menudo curro te haz pegado con el programa. Felicidades.
Suelo trabajar en C#.
Si tengo este programa del PIC16F84A ya compilado. Su hex queda así:
Saber más sobre del hex.
https://es.wikipedia.org/wiki/Intel_HEX
En la librerta o en un folio escribo estas intrucciones. Lo qu ehace es encender y apagar un Led con el mismo pulsador y tiene antirrebotes.
Código en asm:
Como puedes ver, hay que tener en cuenta esto del código:
INCLUDE <P16F84A.INC>
Que es la lista externa ya indicada aquí. Más el otro archivo externo llamado INCLUDE <RETARDOS.INC>, todo esto tiene que estar en un mismo archivo como se hacía antes.
Como voy hacer un simulador primero en la consola de C#, si funciona, diseño y monto físicamente programar el PIC16F84A a base de binario y físicamente. Se que es una tontería pero es un retillo y curiosidad, .
Algo ya han hecho con Arduino.
https://create.arduino.cc/projecthub/da ... tor-3594a6
Analizando tu pseudo, pensé que ibas atacar el nibble más bajo. viendo la tabla, hay 3 tipos. Traduje la tabla.
Saludos.
Menudo curro te haz pegado con el programa. Felicidades.
Suelo trabajar en C#.
Si tengo este programa del PIC16F84A ya compilado. Su hex queda así:
Código: Seleccionar todo
:020000040000FA
:10000000831686011F308500831206100518062806
:10001000051806280E28051C0B2806280C1C11287C
:100020001528061001308C00062806148C010628BD
:1000300000000000000000000000000008000000B8
:10004000A4302B28000040302B281F302B28000024
:100050000E302B2805308D008D0B2C280800C83061
:100060003E2864303E2832303E2814303E280A3084
:100070003E2805303E2802303E2801308E00F930FF
:100080008D0000008D0B41288E0B3F280800C830E2
:1000900052286430522832305228143052280A3004
:1000A000522805308F0064308E00F9308D0000003A
:0E00B0008D0B57288E0B55288F0B53280800F8
:02400E00F13F80
:00000001FF
Saber más sobre del hex.
https://es.wikipedia.org/wiki/Intel_HEX
En la librerta o en un folio escribo estas intrucciones. Lo qu ehace es encender y apagar un Led con el mismo pulsador y tiene antirrebotes.
Código en asm:
Código: Seleccionar todo
; ZONA DE DATOS **********************************************************************
LIST P=16F84A
INCLUDE <P16F84A.INC>
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
CBLOCK 0x0C
Flag
ENDC
; ZONA DE CÓDIGOS ********************************************************************
ORG 0 ; El programa comienza en la dirección 0.
Inicio
bsf STATUS,RP0 ; Acceso al Banco 1.
clrf PORTB ; Las líneas del Puerto B se configuran como salida.
movlw b'00011111' ; Las 5 líneas del Puerto A se configuran como entrada.
movwf PORTA
bcf STATUS,RP0 ; Acceso al Banco 0.
bcf PORTB,0
Principal
btfsc PORTA,0 ; ¿Pulsador presionado?, ¿(Pulsador)=0?
goto Principal ; No. Vuelve a leerlo.
; call Retardo_20ms ; Espera que se estabilicen los niveles de tensión.
btfsc PORTA,0 ; Comprueba si es un rebote.
goto Principal ; Era rebote y sale fuera.
goto Led
EsperaDejePulsar
btfss PORTA,0 ; ¿Dejó de pulsar?, ¿(Pulsador)=1?
goto EsperaDejePulsar ; No. Espere que deje de pulsar.
goto Principal
Led
btfss Flag,0
goto Led_OFF
goto Led_ON
Led_OFF
bcf PORTB,0
movlw .1
movwf Flag
goto Principal
Led_ON
bsf PORTB,0
clrf Flag
goto Principal
INCLUDE <RETARDOS.INC>
END
Como puedes ver, hay que tener en cuenta esto del código:
INCLUDE <P16F84A.INC>
Que es la lista externa ya indicada aquí. Más el otro archivo externo llamado INCLUDE <RETARDOS.INC>, todo esto tiene que estar en un mismo archivo como se hacía antes.
Como voy hacer un simulador primero en la consola de C#, si funciona, diseño y monto físicamente programar el PIC16F84A a base de binario y físicamente. Se que es una tontería pero es un retillo y curiosidad, .
Algo ya han hecho con Arduino.
https://create.arduino.cc/projecthub/da ... tor-3594a6
Analizando tu pseudo, pensé que ibas atacar el nibble más bajo. viendo la tabla, hay 3 tipos. Traduje la tabla.
Saludos.
-
- 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
@explorer
¿Entiendes el Java?
Mi idea es adaptar tu pseudocódigo a C#, primero por mis amigos lo haremos a Java, si todo funciona de maravilla, lo adaptamos también al C#, C++ CLR y VB .net en modo consola.
Para dejarlo más ordenado ya que hay gente leyendo este tema,lo pongo en resumen y depaso no me llegan tantas preguntas en privado cuando lo pueden hacer por aquí.
Hoja de datos PIC16F84A:
Ver enlace.
Página 22. Organización de la memoria de datos:
El archivo p16f84a.inc que encuentras en el directorio en mi caso cuando instalé MPLAB X v4.00.
C:\Program Files (x86)\Microchip\MPLABX\v4.00\mpasmx
p16f84aa.inc:
Página 35. SISTEMA DE INSTRUCCIONES:
Para dejarlo mejor explicado, cogemos por ejemplo el registro MOVF que puedes ver en l apágin a36 de la hoja de datos del PIC16F84A.
Como podrás ver en la tabla, MOVF corresponde al 00 1000, o lo que es lo mismo, añadir dos ceros más al principio, 00001000.
El registro PORTB que muestra en el archivo p16f84a.inc:
Del hexadecimal H'0006' al binario es: 000 0110
Mirando el archivo p16f84a.inc de arriba:
Elegimos la F que corresponde guardar en el propio registro, es un 1. La d es el lugar de destino, W que equivale a 0 se guarda en el registro de trabajo. La F que equivale a 1 se guarda en el registro.
En resumen:
MOVF PORTB, F
MOVF H'0006', H'0001'
00001000 1 000 0110
Pseudocódigo de nuestro compañero del foro explorer:
Yo y un amigo lo valos a traducir por el momento a Java que es el que entiende mejor, luego haré en otros lenguajes para quien le guste, como dije arriba, C#, C++ CLR y VB .net.
Si no tienen algo claro, avisen.
Un cordial saludo.
¿Entiendes el Java?
Mi idea es adaptar tu pseudocódigo a C#, primero por mis amigos lo haremos a Java, si todo funciona de maravilla, lo adaptamos también al C#, C++ CLR y VB .net en modo consola.
Para dejarlo más ordenado ya que hay gente leyendo este tema,lo pongo en resumen y depaso no me llegan tantas preguntas en privado cuando lo pueden hacer por aquí.
Hoja de datos PIC16F84A:
Ver enlace.
Página 22. Organización de la memoria de datos:
El archivo p16f84a.inc que encuentras en el directorio en mi caso cuando instalé MPLAB X v4.00.
C:\Program Files (x86)\Microchip\MPLABX\v4.00\mpasmx
p16f84aa.inc:
Código: Seleccionar todo
LIST
;==========================================================================
; Build date : May 17 2017
; MPASM PIC16F84A processor include
;
; (c) Copyright 1999-2017 Microchip Technology, All rights reserved
;==========================================================================
NOLIST
;==========================================================================
; This header file defines configurations, registers, and other useful
; bits of information for the PIC16F84A microcontroller. These names
; are taken to match the data sheets as closely as possible.
;
; Note that the processor must be selected before this file is included.
; The processor may be selected the following ways:
;
; 1. Command line switch:
; C:\MPASM MYFILE.ASM /PIC16F84A
; 2. LIST directive in the source file
; LIST P=PIC16F84A
; 3. Processor Type entry in the MPASM full-screen interface
; 4. Setting the processor in the MPLAB Project Dialog
;==========================================================================
;==========================================================================
;
; Verify Processor
;
;==========================================================================
IFNDEF __16F84A
MESSG "Processor-header file mismatch. Verify selected processor."
ENDIF
;==========================================================================
;
; Register Definitions
;
;==========================================================================
W EQU H'0000'
F EQU H'0001'
;----- Register Files -----------------------------------------------------
;-----Bank0------------------
INDF EQU H'0000'
TMR0 EQU H'0001'
PCL EQU H'0002'
STATUS EQU H'0003'
FSR EQU H'0004'
PORTA EQU H'0005'
PORTB EQU H'0006'
EEDATA EQU H'0008'
EEADR EQU H'0009'
PCLATH EQU H'000A'
INTCON EQU H'000B'
;-----Bank1------------------
OPTION_REG EQU H'0081'
TRISA EQU H'0085'
TRISB EQU H'0086'
EECON1 EQU H'0088'
EECON2 EQU H'0089'
;----- STATUS Bits -----------------------------------------------------
C EQU H'0000'
DC EQU H'0001'
Z EQU H'0002'
NOT_PD EQU H'0003'
NOT_TO EQU H'0004'
IRP EQU H'0007'
RP0 EQU H'0005'
RP1 EQU H'0006'
;----- PORTA Bits -----------------------------------------------------
RA0 EQU H'0000'
RA1 EQU H'0001'
RA2 EQU H'0002'
RA3 EQU H'0003'
RA4 EQU H'0004'
;----- PORTB Bits -----------------------------------------------------
RB0 EQU H'0000'
RB1 EQU H'0001'
RB2 EQU H'0002'
RB3 EQU H'0003'
RB4 EQU H'0004'
RB5 EQU H'0005'
RB6 EQU H'0006'
RB7 EQU H'0007'
;----- INTCON Bits -----------------------------------------------------
RBIF EQU H'0000'
INTF EQU H'0001'
T0IF EQU H'0002'
RBIE EQU H'0003'
INTE EQU H'0004'
T0IE EQU H'0005'
EEIE EQU H'0006'
GIE EQU H'0007'
TMR0IF EQU H'0002'
TMR0IE EQU H'0005'
;----- OPTION_REG Bits -----------------------------------------------------
PSA EQU H'0003'
T0SE EQU H'0004'
T0CS EQU H'0005'
INTEDG EQU H'0006'
NOT_RBPU EQU H'0007'
PS0 EQU H'0000'
PS1 EQU H'0001'
PS2 EQU H'0002'
;----- TRISA Bits -----------------------------------------------------
TRISA0 EQU H'0000'
TRISA1 EQU H'0001'
TRISA2 EQU H'0002'
TRISA3 EQU H'0003'
TRISA4 EQU H'0004'
;----- TRISB Bits -----------------------------------------------------
TRISB0 EQU H'0000'
TRISB1 EQU H'0001'
TRISB2 EQU H'0002'
TRISB3 EQU H'0003'
TRISB4 EQU H'0004'
TRISB5 EQU H'0005'
TRISB6 EQU H'0006'
TRISB7 EQU H'0007'
;----- EECON1 Bits -----------------------------------------------------
RD EQU H'0000'
WR EQU H'0001'
WREN EQU H'0002'
WRERR EQU H'0003'
EEIF EQU H'0004'
;==========================================================================
;
; RAM Definitions
;
;==========================================================================
__MAXRAM H'00CF'
__BADRAM H'0007'
__BADRAM H'0050'-H'007F'
__BADRAM H'0087'
;==========================================================================
;
; Configuration Bits
;
; NAME Address
; CONFIG 2007h
;
;==========================================================================
; The following is an assignment of address values for all of the
; configuration registers for the purpose of table reads
_CONFIG EQU H'2007'
;----- CONFIG Options --------------------------------------------------
_FOSC_LP EQU H'3FFC'; LP oscillator
_LP_OSC EQU H'3FFC'; LP oscillator
_FOSC_XT EQU H'3FFD'; XT oscillator
_XT_OSC EQU H'3FFD'; XT oscillator
_FOSC_HS EQU H'3FFE'; HS oscillator
_HS_OSC EQU H'3FFE'; HS oscillator
_FOSC_EXTRC EQU H'3FFF'; RC oscillator
_RC_OSC EQU H'3FFF'; RC oscillator
_WDTE_OFF EQU H'3FFB'; WDT disabled
_WDT_OFF EQU H'3FFB'; WDT disabled
_WDTE_ON EQU H'3FFF'; WDT enabled
_WDT_ON EQU H'3FFF'; WDT enabled
_PWRTE_ON EQU H'3FF7'; Power-up Timer is enabled
_PWRTE_OFF EQU H'3FFF'; Power-up Timer is disabled
_CP_ON EQU H'000F'; All program memory is code protected
_CP_OFF EQU H'3FFF'; Code protection disabled
;----- DEVID Equates --------------------------------------------------
_DEVID1 EQU H'2006'
;----- IDLOC Equates --------------------------------------------------
_IDLOC0 EQU H'2000'
_IDLOC1 EQU H'2001'
_IDLOC2 EQU H'2002'
_IDLOC3 EQU H'2003'
LIST
Página 35. SISTEMA DE INSTRUCCIONES:
Para dejarlo mejor explicado, cogemos por ejemplo el registro MOVF que puedes ver en l apágin a36 de la hoja de datos del PIC16F84A.
Como podrás ver en la tabla, MOVF corresponde al 00 1000, o lo que es lo mismo, añadir dos ceros más al principio, 00001000.
El registro PORTB que muestra en el archivo p16f84a.inc:
Código: Seleccionar todo
;----- Register Files -----------------------------------------------------
;-----Bank0------------------
PORTB EQU H'0006'
Del hexadecimal H'0006' al binario es: 000 0110
Mirando el archivo p16f84a.inc de arriba:
Código: Seleccionar todo
;==========================================================================
;
; Register Definitions
;
;==========================================================================
W EQU H'0000'
F EQU H'0001'
Elegimos la F que corresponde guardar en el propio registro, es un 1. La d es el lugar de destino, W que equivale a 0 se guarda en el registro de trabajo. La F que equivale a 1 se guarda en el registro.
En resumen:
MOVF PORTB, F
MOVF H'0006', H'0001'
00001000 1 000 0110
Pseudocódigo de nuestro compañero del foro explorer:
Código: Seleccionar todo
bits1413 = (0b11_0000_0000_0000 & opcode) >> 12; // extraemos los dos bits superiores
switch (bits1413) {
case 0b00:
// en este caso, el tercer nibble es la operación, el bit 7 es la suboperación o destino, y el resto, el operando
nibble3 = (0b00_1111_0000_0000 & opcode) >> 8;
bit7 = (0b00_0000_1000_0000 & opcode) >> 7;
operando = (0b00_0000_0111_1111 & opcode);
switch (bit7) {
case 0:
reg = 'W';
break;
case 1;
reg = 'F';
break;
}
switch (nibble3) {
case 0x0:
switch (bit7) {
case 1:
printf("MOVWF %x\n", operando);
break;
case 0;
// aquí pueden ocurrir varios casos, según el primer nibble
nibble1 = (0b00_0000_0000_1111 & opcode);
switch (nibble1) {
case 0x0:
printf("NOP\n");
break;
case 0x4:
printf("CLRWDT\n");
break;
case 0x9:
printf("RETFIE\n");
break;
case 0x8:
printf("RETURN\n");
break;
case 0x3:
printf("SLEEP\n");
break;
}
break;
}
break;
case 0x1:
switch (bit7) {
case 0:
printf("CLRW\n");
break;
case 1;
printf("CLRF %x\n", operando);
break;
}
break;
case 0x2:
printf("SUBWF %x,%c\n", operando, reg);
break;
case 0x3:
printf("DECF %x,%c\n", operando, reg);
break;
case 0x4:
printf("IORWF %x,%c\n", operando, reg);
break;
case 0x5:
printf("ANDWF %x,%c\n", operando, reg);
break;
case 0x6:
printf("XORWF %x,%c\n", operando, reg);
break;
case 0x7:
printf("ADDWF %x,%c\n", operando, reg);
break;
case 0x8:
printf("MOVF %x,%c\n", operando, reg);
break;
case 0x9:
printf("COMF %x,%c\n", operando, reg);
break;
case 0xA:
printf("INCF %x,%c\n", operando, reg);
break;
case 0xB:
printf("DECFSZ %x,%c\n", operando, reg);
break;
case 0xC:
printf("RRF %x,%c\n", operando, reg);
break;
case 0xD:
printf("RLF %x,%c\n", operando, reg);
break;
case 0xE:
printf("SWAPF %x,%c\n", operando, reg);
break;
case 0xF:
printf("INCFSZ %x,%c\n", operando, reg);
break;
}
break;
case 0b01:
// 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 operando
subop = (0b00_1100_0000_0000 & opcode) >> 10;
bit = (0b00_0011_1000_0000 & opcode) >> 7;
operando = (0b00_0000_0111_1111 & opcode);
switch (subop) {
case 0x0;
printf("BCF %x,%d\n", operando, bit);
break;
case 0x1;
printf("BSF %x,%d\n", operando, bit);
break;
case 0x2;
printf("BTFSC %x,%d\n", operando, bit);
break;
case 0x3;
printf("BTFSS %x,%d\n", operando, bit);
break;
}
break;
case 0b10:
// ver el bit 12. El resto es el operando
bit12 = (0b00_1000_0000_0000 & opcode) >> 11;
operando = (0b00_0111_1111_1111 & opcode);
switch (bit12) {
case 0:
printf("CALL %x\n", operando);
break;
case 1:
printf("GOTO %x\n", operando);
break;
}
break;
case 0b11:
// el tercer nibble es la suboperación, y el resto, el operando
nibble3 = (0b00_1111_0000_0000 & opcode) >> 8;
operando = (0b00_0000_1111_1111 & opcode);
switch (nibble3) {
case 0b0000:
case 0b0001:
case 0b0010:
case 0b0011:
printf("MOVLW %x\n", operando);
break;
case 0b0100:
case 0b0101:
case 0b0110:
case 0b0111:
printf("RETLW %x\n", operando);
break;
case 0b1000:
printf("IORLW %x\n", operando);
break;
case 0b1001:
printf("ANDLW %x\n", operando);
break;
case 0b1010:
printf("XORLW %x\n", operando);
break;
case 0b1100:
case 0b1101:
printf("SUBLW %x\n", operando);
break;
case 0b1110:
case 0b1111:
printf("ADDLW %x\n", operando);
break;
}
break;
}
Yo y un amigo lo valos a traducir por el momento a Java que es el que entiende mejor, luego haré en otros lenguajes para quien le guste, como dije arriba, C#, C++ CLR y VB .net.
Si no tienen algo claro, avisen.
Un cordial saludo.
-
- 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
Hola:
Ya se ha hecho algo a secar por un amigo pero no está del todo completo, solo muestra del binario establecido como ejemplo y lo muestra en código ensamblador.
Puedes usar el NetBeanso el Eclipse.
Descompila.java
TroceadoEnBits.java
Lo que falta ahora es una entrada de datos en consola, por ejemplo, introducir estos datos.
00001000 1 000 0110
A la hora de instroducción de datos se pondrá todo junto, los 14 ó 16 bits.
000010001000 0110
Por cada entrada binaria que metan, al pulsar Enter muestra el código en ensamblador como puede ser este ejemplo:
MOVF PORTB, F
Saludos.
Ya se ha hecho algo a secar por un amigo pero no está del todo completo, solo muestra del binario establecido como ejemplo y lo muestra en código ensamblador.
Puedes usar el NetBeanso el Eclipse.
Descompila.java
Código: Seleccionar todo
package descompila;
import java.io.*;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class Descompila {
public static void main(String [] arg) {
descompilar(new TroceadoEnBits(0x0886));
}
static void print(String cadena){
System.out.println(cadena);
}
static String direccion(int operando){
String registro="";
switch(operando){
case 0x6:
registro="PORTB";
break;
//chago aqui vete completando la tabla de REGISTER FILE MAP
default:
registro= Integer.toHexString(operando);
break;
}
return registro;
}
static void descompilar(TroceadoEnBits opcode){
int bits1312 =opcode.dameRango(12, 13);// (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;
}
}
}
TroceadoEnBits.java
Código: Seleccionar todo
package descompila;
public 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){
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));
}
}
Lo que falta ahora es una entrada de datos en consola, por ejemplo, introducir estos datos.
00001000 1 000 0110
A la hora de instroducción de datos se pondrá todo junto, los 14 ó 16 bits.
000010001000 0110
Por cada entrada binaria que metan, al pulsar Enter muestra el código en ensamblador como puede ser este ejemplo:
MOVF PORTB, F
Saludos.
- explorer
- MSX Turbo R
- Mensajes: 400
- 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
Pues no, no uso Java. Desde hace 20 años, precisamente. Es un lenguaje muy verboso (escribir muchas líneas para poder hacer algo).
Yo soy programador de Perl. Y el problema se puede resolver en una sola línea de comando
Bueno, naturalmente, hay trampa: uso el desensamblador gpdasm de las gputils. El código Perl crea un archivo kkk.hex a partir de los dos bytes que queremos desensamblar, y se lo pasa al desensamblador, que genera el código para el micro indicado (p16f874a).
Desensambladores hay unos cuantos. Y algunos en código C. Seguro que en Java ya hay alguna cosa hecha. Cuestión de buscar.
Yo soy programador de Perl. Y el problema se puede resolver en una sola línea de comando
Código: Seleccionar todo
$ perl -E '$dat = pack "v*", 0b001000_1_000_0110; $l = length $dat; say sprintf ":%02x000000%s%s\n:00000001FF", $l, unpack("H*", $dat), unpack "H2", pack "C", 0x100 - ($l + unpack "%8C*", $dat) ' > kkk.hex; gpdasm -p p16f874a kkk.hex
000000: 0886 movf 0x6, f
Bueno, naturalmente, hay trampa: uso el desensamblador gpdasm de las gputils. El código Perl crea un archivo kkk.hex a partir de los dos bytes que queremos desensamblar, y se lo pasa al desensamblador, que genera el código para el micro indicado (p16f874a).
Desensambladores hay unos cuantos. Y algunos en código C. Seguro que en Java ya hay alguna cosa hecha. Cuestión de buscar.
¿Quién está conectado?
Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 13 invitados