Advertencias: Ha pasado más de una década desde que habitualmente escribí el código de ensamblaje PIC (y utilicé su compilador de C; tampoco estoy seguro de si mi licencia ya es válida). Tampoco dijo qué compilador es. Usando, así que no puedo ir a buscar una copia y ver qué genera. Y ni siquiera sé si está usando un PIC16 o un PIC18 (diferentes criaturas, con el PIC18 con mejores arreglos para el código de ensamblaje). Finalmente, asumo que usted está bastante al tanto de las cosas con el PIC y eso en algunos aspectos. maneras en que podrá responder a preguntas específicas sobre su código de ensamblaje debido a su trabajo actual en comparación con mi conocimiento de hace una década (y más).
Suposiciones:
- Es una parte de la familia PIC16 (o inferior) y no un PIC18.
- Cuando escribe el código de ensamblaje, está utilizando un ensamblador real y no un código de máquina de codificación manual.
- No has estado observando de cerca el código de máquina generado.
- La confusión no declarada está sobre la dirección allí.
Suponiendo que los anteriores sean correctos, sospecho que puede haber perdido la atención de que la instrucción GOTO solo usa 11 bits para la dirección. Solo se puede bifurcar dentro de la "página" del código actual, donde los bits de la dirección superior permanecen sin cambios en la bifurcación a una nueva dirección.
Cuando escribes en ensamblaje, usualmente usas etiquetas. Incluso si usó direcciones absolutas, el ensamblador sigue haciendo "la matemática" para asegurarse de que la dirección que especifique esté "al alcance". De modo que ni siquiera sabrías de una manera u otra lo que está pasando a menos que observes detenidamente el código de máquina que genera.
Permítame documentar lo que veo arriba (junto con una columna faltante que sinceramente deseo que también incluyera también ):
Address Machine Code Code Lines Description
0x178E BCF STATUS, 0x5 These two lines make sure that data access
0x178F BCF STATUS, 0x6 is on page 0 where PORTE is at.
0x1790 BTFSS PORTE, 0x2 Skip GOTO if the loop should continue.
0x1791 GOTO 0x7E5 Go out of loop to 0x17E5 (past the GOTO.)
0x1792 BTFSC PORTE, 0x0 "if ArrowUpClosed()"
0x1793 <>
0x1794 <>
... ...
0x17E1 <>
0x17E2 <>
0x17E3 <>
0x17E4 GOTO 0x78E Branch to address 0x178E (start of loop.)
0x17E5 MOVLW 0x8
Si observa que solo hay 11 bits en la instrucción de máquina codificada para el GOTO, entonces puede ver por qué el "0x17E5" o "0x178E" completo no se puede codificar en la palabra de la máquina. Sin embargo, ese hecho no impide que el ensamblador y / o el compilador sepan que la dirección puede ser alcanzada correctamente (o no, lo que indica que se necesita más código para hacer una transferencia más distante).
El código del compilador funciona, creo que dices. También dice que cuando escribió un código de ensamblaje propio, también funcionó. Creo que ambos son ciertos. Pero el problema puede ser simplemente que no te has dado cuenta de cómo funciona un ensamblador (lo que es más importante, cómo funciona un enlazador) para generar el código correcto o generar errores.
El ensamblador y el compilador de C generarán un archivo de objeto que contiene lo que equivale a "cadenas" de valores de byte literales + registros de "parche" periódicos que instruyen al enlazador exactamente dónde y exactamente cómo corregir bits y piezas de esos literales cadenas, durante la fase de vinculación cuando el código realmente se coloca en algún lugar. Para el código generado por el ensamblaje, estoy bastante seguro de que este es un proceso muy simple y el vinculador se quejará si escribe instrucciones que requieran una codificación fuera de rango. Para el compilador de C, no estoy tan seguro de la complejidad que se extiende al enlazador. Pero es posible que el compilador de C no quiera preocuparse acerca de si un poco de código se extiende a través de una página de códigos y en su lugar simplemente proporciona al enlazador suficiente información adicional para que el enlazador pueda hacer la determinación y "extenderse automáticamente" una cadena de bytes según sea necesario (lo que hace que el proceso de vinculación sea más complejo pero también lleva a una menor confusión del codificador C típico).
He tenido mi opinión al respecto. Podría ser que malinterpreté totalmente tu dilema aquí. Acabo de despertarme y quién sabe si estoy caminando dormido a través de esto. Pero ahí está. ¿Quizás podrías aclarar el dispositivo, etc., también?
Para aquellos interesados en alguna historia sobre el compilador XC8 C, así como también información sobre las diferencias de optimización en las versiones PRO, encontré este enlace inmediatamente útil. Por eso, puedo ver que el compilador XC8 es básicamente el código del compilador Hi-Tech, con "impedimentos" adicionales para "mejorar" las motivaciones para comprar la versión PRO de su conjunto de herramientas del compilador. Interesantes detalles allí.