Olá Visitante, Por favor faça Login ou Registe-se

Autor Tópico: Multiplicar e dividir em assembler  (Lida 4008 vezes)

Offline José Flor

  • Vigiado
  • *
  • Mensagens: 0
  • OzFlor - José Flor
Multiplicar e dividir em assembler
« em: Janeiro 20, 2008, 09:54:54 am »
.
« Última modificação: Janeiro 23, 2011, 10:13:11 am por José Flor »

Offline resinba

  • Cristal
  • ***
  • Mensagens: 450
Re: Multiplicar e dividir em assembler
« Responder #1 em: Janeiro 20, 2008, 14:35:20 pm »
outra técnica (normalmente a que eu uso) é fazer somas consecutivas para a multiplicação e subtracções consecutivas para a divisão exemplo disso...

multiplicação

axb=c <=> 2X5=10 <=>2+2+2+2+2=10

label
     addf a,f
     defsz b,f
       goto label
continua

divisão

a:b=c <=> 15:3=5 <=> 15-3=12 (1) 12-3=9 (2) 9-3=6 (3) 6-3=3 (4) 3-3=0 (5)

label
     movf b,w
     subwf a,f
     incf c
     btfss STATUS,C
           goto continua
           btfsc STATUS,Z
                 goto label
                  continua




« Última modificação: Janeiro 20, 2008, 16:06:48 pm por resinba »
Por favor, alterem o meu email no msn pois tenho outro email dedicado aos foruns, e vou bloquear todos os que se encontram no antigo email.

Offline RJSC

  • Socket
  • **
  • Mensagens: 190
Re: Multiplicar e dividir em assembler
« Responder #2 em: Janeiro 21, 2008, 01:12:19 am »
Resumindo, abaixo com o assembly!
Tanto trabalho para coisas tão simples, faz-nos passar a compiladores humanos  :-\
Esse processo é exactamente o que os compiladores fazem, calculam as somas e subtracções ou shifts de bits necessários à operação.

Offline ZeBit

  • Socket
  • **
  • Mensagens: 134
Re: Multiplicar e dividir em assembler
« Responder #3 em: Janeiro 21, 2008, 01:19:59 am »
Flor,

Não conheço em pormenor o assembly dos PIC´s no entanto essas instrucções (rodar à esquerda e rodar à direita) tambem existe na familia do 8051.

No 8051:
            RR    rodar á direita
           
            RL    rodar á esquerda
           
ou ainda:
            RRC  rodar á direita com Carry

            RLC rodar á esquerda com Carry

Supondo que há consenso na interpretação dessas instrucções por parte dos dois fabricantes (Microchip e Intel), arrisco-me a dizer que a dizer que há uma distracção da sua parte na designaçao das instrucções não no raciocinio, esse está correcto.

Isto é quando diz:

Citar
RLF = rodar á esquerda
00000100 = 4
quando rodo o bit á esquerda fica
00000010 = 2
Aqui dividi 4/2 = 2

Está na verdade a fazer uma rotacção á direita ...

ou ainda:

Citar
RRF = rodar á direita
00000100 = 4
quando rodo o bit á direita fica
00001000 = 8
Aqui multipliquei 4x2 = 2
Voltando a rodar á direita fica
00010000 = 16 (4x2x2) ou (4x4) = 16

Aqui é ao contrario, isto é rotacção á esquerda.

Agradeço que me confirmem se é assim ou não.


Este algoritmo tambem é usado no 8051.

Vejam a parte interessante no proximo post!

Até já...

Offline ZeBit

  • Socket
  • **
  • Mensagens: 134
Re: Multiplicar e dividir em assembler
« Responder #4 em: Janeiro 21, 2008, 01:38:45 am »
No 8051 pode-se simplesmente usar as instrucções disponiveis para esse efeito:

para multiplicar A (Acc) por B

basta fazer:

 MUL AB

o resultado fica distribuido pelos 2 registos

B - byte de ordem alta

A (Acc) - byte de ordem baixa

para dividir A (Acc) por B

faz-se :

DIV AB

A (Acc) fica com o quociente

B fica com o resto

Por isso referi no outro topico http://www.electronicapt.com/forum/index.php/topic,412.msg6669.html#msg6669  que estas duas instrucções são um luxo no mundo dos 8 bits.

Um abraço

Offline ZeBit

  • Socket
  • **
  • Mensagens: 134
Re: Multiplicar e dividir em assembler
« Responder #5 em: Janeiro 21, 2008, 02:08:48 am »
Citar
Logo quando falaram em 12 e 24 ciclos máquina em CISC para multiplicar e dividir é isso que o assembla está a fazer.
Estou certo ou estou errado ou estou a meio caminho?

Ola novamente Flor,

A afirmação que fiz com relacção aos 12 e 24 ciclos de clock (não ciclos maquina, isso é outra coisa), refere-se aos ciclos de clock necessários para o 8051 tradiccional executar a generalidade das instrucções, não a multiplicação e a divisão. Essas são as excepções: levam 48 ciclos maquina.

Tambem não podemos referir-nos a esses mesmos ciclos 12 e 24 como se todos os microcontroladores CISC levassem o mesmo nº de ciclos a executarem as suas instrucções. Não é verdade, nem mesmo em instrucçoes equivalentes. Pode acontecer, mas não é taxativo.

Por outro lado as instrucções que referi multiplicação e divisão nem sequer existem em muitos micros, quer CISC ou RISC, são raras até em micros maiores (16 bites).

Desculpa as correcções mas há outras pessoas a ler que podem ser levadas ao erro

Um abraço 

Offline José Flor

  • Vigiado
  • *
  • Mensagens: 0
  • OzFlor - José Flor
