1. TugaTech » Programação, Scripts e Webmasters » Programação, Scripts e Webmasters

Siga-nos

Realize o Login na sua conta ou Registe-se para participar.

Ver o tópico anterior Ver o tópico seguinte Ir em baixo  Mensagem [Página 1 de 1]

zemar

Utilizador

Olá

 

Preciso de ajuda neste problema:

 

Dado dois valores inteiros quero calcular o seu produto e testar se houve overflow (resultado não pode ser representado em 32 bit). Eu tenho o seguinte código:

 

MOV R0 , #8000

MOV R1 , #8000

umulls  r2, r3, r0, r1

MOVVC R4 , R0

 

O código a cima não está a dar sinal que exista overflow, o que tenho que alterar para dar overflow?

 

Obrigado desde já pela ajuda.

Aprendiz

Avançado
Aprendiz

Boa noite,

 

Não estou familiarizado com a arquitectura ARM em particular (já trabalhei com MIPS), mas de qualquer das formas tem de fazer uma comparação para pelo menos verificar se houve overflow, algo que o código que fornece aparentemente não faz visto que não possui nenhuma instrução cmp ou bne/be .

Fiz uma rápida pesquisa e encontrei 2 links que me pareceram importantes:

-Como detectar overflow em multiplicação de 2 números em complemento para dois (teoria)

-Implementação ARM de um programa que faz verificação de overflow na multiplicação

 

A resposta que procura está no segundo link, na secção Detecting Signed/Unsigned Overflow (dependerá se está ou não a usar números unsigned ou não), no entanto aconselho a ler a informação no primeiro link devido à sua completude. Wink

 

Melhores cumprimentos,

http://goncalotomas.com

zemar

Utilizador
@Aprendiz escreveu:

Boa noite,

 

Não estou familiarizado com a arquitectura ARM em particular (já trabalhei com MIPS), mas de qualquer das formas tem de fazer uma comparação para pelo menos verificar se houve overflow, algo que o código que fornece aparentemente não faz visto que não possui nenhuma instrução cmp ou bne/be .

Fiz uma rápida pesquisa e encontrei 2 links que me pareceram importantes:

-Como detectar overflow em multiplicação de 2 números em complemento para dois (teoria)

-Implementação ARM de um programa que faz verificação de overflow na multiplicação

 

A resposta que procura está no segundo link, na secção Detecting Signed/Unsigned Overflow (dependerá se está ou não a usar números unsigned ou não), no entanto aconselho a ler a informação no primeiro link devido à sua completude. Wink

 

Melhores cumprimentos,

 

Obrigado pela resposta.

 

Na arquitectura ARM basta neste caso (acho) acrescentar um 's' (ex: adds) para activar os bits de condição. Relativamente aos links, já tinha achado esses sites e testei os exemplos porém não deu overflow :/ Devo estar a fazer algo mal...

Aprendiz

Avançado
Aprendiz

Boa tarde,

 

Confirmei agora esse pormenor das instruções. Acrescentar o S de facto actualiza o valor das Flags, sendo a mais importante a de Carry (Flag C), que indica que o resultado não coube em 32 bits.

Apenas para que perceba por completo o que se passa, qual é o significado de VC como sufixo do comando MOV?

 

Melhores cumprimentos,

http://goncalotomas.com

zemar

Utilizador
@Aprendiz escreveu:

Boa tarde,

 

Confirmei agora esse pormenor das instruções. Acrescentar o S de facto actualiza o valor das Flags, sendo a mais importante a de Carry (Flag C), que indica que o resultado não coube em 32 bits.

Apenas para que perceba por completo o que se passa, qual é o significado de VC como sufixo do comando MOV?

 

Melhores cumprimentos,

 

Boa Tarde

 

 

O VC vem desta tabela:

 

 

 

Ou seja, eu queria que ele só movesse quando exista overflow.

 

Em relação ao umulls ele está a fazer: [R3,R2]=R0*R1

Aprendiz

Avançado
Aprendiz

Creio saber de onde vem o problema. De acordo com a documentação oficial da operação UMULL, a Flag C e V não são afectadas, mesmo se especificar o sufixo S, como fez. Isto significa que muito embora a operação MOVVC esteja bem pensada, nunca vai conseguir verificar se houve ou não overflow.

Agora para a parte que eu achei mais complicada: porque é que não actualiza as flags?

Tenho quase a certeza que este comportamento se deve ao facto de ser uma operação de multiplicação cujo resultado é efectivamente guardado em 64 bits (2 registos de 32 bits cada, R3 e R2). Sendo os operandos de 32 bits cada um, o resultado dessa multiplicação nunca será maior que 64 bits.

Se o meu raciocínio estiver correcto, poderá verificar a existência de um "overflow" ao verificar o conteúdo de R3. Se o resultado de R0*R1 couber em 32 bits, R3 deverá estar a zeros. Caso contrário, o resultado ocupou efectivamente mais de 32 bits.

 

Melhores cumprimentos,

http://goncalotomas.com

zemar

Utilizador
@Aprendiz escreveu:

Creio saber de onde vem o problema. De acordo com a documentação oficial da operação UMULL, a Flag C e V não são afectadas, mesmo se especificar o sufixo S, como fez. Isto significa que muito embora a operação MOVVC esteja bem pensada, nunca vai conseguir verificar se houve ou não overflow.

Agora para a parte que eu achei mais complicada: porque é que não actualiza as flags?

Tenho quase a certeza que este comportamento se deve ao facto de ser uma operação de multiplicação cujo resultado é efectivamente guardado em 64 bits (2 registos de 32 bits cada, R3 e R2). Sendo os operandos de 32 bits cada um, o resultado dessa multiplicação nunca será maior que 64 bits.

Se o meu raciocínio estiver correcto, poderá verificar a existência de um "overflow" ao verificar o conteúdo de R3. Se o resultado de R0*R1 couber em 32 bits, R3 deverá estar a zeros. Caso contrário, o resultado ocupou efectivamente mais de 32 bits.

 

Melhores cumprimentos,

 

Também pensei nisso, vou testar.

 

Obrigado

Aprendiz

Avançado
Aprendiz
Depois diga se funcionou, estou curioso Very Happy

http://goncalotomas.com

zemar

Utilizador

@Aprendiz escreveu:Depois diga se funcionou, estou curioso Very Happy

 

Fiz :

 

mov r0, #0X40000000

mov r1, #0X40000000

umulls r2,r3,r0,r1

cmp r3, #0

moveq r7,#1 ; se não existir overflow move 1 para R7

 

Acho que é isto Smile

Aprendiz

Avançado
Aprendiz

O código parece-me correcto.

Já testou se funciona? Smile

http://goncalotomas.com

zemar

Utilizador
@Aprendiz escreveu:

O código parece-me correcto.

Já testou se funciona? Smile

 

"Se o resultado de R0*R1 couber em 32 bits, R3 deverá estar a zeros. Caso contrário, o resultado ocupou efectivamente mais de 32 bits."

 

Foi isto que testei e funciona Wink

 

Obrigado!

Ver o tópico anterior Ver o tópico seguinte Voltar ao Topo  Mensagem [Página 1 de 1]

Permissão deste fórum:
Você não pode responder aos tópicos neste fórum




Aplicações do TugaTechAplicações TugaTechBlog TugaTechBlog do TugaTechRSS TugaTechRSS do TugaTechSpeedtest TugaTechSpeedtest TugatechHost TugaTechHost TugaTech