Jump to content

[C\Assembly]


eMineiro
 Share

Recommended Posts

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.

Link to comment
Share on other 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.

Link to comment
Share on other 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.

Desaparecido.

Link to comment
Share on other 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

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.