collapse

* Posts Recentes

Amplificador - Rockboard HA 1 In-Ear por almamater
[Ontem às 19:13]


O que é isto ? por KammutierSpule
[26 de Março de 2024, 19:35]


Bateria - Portátil por almamater
[25 de Março de 2024, 22:14]


Emulador NES em ESP32 por dropes
[13 de Março de 2024, 21:19]


Escolher Osciloscópio por jm_araujo
[06 de Fevereiro de 2024, 23:07]


TP4056 - Dúvida por dropes
[31 de Janeiro de 2024, 14:13]


Leitura de dados por Porta Serie por jm_araujo
[22 de Janeiro de 2024, 14:00]


Distancia Cabo por jm_araujo
[08 de Janeiro de 2024, 16:30]


Meu novo robô por josecarlos
[06 de Janeiro de 2024, 16:46]


Laser Engraver - Alguém tem? por almamater
[16 de Dezembro de 2023, 14:23]

Autor Tópico: Operações de branch e jump  (Lida 5913 vezes)

0 Membros e 1 Visitante estão a ver este tópico.

Offline rglove

  • Mini Robot
  • *
  • Mensagens: 527
Operações de branch e jump
« em: 04 de Abril de 2014, 16:41 »
Boas,

Há pouco tempo atrás comecei a aprender assembly. Tenho estado a ler o instruction set e a experimentar diversas instruções, mas as instruções de salto relativo não são executadas da forma como está escrito no instruction set. O microcontrolador que estou a programar é o atmega328p.

Se colocar a seguinte instrução:
RJMP 2
Era de esperar que PC <- PC + 1 + 2 segundo o que está no instruction set. O que acontece na realidade é que PC <- 2. Alguém me sabe explicar o porquê disto? Tentei procurar na datasheet algo relacionado com isto, mas não descobri... No instruction set também não descobri...

Offline jm_araujo

  • Mini Robot
  • *
  • Mensagens: 2.947
  • NERD!
Re: Operações de branch e jump
« Responder #1 em: 04 de Abril de 2014, 17:24 »
Já não programo em assembly há tempos, e acho que nunca programei AVR, mas para jumps é normal utilizar-se labels ("LABEL:"- o nome com dois pontos no fim), o assemblador sabe interpretá-las. Utilizam-se para jumps e calls.
 Senão tens de andar a fazer contas de quantos bytes ocupa cada instrução para que o salto acerte no destino.

Edit:
Como está no exemplo do instruction set do AVR (http://www.atmel.com/images/doc0856.pdf)
Código: [Seleccione]
Example:
        cpi r16,$42 ; Compare r16 to $42
        brne error ; Branch if r16 <> $42
        rjmp ok ; Unconditional branch
error:  add r16,r17 ; Add r17 to r16
        inc r16 ; Increment r16
ok:     nop ; Destination for rjmp (do nothing)

Edit 2:
O que deve estar a acontecer é o assemblador estar a considerar o "2" como um endereço absoluto (o comportamento que se pretende mais habitualmente), em vez do comprimento do salto. Vê o código em hexadecimal gerado para confirmar.
« Última modificação: 04 de Abril de 2014, 18:11 por jm_araujo »

Offline dropes

  • Mini Robot
  • *
  • Mensagens: 2.189
Re: Operações de branch e jump
« Responder #2 em: 04 de Abril de 2014, 18:52 »
Não me punha a contar os ciclos das instruções (PC), isso dá uma dor de cabeça além de não ter grande utilidade.

Como o jm_araujo referiu este "2" seria um label tendo de ser colocado "2:" para assumir o salto, não creio que vá reconhecer como um endereço.

O rjmp é até 2k(words)=4kB e são 2 ciclos
O jmp é para maiores distâncias do programa e são 3 ciclos.

O código começo sempre por :

.include "m8def.inc"
;a memória de $60 até $FF é utilizada para variaveis
.def    lpmreg            = r00 ;leitura da memória flash
.def   "Nomes associados aos registos de r4 a r25" exe:
.def    Temp              = r19
;X=R27,R26 Y=R29,R28 Z=R31,R30
.cseg
.org 0

Também não programo assembler faz tempo, porque será :P, os micro-controladores são baratos, rápidos e têm bastante memória, de qualquer forma tem o seu interesse, o último programa que fiz em assembler foi para um cubo de leds com o atmega8 e 814 linhas de código, é um pouco difícil de entender ao começar mas passado umas horas já estamos confortáveis; por isso ver um problema que surja agora é quase como começar do início, abusar nos comentários!!!  ;)

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: Operações de branch e jump
« Responder #3 em: 04 de Abril de 2014, 19:20 »
http://www.avrbeginners.net/

