• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

eMineiro

[C\Assembly]

7 mensagens neste tópico

Bom galera estou fazendo um trabalho em C , é um simulador de CPU extremamente básica e não preciso explicar nada sobre ela a não ser o seguinte.

Opera em 8 bits

--> Números Positivos = 0x00 até 0x7F

--> Números Negativos = 0x80 até 0xFF

--> 2 registradores , e duas memórias de 256bytes.

A razão pelo qual posto aqui o que deveria postar em C é por que se trata de dúvida quanta a FLAGS, essa CPU possui ZeroFlag , NegativeFlag , OverflowFLAG , CarryFlag.

Então me deparei com o seguinte problema

Se R0 = 0x01 e R1 = 0x7F --> R0 = R0 + R1 --> 0x80

Então ZeroFlag  = 0 , CarryFlag = 0 , OverflowFLAG = 1 , NegativeFLAG = ???

O que devo analisar??

Penso eu que R0 = positivo e  R1 = positivo, logo soma de positivos = positivo , portando FlagN (Negative Flag) = 0x00

Me falaram que o resultado deu negativo , entao FlagN = 0x01

Estou com essa dúvida!!

Caso a segunda esteja certa , me eplique então

R0 = 80h e R1 = 80h  --> R0 = R0 + R1 ---> FlagN = ?? , FlagZ = ?? , Overflow = ??

Se possível explicar todas as Flags , e dar exemplo com as possíveis operações críticas serei grato.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Isso depende da implementação do CPU, depois de ter dado overflow não importa muito se a nf está a 0 ou 1..

Eu colocaria a 1, porque existe muita gente que para verificar se deu overflow verifica se a soma é menor que 0 (ou seja, nf)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

E no caso da segunta??

0x80+0x80 = 0x100 ---> e ai??? acende quais flags??? Uma vez que nao temos como comparar mais os números já que o resultado deu maior que 255 e não está definido como positivo ou negativo??

carryflag = 1 , overflowflag = 1 e agora??? zeroflag ou negativeflag???

Eu pensava que sempre que positivo + postivo deveria ser positivo , negativo + negativo = negativo.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

zeroflag=1, só contam os 8 bits de menor peso, e dão zero;

negativeflag=0, zero conta como positivo.

Isto é como eu faria. A zeroflag não acho que possa ser feita de outra forma. A negativeflag podes alterar para detectar o caso específico que disseste, mas penso que a overflowflag chega para isso.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

então a análise das flags de Zero , Negative e Carry são feitas depois da operação , e a overflow é feita uma análise antes de se fazer a operação??

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Neste momento estou a concordar mais com aquilo que o Warrior disse do que com o que eu disse. Mas depende da implementação que pretendas.

Quanto à tua ultima pergunta, eu no simulador fazia e pegava no resultado a 16 ou 32 bits com sinal (vou chamar-lhe res16); se res16 fosse menor que -128 ou maior que 127, colocava CF=1, caso contrário CF=0.

Depois, via se res16 era menor que 0; se fosse, colocava NF=1, caso contrário NF=0.

Depois, via se res16 < -255 ou res16 > 255; se fosse, colocava OF=1, caso contrário OF=0.

Finalmente, via se os 8 bits de menor peso de res16 eram todos 0 (talvez com um AND); se fossem, colocava ZF=1, caso contrário ZF=0.

Nesta óptica, só ZF é que era analisada depois da operação, todas as outras flags eram analisadas antes.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Então me deparei com o seguinte problema

Se R0 = 0x01 e R1 = 0x7F --> R0 = R0 + R1 --> 0x80

Então ZeroFlag  = 0 , CarryFlag = 0 , OverflowFLAG = 1 , NegativeFLAG = ???

A sugestão sensata é: faz um programazinho que veja como é que o processador real se comporta.

Se não tens nenhum proc real (ou se o inventaste tu), o que te digo é que o número 0x80 é negativo porque tem o bit de maior peso a 1.

Essa classificação (negative/positive) só interessa se não houver signed overflow. Se houver, então o resultado é para esquecer, caso estejas a trabalhar com números com sinal. Se estiveres a trabalhar com números sem sinal, então não vais consultar as flags overflow/negativa, uma vez que elas só têm aplicabilidade em números com sinal.

O que devo analisar??

Penso eu que R0 = positivo e  R1 = positivo, logo soma de positivos = positivo , portando FlagN (Negative Flag) = 0x00

Me falaram que o resultado deu negativo , entao FlagN = 0x01

Pois, mas o processador funciona com aritmética modular (i.e. aneis). O facto de considerarmos metade dos números possíveis como sendo "negativos" é apenas uma convenção.

Estou com essa dúvida!!

Caso a segunda esteja certa , me explique então

R0 = 80h e R1 = 80h  --> R0 = R0 + R1 ---> FlagN = ?? , FlagZ = ?? , Overflow = ??

Negative = 0, Zero = 1, Overflow = 1

Se possível explicar todas as Flags, e dar exemplo com as possíveis operações críticas serei grato.

Positivo porque o bit de maior peso vai ser 0. Zero porque o resultado vai ser 0. E Overflow porque, ao somares dois números negativos muito baixos, saiste de fora do "range" possível para os números negativos.

Um algoritmo para detectar se há overflow? Bem... ia-te dizer que não fazia ideia, mas por acaso até tenho a referência do EFLAGS da AMD à frente e posso-te dizer como é que eles fazem:

"Overflow Flag (OF). Bit 11. Hardware sets the overflow flag to 1 to indicate that the most-significant (sign) bit of the result of the last signed integer operation differed from the signs of both source operands. Otherwise, hardware clears the flag to 0. A set overflow flag means that the magnitude of the positive or negative result is too big (overflow) or too small (underflow) to fit its defined data type."

Parece que funciona para a adição (estive a pensar nisso). Para a subtracção parece-me que precisa de uns ajustes, mas deve dar.

Um corolário é que adições com números de sinais diferentes nunca causam um overflow. Basicamente, sendo os sinais forem diferentes, o overflow seria causado se o número negativo fosse -1 e o positivo fosse o maior possível. No entanto, -1+número_grande = numero_grande-1, o que está dentro do range. O mesmo se passa com o underflow.

Se os sinais forem iguais, o resultado tá ok se tiver o mesmo sinal dos operandos.

JJ

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora