Assembler Integer invertieren?

LotadaC

Sehr aktives Mitglied
22. Jan. 2009
3.547
70
48
Marwitz
Sprachen
  1. BascomAVR
  2. Assembler
...also Integer (im Sinne des Zweierkomplements) quasi mit "-1" multiplizieren - gibts da 'n Trick?

Wenn ich mich recht erinner, müssen alle Bits invertiert werden (Einerkomplement), und anschließend eins addiert werden.

Bei einem Byte kann man das entweder genau so machen ("COM", "INC"oder "SUBI"), oder die genau dafür gedachte Instruktion "NEG" verwenden.
Aber was ist mit Mehr-Byte-Integern?

Meine bisher kürzeste Lösung wäre:


CodeBox Assembler
          COM MSB
          NEG LSB
          BRNE feddich
          INC MSB
feddich:  NOP

Wären vier Takte.
Korrekt?
Gibts was besseres?
 
BRVC statt BRNE. Das MSB muß nur inkrementiert werden, wenn ein Übertrag auftritt (wenn ich mich recht erinnere).
Set if there is a two’s complement overflow from the implied subtraction from zero; cleared otherwise.
A two’s complement overflow will occur if and only if the contents of the Register after operation
(Result) is $80.
 
Vielleicht wäre das besser:

CodeBox Assembler
COM LSB
ADD LSB,#1
COM MSB
ADC MSB.#0
(Kenne mich mit der Asseblersyntax nicht mehr so aus, aber ich denke Du weißt was ich meine)

Das hätte auch den Vorteil, daß man das durch weitere COMs und ADCs für größere Zahlen erweitern kann.
 
COM setzt das Carry, also Zeile zwei und drei tauschen. Kostet allerdings zwei Rechenregister und ggf entsprechende Load-Instruktionen (ab hinreichend großen Integern lohnt sich das, korrekt)

Wegen Branch if V clear schau ich nochmal...
Danke.
 
Branch if V clear schau ich nochmal
So?


CodeBox Assembler
.equ var=256
          LDI r16, high(var)
          LDI r17, low(var)
          COM r16
          NEG r17
          BRVC feddich
          INC r16
feddich:  NOP

liefert R16:R17=0xFE00=-512



CodeBox Assembler
.equ var=256
          LDI r16, high(var)
          LDI r17, low(var)
          COM r16
          NEG r17
          BRNE feddich
          INC r16
feddich:  NOP

liefert R16:R17=0xFF00=-256
paßt.

Mein Gedankengang war:
  1. Um einen Integer mit -1 zu multiplizieren, sind alle Bits zu toggeln, und anschließend "1" zu addieren.
  2. Da das ganze in mehreren Bytes abläuft, ist der Überlauf von einem Byte zum nächsten zu berücksichtigen.
  3. Da nur immer eins addiert wird, bedeutet Überlauf, daß das Byte von 0xFF nach 0x00 überläuft, also Z gesetzt ist
  4. (INC manipuliert das C nicht, SUBI liefert bei "-1" auch immer 'n C...)
 
Tja, lange ist es her. Da habe ich wohl das Overflow mit dem Carry-Flag verwechselt.
Set if there is a borrow in the implied subtraction from zero; cleared otherwise. The C Flag will be set
in all cases except when the contents of Register after operation is $00.
Logisch richtig wäre es hier das Carry zu verwenden, aber in diesem Fall kommt man mit dem Zero-Flag zum gleichen Ergebnis.
 
Logisch richtig wäre es hier das Carry zu verwenden
Ja, aber andersrum als gedacht... NEG-->
C R7 + R6 + R5 + R4 + R3 + R2 + R1 + R0
Set if there is a borrow in the implied subtraction from zero; cleared otherwise. The C Flag will be set
in all cases except when the contents of Register after operation is $00.
C=Not(Z), also Jacke wie Hose...
Dann muß man bei größeren Zahlen erst alles invertieren und dann addieren.
Genau.
 
  • Like
Reaktionen: Dirk
Bei 16bit ginge, wenn man die 16bit-fähigen Register verwendet auch "COM-COM-ADIW" - wobei das auch vier Takte sind...
(ließe sich auch mit weiteren 8/16bit-Registern kaskadieren)
 
(ließe sich auch mit weiteren 8/16bit-Registern kaskadieren)
wobei ADIW das Carry nicht berücksichtigt (es wird zwar gesetzt, aber nicht addiert), d.h. für jedes weitere Wort muß noch extra getestet werden, ob es gesetzt wurde.
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)