Carry flag abfragen

Lschreyer
Schreiberling
Avatar
Gender: n/a
Posts: 527
Registered: 02 / 2007
Subject:

Carry flag abfragen

 · 
Posted: 02.07.2012 - 15:21  ·  #1
Ich stehe irgendwie auf dem Schlauch, ich möchte nach einer Addition eines Words gerne das Carry Flag abfragen um zu sehen ob ein Überlauf stattfand.

Bit(Sreg,0) liefert aber immer 0.

Wie frage ich das Carry Bit ab?

Louis
Gunter
Administrator
Avatar
Gender:
Location: Frankfurt Main / Germany
Posts: 1697
Registered: 02 / 2003
Subject:

Re: Carry flag abfragen

 · 
Posted: 02.07.2012 - 15:32  ·  #2
Hallo Louis,

auch die Anweisung Bit(..) ändert ja das Prozessor Status Register.
Schau Dir im Compiler Handbuch mal Kapitel 4.15 an -> RunErr !

Gruß
Gunter
Lschreyer
Schreiberling
Avatar
Gender: n/a
Posts: 527
Registered: 02 / 2007
Subject:

Re: Carry flag abfragen

 · 
Posted: 02.07.2012 - 16:30  ·  #3
Ich habe es jetzt in Assembler gemacht, da taucht aber ein neues Problem auf:

Ich habe ein Word namens "Count".
Da addiere ich die Variable D und warte auf einen Überlauf.
Das klappt auch prima sobald ich über 65535 komme steht Carry auf "1".

Beim Subtrahieren sollte das analog gehen, da kommt das Carry Flag aber schon weit vorher, ich kann das Verhalten nicht erklären. Es geht mal an mal aus. Woran liegt das?
Wie kann ich beim Subtrahieren ein Überlauf abfragen?

Louis
Gunter
Administrator
Avatar
Gender:
Location: Frankfurt Main / Germany
Posts: 1697
Registered: 02 / 2003
Subject:

Re: Carry flag abfragen

 · 
Posted: 02.07.2012 - 16:43  ·  #4
woran das liegt?
Da muss man sich anschauen wie die Subtraktion auf ASM-Ebene
vom AVRco umgesetzt wird / werden muss.
Aber beim Subtrahieren zeigt doch das N-Flag ein neg. Ergebnis an.

Gunter
Lschreyer
Schreiberling
Avatar
Gender: n/a
Posts: 527
Registered: 02 / 2007
Subject:

Re: Carry flag abfragen

 · 
Posted: 03.07.2012 - 11:43  ·  #5
Ok, ein einfaches

kla:=kla-klb;

ergibt
Code

                        LDS       _ACCB, subtest.KLA
                        LDS       _ACCA, subtest.KLA+1
                        PUSH      _ACCB
                        PUSH      _ACCA
                        LDS       _ACCB, subtest.KLB
                        LDS       _ACCA, subtest.KLB+1
                        NEG       _ACCB
                        BRNE      subtest._L0000
                        DEC       _ACCA
subtest._L0000:
                        COM       _ACCA
                        POP       _ACCAHI
                        POP       _ACCALO
                        ADD       _ACCB, _ACCALO
                        ADC       _ACCA, _ACCAHI
                        STS       SUBTEST.KLA, _ACCB
                        STS       SUBTEST.KLA+1, _ACCA


Da wird das Carry auch ohne Nulldurchgang des Ergebnisses (manchmal) gesetzt.

Ich habe das jetzt mal so gemacht:

Code
  asm;
  LDS    _ACCA, subtest.KLa;
  LDS    _ACCB, subtest.KLa+1;
  LDS    R30, subtest.KLb;
  LDS    R31, subtest.KLb+1;

  SUB    _ACCA, R30;
  SBC    _ACCB, R31;
  STS    subtest.KLa, _ACCA;
  STS    subtest.KLa+1, _ACCB;
  endasm;


Das klappt wie gewünscht, nur beim Nulldurchgang wird Carry gesetzt, so wie es sein soll.
Soweit ich weiß werden Register ACCA, ACCB und R30 und R31 bei Interrupts gesichert,
die kann ich also doch verwenden richtig? Oder muss ich die bei Hand-Assemblercode innerhalb einer Interruptroutine selber sichern?

Lang lang ist es her, als ich Assembler auf einem PIC gelernt habe...20 Jahre schätze ich mal..Ich bin da also leider nicht mehr so der Held, ich bitte das zu entschuldigen :'(

Louis
Merlin
Administrator
Avatar
Gender:
Age: 24
Posts: 1408
Registered: 03 / 2005
Subject:

Re: Carry flag abfragen

 · 
Posted: 04.07.2012 - 11:51  ·  #6
Sorry Louis, but I have to ask. Why are you doing this? Surely the whole point of using Pascal is to get away from using assembler.

What is wrong with, for example,

Code
var 
Count : word;

...

inc( count );
if Count = 0 then
  ... overflow has occurred
endif;
...
dec( count )
if Count = $FFFF then

  ... underflow has occurred
endif;


Regards
Lschreyer
Schreiberling
Avatar
Gender: n/a
Posts: 527
Registered: 02 / 2007
Subject:

Re: Carry flag abfragen

 · 
Posted: 13.07.2012 - 12:01  ·  #7
Hello Merlin,

I have a 16 bit Word to which I add an other word or subtract an other word.
Its not just inc and dec a 1, that would be easy.
I need to know if I crossed Zero after an add or sub, and that is done by checking the carry flag after the sub or add.
Also, it runs in a very fast interrupt (25 KHz), it needs to be fast.

Louis
Merlin
Administrator
Avatar
Gender:
Age: 24
Posts: 1408
Registered: 03 / 2005
Subject:

Re: Carry flag abfragen

 · 
Posted: 13.07.2012 - 15:12  ·  #8
Hi Louis.

I understand what you mean about speed, and then it may be essential, but as a first try (obviously with the Merlin optimiser because that usually increases speed as well as reduces size) I would create two functions that return a boolean value on overflow or underflow

Code
function MyInc( var W1 : word; const W2 : word ) : boolean;
var
  iSave : word;
begin
  iSave := W1;
  inc(W1, W2);
  return( W1 < iSave );
end;


with something similar for subtraction (but with the test the opposite way round). I am not sure what speed you are running your processor at but optimised this routine is less than 40 assembler statements and much less than machine 100 cycles. At say 8 MHz this could represent up to 30% of your processor time, which may be too much (depending on your application). At 16kHz it represents less than 15% and obviously the faster your processor is going the less time this represents.

Another, more latteral approach, is to use longword rather than word and check the state afterwards, e.g.

[quote]code
var
v1 : LongWord
v1Carry[ @v1, 16] : bit;
/quote]

You may need to set Hi(v1) to zero after a carry, though.
Selected quotes for multi-quoting:   0

Registered users in this topic

Currently no registered users in this section

The statistic shows who was online during the last 5 minutes. Updated every 90 seconds.
MySQL Queries: 15 · Cache Hits: 14   131   145 · Page-Gen-Time: 0.031924s · Memory Usage: 2 MB · GZIP: on · Viewport: SMXL-HiDPI