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.

Ver perfil do usuário

Aprendiz

Avançado
avatar

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,

Ver perfil do usuário 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...

Ver perfil do usuário

Aprendiz

Avançado
avatar

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,

Ver perfil do usuário 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

Ver perfil do usuário

Aprendiz

Avançado
avatar

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,

Ver perfil do usuário 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

Ver perfil do usuário

Aprendiz

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

Ver perfil do usuário 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

Ver perfil do usuário

Aprendiz

Avançado
avatar

O código parece-me correcto.

Já testou se funciona? Smile

Ver perfil do usuário 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 perfil do usuário

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