[AVR] Hoe maak ik negatief verschil getal positief?

Hoe maak ik een negatief verschil van een 8-bit getal positief?

Stel A = 100 en B = 120 -> A - B = -20 is dus 236 (8-bit)

sub A, B

Hoe kan ik van A (die nu 236 is) 20 maken? Want ik heb het positieve verschil getal nodig, om wat af te tellen.

Probleem is.

sub A, B

blijft bestaan. A en B veranderen.

Dus als A = 120 en B = 100, dan in A 20. (120-100=20)

[Bericht gewijzigd door RES op ]

if a>b then....
else....?

Hangt van de taal af.
anders ABS()

[Bericht gewijzigd door GJ_ op ]

Op 26 augustus 2006 17:44:26 schreef GJ_:
if a>b then....
else....?

Hangt van de taal af.
anders ABS()

Moet in ASM.
Ik doe dit om A en B niet aan te tasten.

mov temp, A ;A in temp
sub temp, B ;temp - B

Zoek eens op google over "Two's complement", dan kom je er denk ik wel uit.
Edit, zelf ook even opgefrist: http://www.asmcommunity.net/x86book/index.php?title=Data_Representatio…

[Bericht gewijzigd door Henry S. op ]

Ow, sorry. Topictitel niet goed gelezen (AVR). Daar weet ik niet zoveel van.

Negatief naar positief (en andersom) kan met de neg instructie. 'neg temp' dus. Maar dan worden positieve uitomsten wel negatief, ik weet niet of dat voorkomt.

Op 26 augustus 2006 17:50:11 schreef madwizard:
Negatief naar positief (en andersom) kan met de neg instructie. 'neg temp' dus. Maar dan worden positieve uitomsten wel negatief, ik weet niet of dat voorkomt.

Ja das het probleem.
Maar ik zie ineens wat in de instructieset.

brpl

Ook niet ingewikkeld dan, instructie heb je al gevonden:


    mov  temp, A
    sub  temp, B
    brpl positive
    neg  temp
positive:

Wat gebeurt er als A = B dus verschil van 0?
neg over 0? Op zich maakt het niet uit voor de code die ik heb. Want ik doe dit.

mov  temp, A
sub  temp, B
brpl positive
neg  temp
positive:
cp   A, B
brlo faster

[Bericht gewijzigd door RES op ]

Neg 0 blijft 0, maar met brpl wordt de neg niet uitgevoerd als het resultaat nul is. Nul wordt namelijk als positief gezien. Dat is ook de reden dat je 1 negatief getal meer hebt dan positief getal (8-bits is negatief tot -128, maar positief +127, omdat de 0 ook bij de positieve waarden hoort).

Neg getal positief maken ?

Bit 7 op 0 zetten daarna getal met 1 incrementeren


-20 = 236 = 11101100
Bit 7 op 0: 01101100
Plus 1    : 01101101

01101101 = 109

Werkt niet dus. Juiste algoritme is alle bits inverteren en dan er 1 bij optellen, maar dat is wat de neg instructie al doet (is meer werk om dat zelf te doen). Daarnaast is dat niet het enige doel van RES, zoals uit eerdere posts al bleek.

Je hebt gelijk
alles inverteren zet bit-7 ook op 0 he ;)
Maar is ook alweer erg lang geleden he
mag ik mij ook eens vergissen
kan niet alles weten wat een ander zelf ook bijeen kan goegelen.
ben tenslote geen saaie kompjoeter maar een super coole goser !!!

Op 26 augustus 2006 19:39:23 schreef Capt501:
Neg getal positief maken ?

Bit 7 op 0 zetten daarna getal met 1 incrementeren

TS werkt met unsigned getallen, dit trucje werkt alleen met signed, dan geeft bit 7 wel positief/negatief aan :)

Bit 7 mag dan wel de sign bit zijn maar dat maakt het trucje nog steeds niet goed. Je moet echt alle bits inverteren, de negatieve getallen lopen omgekeerd (FF=-1, FE=-2 etc.).

De code die hier gebruikt wordt (met brpl en neg) werkt trouwens alleen met signed getallen, als je 240 en 20 als getallen hebt bijvoorbeeld gaat het de mist in (komt 36 uit). Dat komt omdat brpl en neg op signed getallen werken.

Op 27 augustus 2006 00:36:05 schreef madwizard:
Bit 7 mag dan wel de sign bit zijn maar dat maakt het trucje nog steeds niet goed. Je moet echt alle bits inverteren, de negatieve getallen lopen omgekeerd (FF=-1, FE=-2 etc.).

