TODOPIC
Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: danfly en 18 de Abril de 2012, 13:32:01
-
Buenas, tengo tiempo programando microcontroladores... Cuando era nuevo usaba muchas etiquetas para realizar saltos...
Cabe acotar que mi primer PIC y donde aprendí a programar fue el PIC18f4550... Sin embargo luego en un proyecto estuve trabajando con unos PIC16's, donde descubrí el interesante salto goto $+x, donde podia dar saltos hacia adelante y hacia atrás y me pareció excelente al ahorrarme el utilizar muchas etiquetas...
En estos dias volví nuevamente al 18F4550 y quise usar el mismo truco, y bueno mi primer error lo noté rápidamente al recordar que en los 18's las instrucciones avanzan de 2 en 2 y en algunas especiales inclusive el PC avanzan 4 espacios... así que sacar cuentas para un salto relativo no es tan cómodo y fue cuando recordé haber visto unas instrucciones que me parecieron inútiles en aquel entonces y son todos los BRANCH
Si leemos el manual del microcontrolador vemos que dice que la instrucción BRA n, dará como resultado PC = PC + 2 + 2n... perfecto!! justo lo que necesitaba, pero al intentar hacer un BRA 4, me manda es a la dirección literal 0x04 del programa. Estuve revisando y pues noté que por años muchos han usado esa instrucción para saltos literales como me ocurre a mí... pero pregunto yo, para eso no está ya el goto? y además, porque entonces miente el manual? habrá alguna forma de configurar el compilador para que funcione como aparece en el manual? o será que simplemente lo estoy interpretando mal? porque inclusive, mas extraño es cuando volví a revisar el manual para ver si es que estoy interpretándolo mal, es que a pesar de mostrar la ecuación del resultado como les estoy diciendo "PC = PC + 2 + 2n" el ejemplo que utilizan para la demostración del uso de esas instrucciones, si hacen saltos literales =S... Alguna ayuda???
-
Hola, estuve viendo unos archivos .cof y .asm generados por sdcc y por ejemplo "BRA _00150_DS_" en el .asm, es "bra 0xa86" en el .cof, donde 0xa86 es precisamente la posición de la etiqueta _00150_DS_, pero en hex queda 0xD01A en la posición 000A50, en binario es 1101000000011010, de los cuales 00000011010 son n en complemento a 2, por lo que n=1A.
PC = PC + 2 + 2n
PC = 0xA50 + 2 + 2*0x1A = 0xA86, que coincide con la posición a la que tenía que saltar.
Por lo que concluyo que es el ensamblador el que en vez de usar el n como argumento para la instrucción, lo usa como la posición y al ensamblar, calcula el valor necesario para ir desde el "bra n" hasta la posición n.
Saludos.
-
si no estoy equivocado.la diferencia entre goto y bra,es la capacidad de direccionamiento de cada instruccion.
goto puede realizar un salto dentro de esta zona de memoria. 000h a FFFh
y bra entre 000h y 7FFh.aunque no estoy muy seguro.porque no entiendo lo que quiere decir el datasheet.
-
El "goto x" va directamente a la posición de memoria x, el "bra n" (n en complemento a 2) suma n a la posición actual, según el datasheet. Pero según estuve viendo, el ensamblador (o por lo menos gpasm), hace lo que indique en el mensaje anterior.
Saludos.
-
pues es verdad lo que dices.no me habia dado cuenta porque estoy empezando con los 18F.
como tu dices esto es parecido a lo que hace el asm de los 16f con las direcctivas $+1 o $-1.
he visto algo que me ha llamado la atencion en el datasheet.y es que BRA se puede utilizar tanto como incremento como decremento.
pero cual es la base? si utilizamos datos con signo.el valor indice no puede ser el valor 0.
-
El valor tiene que estar en complemento a dos en caso de ser negativo, pero el ensamblador (estoy hablando de gpasm, no se otro) no me deja poner el valor directamente, sino que lo toma como una posición y calcula el valor correspondiente. Osea que funciona como un goto pero acotado a 1023 instrucciones hacia adelante o 1024 hacia atras.
Saludos.
-
estoy realizando unas pruebas en el mplab.y si pongo una direccion impar,el PC salta a la posicion par anterior.si es par salta a la indicada.
igual estas interpretando mal el datasheet.o esta mal explicado.en todos los ejemplos que hay en el datasheet,el BRA va seguido de una etiqueta.eso indica que se utiliza para saltos directos incondicionales.no incrementos o decrementos del PC.
en tal caso habria un valor positivo o negativo de numero de saltos.y no he visto tales ejemplos.
-
Segun el datasheet:
Syntax: BRA n
Operands: -1024 ≤ n ≤ 1023
Operation: (PC) + 2 + 2n → PC
Status Affected: None
Encoding: 1101 0nnn nnnn nnnn
Description:
Add the 2’s complement number ‘2n’ to
the PC. Since the PC will have
incremented to fetch the next
instruction, the new address will be
PC + 2 + 2n. This instruction is a
two-cycle instruction.
Words: 1
Cycles: 2
Lo que entiendo yo es que la instrucción hace un desplazamiento. Pero creo que el ensamblador le cambia la sintaxis a la instrucción y el valor "n" no lo usa como desplazamiento si no que como dirección, al momento de codificar el bra, hace el calculo del desplazamiento necesario para ir a esa dirección y codifica el bra con ese resultado. Pero en el PIC esa instrucción realiza esta operación (PC) + 2 + 2n → PC.
Pero no es un salto directo incondicional, sino que sería un salto "indirecto" incondicional.
Saludos.
-
Entiendo lo que quieres decir.que sea culpa del compilador.en tal caso habría que analizar el código de instrucción al compilar.y si no es el mismo que indica el datasheet,corregirlo manualmente en el código hex.y hacerlo funcionar de forma real en un pic.
-
he estado practicando.y hay unas diferencias notables entre el GOTO y el BRA.
el GOTO puede direccionar mas memoria que el BRA.a este se le introduce un valor de la direccion a la que saltar.
pero al BRA no se le introduce un valor de direccion a saltar.si no que este salta 1024 saltos hacia atras o 1023 saltos hacia adelante.
un bucle cerrado dentro del BRA da un codigo de intruccion 0xD7FF independientemente de en que zona de la memora este alojada esa instruccion.
no sucede lo mismo con los goto o call.que segun donde este la instruccion el codigo de instruccion varia.ya que estaria alojado en diferentes direcciones.
el direccionamiento del BRA es mas restringido.y si usa el mismo ciclo de instrucciones,no veo la ventaja de su uso.
yo creo que que como es compañero de las instrucciones condicionales de salto,pues han decidido no quitarlo.
-
gracias a los dos por el interés... al final resolví haciendo goto $ y tomando en cuenta con las instrucciones goto, call, movff toman 4 espacios en el PC, y el resto de instrucciones 2...
Ojalá en el futuro MPLAB pueda solucionar ese problemilla, de verdad sería muy útil poder hacer un BRA n donde n sea la cantidad de instrucciones que quieres saltar, tal como ocurre con el goto $ en los PIC's 16
-
esque BRA es una instruccion,no se puede modificar.y goto $+1 o goto $-5,etc .es ina directiva.
en todo caso mplab podria hacer una directiva que distinguiera entre tipos de instrucciones.pero depende a donde queramos saltar y que tipo de instrucciones tengamos que saltar,es complicado.
se puede tener en cuenta un salto o dos.pero si son mas,es un lio.ya habria que mirar la ventana de programa.es mucho mejor utilizar etiquetas.