Secção assembly, tens lá muita informação.

Dropes, mesmo assim não estás a tratar da stack, por acaso maior parte dos avr's mete o SP com o devido valor para o correcto funcionamento, mas não se deve esperar isso de todos os micros.
Avr fanboy

Offline dropes

  • Mini Robot
  • *
  • Mensagens: 2.189
Re: Operações de branch e jump
« Responder #4 em: 04 de Abril de 2014, 19:57 »
Bem visto,
costumo ligar a isso quanto é em programação de alto nível, em assembler também convém estar bem definido para que não ocorram atropelamentos na memória...

Existe no ficheiro "m8def.inc" essa informação mas por comodidade alterei os valores:
;Posição inferior da memória
ldi temp,$00
out sph,temp   
ldi temp,$FF
out spl,temp

Offline rglove

  • Mini Robot
  • *
  • Mensagens: 527
Re: Operações de branch e jump
« Responder #5 em: 04 de Abril de 2014, 23:57 »
Obrigado pelas respostas.
jm_araujo, eu sei que é possível o uso das labels, mas para o salto de uma instrução ou duas repetidamente fica "feio" e um bocado confuso ter tantas labels, isto na minha opinião.

dropes, ainda estou muito fresquinho no que diz respeito a assembly. Ainda estou só a experimentar, daí ter surgido esta dúvida, porque o instruction set não está de acordo com o que acontece realmente. Contar o PC não é assim tão difícil, os casos em que pretendia usar isto eram simples e onde o PC incrementava só 1 por instrução... Vou experimentar ver a instrução guardada na memória flash para ver se está de acordo com o instruction set.

senso, obrigado pela partilha do link.

Consegui usar na mesma como pretendia, mas tive que usar da seguinte forma:
RJMP PC + 3

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: Operações de branch e jump
« Responder #6 em: 05 de Abril de 2014, 00:47 »
Tipicamente quando queres saltar uma instrução usas os branchs(a base dos if's).
Avr fanboy

Offline rglove

  • Mini Robot
  • *
  • Mensagens: 527
Re: Operações de branch e jump
« Responder #7 em: 05 de Abril de 2014, 02:08 »
Sim, é exatamente para situações dessas (if's) que não é prático as labels, é chato ter que colocar labels para cada branch ou jmp...

Mas apesar de achar estúpido o instruction set não fazer referência ao uso dessas operações desta forma, acho que já descobri o que está a acontecer...

No atmel simulator vi a instrução que era guardada na memória flash e cheguei à conclusão que o assembler faz os cálculos de forma a colocar na instrução o offset correto. Ou seja, interpreta RJMP (ou qqr jmp ou branch) k como se quisesse  fazer um salto absoluto para PC = k e calcula o offset. Também dá para ver isso no tab "disassembly".

Offline dropes

  • Mini Robot
  • *
  • Mensagens: 2.189
Re: Operações de branch e jump
« Responder #8 em: 05 de Abril de 2014, 10:53 »
Até pode ficar feio usar labels, embora não tenham de ser declarados no início do programa trata-se apenas de uma posição da memória flash para onde vai saltar sem ter de se andar a contar, caso desejes colocar alguma instrução no meio o endereço adapta-se, coisa que não acontece com o PC e toca a calcular novamente... bugs

Realmente em assembler fazem-se coisas que são de se evitar em C ou outra do género, como "goto" "jump" "labels" , "ifs" dentro de "ifs" e tudo aquilo que vamos aprendendo a não fazer para que não se crie situações difíceis de interpretar, daí colocarem-se bastantes comentários, bastam minutos para nos esquecermos o motivo de algumas decisões.

Resume-se a branchs ao comparar registos e valores, ifs, como o Senso referiu.