De code die hier gebruikt wordt (met brpl en neg) werkt trouwens alleen met signed getallen, als je 240 en 20 als getallen hebt bijvoorbeeld gaat het de mist in (komt 36 uit). Dat komt omdat brpl en neg op signed getallen werken.

Die code is dus niet waterdicht?
Werkt prima.
Weet even niet meer wat signed en unsigned was.

Op 26 augustus 2006 23:47:09 schreef Wouter Sijm:
TS werkt met unsigned getallen, dit trucje werkt alleen met signed, dan geeft bit 7 wel positief/negatief aan :)

Maakt geen drol uit, het is een kwestie van interpretatie. Alleen met signed is je bereik uiteraard verschoven. Je mag dan bijvoorbeel het getal 128 niet meer gebruiken in een 8 bits word, omdat dat er niet meer inpast.

Als hoogste bit = 1, dan alles inverteren en er 1 bij optellen


NOT(1110 1100) + 1 = 0001 0011 + 1 = 0001 0100
      NOT(236) + 1 =        19 + 1 =        20

Ofwel binnen het 8 bits bereik:

if getal > 127 then getal = 256 - getal

Op 27 augustus 2006 10:24:41 schreef RES:
Die code is dus niet waterdicht?
Werkt prima.
Weet even niet meer wat signed en unsigned was.

Unsigned is alleen positief, van 0 tot het maximum. Voor 8-bits dus 0 t/m 255. Signed is positief of negatief. De ene helft (0 t/m 127) is net zoals unsigned gewoon een positieve waarde. De rest (128 t/m 255) stellen negatieve waarden voor. Hierbij is 255=-1, 254=-2 enz. 129 is -127, 128 is -128. Bij elkaar geeft dit een range van -128 t/m +127. Omdat de echte waarde van alle negatieve getallen hoger dan of gelijk is aan 128, hebben deze getallen allemaal een 1 in de hoogste bit. Hieraan kun je herkennen dat een signed getal negatief is. Of een getal signed of unsigned is maak je zelf uit. Optellen en aftrekken is hetzelfde algoritme voor beiden, maar voor branches, vermenigvuldigen e.d. heb je verschillende instructies voor signed en unsigned. Er is een brlo (branch if lower, unsigned) en een brlt (branch if less than, signed) bijvoorbeeld.

Code werkt prima zolang het verschil tussen A en B maar niet groter dan 127 wordt. Dit is een probleem omdat brpl uitgaat van een signed resultaat. Je wilt immers jumpen als het resultaat positief is. Unsigned is altijd positief en daar is die instructie dan ook niet voor. brpl kijkt eigenlijk gewoon in de N (negative) status bit. Die is gelijk aan de hoogste bit van het resultaat, oftewel 1 indien negatief en 0 indien positief.

Omdat signed getallen maar van -128 t/m +127 gaan kun je geen resultaten hebben buiten deze range. Als A 240 is en B 20, krijg je 220 als resultaat. Dat kan niet als signed getal, 220 wordt als -36 geinterpreteert. De brpl zal dit als negatief zien en niet branchen, waarna de neg instructie er +36 van maakt.

Code werkt prima zolang het verschil tussen A en B maar niet groter dan 127 wordt. Dit is een probleem omdat brpl uitgaat van een signed resultaat. Je wilt immers jumpen als het resultaat positief is. Unsigned is altijd positief en daar is die instructie dan ook niet voor. brpl kijkt eigenlijk gewoon in de N (negative) status bit. Die is gelijk aan de hoogste bit van het resultaat, oftewel 1 indien negatief en 0 indien positief.

Das weer toeval ik gebruik 7-bits getallen. (0-127)

Dan is het geen probleem :). En trouwens, je kunt het simpel laten werken voor 8-bits getallen door geen brpl te gebruiken maar brsh (branch if same or higher).

Je kunt namelijk wel zien aan de status bits of de ene groter was dan de andere (of het resultaat door de 0 heen ging zeg maar).

Een compare is niets anders dan een sub zonder het resultaat op te slaan. Een brsh achter een sub werkt dus hezelfde als achter een cp. In dit geval branch je dan dus als A groter of gelijk was aan B, unsigned (dus gaat ook goed bij grotere getallen). Als dat niet zo was kan het resultaat onzin zijn (20-240 geeft 36) maar de neg maakt dit weer helemaal goed (-36 is 220).

Werkt dit ook?

in temp, SREG
sbrc temp, 2

Jammer dat je niet sbrc/sbrs op het SREG kan doen.

Dat kan ook, is hetzelfde als 'brbc 2, positive' en dat is weer hetzelfde als 'brpl positive'. Maar die laatste 2 nemen minder ruimte in en voeren sneller uit.