Re: Multiplicar e dividir em assembler
« Responder #6 em: Janeiro 21, 2008, 09:17:34 am »
.
« Última modificação: Janeiro 23, 2011, 10:13:33 am por José Flor »

Offline ZeBit

  • Socket
  • **
  • Mensagens: 134
Re: Multiplicar e dividir em assembler
« Responder #7 em: Janeiro 23, 2008, 23:52:20 pm »
Uma correcção:

Onde escrevi
Citar
Essas são as excepções: levam 48 ciclos maquina.

Queria escrever :
Essas são as excepções: levam 48 ciclos de clock.


Citar
Então 1 ciclo do clock podem ser mais ciclos maquina no caso do 8051?

Ao contrario:

Um ciclo maquina, no 8051 tradicional contem 12 ciclos de clock.

Citar
Na tua referencia do 8051 o RL e o RR não afectar o carry é curioso. Neste caso só pode somar ou subtrair números dentro do valor do file. Como fica isso?

É logico que o RR e o RL não são os mais adequados para esse fim. Para divisões e multiplicações usa-se respectivamente o RRC e o RLC.

A referencia que fiz ao RR e RL foi apenas para efeitos informativos. Estes têm no entanto outros fins (Ex: Fazer girar continuamente um port, simulando movimento de rotação).

Citar
RRF = rodar á direita
00000100 = 4
quando rodo o bit á direita fica
00001000 = 8 veja que o 0 (zero) da esquerda rodou para a direita, ganhando mais um zero á direita
Aqui multipliquei 4x2 = 2
Voltando a rodar á direita fica
00010000 = 16 (4x2x2) ou (4x4) = 16
Aqui está a rodar á direita sim.

Flor,

Quando tem :                              0000 0100

E depois de uma rotação fica com : 0000 1000

Você deslocou todos os bits do Byte (ou file) para a esquerda, dentro do proprio Byte, esta é a referencia logo o deslocamento foi á esquerda.


Por outro lad se tem:     0000 0100
e fica com:                  0000 0010

a rotaçao é à direita porque todos os bits se deslocaram para a direita, dentro do Byte.

Um abraço

Offline ZeBit

  • Socket
  • **
  • Mensagens: 134
Re: Multiplicar e dividir em assembler
« Responder #8 em: Janeiro 24, 2008, 00:08:39 am »
Citar
RRF = rodar á direita
00000100 = 4
quando rodo o bit á direita fica
00001000 = 8 veja que o 0 (zero) da esquerda rodou para a direita, ganhando mais um zero á direita

Uma vez mais, a referência, é o que se passa no interior do Byte não no exterior.

Portanto, a rotação que referes acima é á esquerda.

Um abraço

Offline José Flor

  • Vigiado
  • *
  • Mensagens: 0
  • OzFlor - José Flor
Re: Multiplicar e dividir em assembler
« Responder #9 em: Janeiro 24, 2008, 02:32:37 am »



[attachment deleted by admin]
« Última modificação: Janeiro 23, 2011, 09:54:52 am por José Flor »

Offline tó neves

  • Cristal
  • ***
  • Mensagens: 295
Re: Multiplicar e dividir em assembler
« Responder #10 em: Janeiro 24, 2008, 22:08:27 pm »
Citação de: José Flor
RRF = rodar á direita
00000100 = 4
quando rodo o bit á direita fica
00001000 = 8 veja que o 0 (zero) da esquerda rodou para a direita, ganhando mais um zero á direita
Aqui multipliquei 4x2 = 2
Voltando a rodar á direita fica
00010000 = 16 (4x2x2) ou (4x4) = 16
Aqui está a rodar á direita sim.

José Flor talvez as setas o tenham induzido em erro, usando a sua figura ROR.gif faça o seguinte raciocínio:

Iniciando no bit0 e usando o sentido das setas, o bit0 vai para Carry o Carry vai para bit7 e o bit7 vai para onde? :)

Na imagem o registo tem 01010101(85) depois do ROtate Right o valor final é 00101010(42) ora você diz:

Citação de: José Flor
(...)Pelo meu conhecimento, rodar o bit á direita duplica o numero,(...)

:)

Se dúvidas restarem consulte a documentação procure em Instruction Descriptions as instruções RLF e RRF, leia a description e veja o example.

Quanto à multiplicação veja na Wikipedia e também o AN526.

Cumprimentos :)

Offline ZeBit

  • Socket
  • **
  • Mensagens: 134
Re: Multiplicar e dividir em assembler
« Responder #11 em: Janeiro 24, 2008, 22:57:56 pm »
Ola Flor,
 
segui o link de finalreport e 
Veja as imagens e estude os exemplos.
Penso que desta é de vez.


Agora com relacção a
Citar
para multiplicar A (Acc) por B
Acc = ?

Acc é o simbolo para acumulador.
A é tambem um simbolo para o acumulador quando o mesmo é intriseco a uma instrucção, como é o caso de MUL AB ou ainda RRC A.

Um abraço

Offline José Flor

  • Vigiado
  • *
  • Mensagens: 0
  • OzFlor - José Flor
Re: Multiplicar e dividir em assembler
« Responder #12 em: Janeiro 25, 2008, 22:51:51 pm »
.
« Última modificação: Janeiro 23, 2011, 09:55:52 am por José Flor »

Offline ZeBit

  • Socket
  • **
  • Mensagens: 134
Re: Multiplicar e dividir em assembler
« Responder #13 em: Janeiro 26, 2008, 16:45:35 pm »
Tudo bem,

O que interessa é que  com a ajuda de todos se tenha chegado a um consenso e que as duvidas tenham sido esclarecidas.

Um abraço