Assembler Integer invertieren?

Dieses Thema im Forum "Software" wurde erstellt von LotadaC, 31. Mai 2018.

  1. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.901
    Zustimmungen:
    43
    Punkte für Erfolge:
    48
    Sprachen:
    BascomAVR, 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?
     
  2. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    223
    Zustimmungen:
    17
    Punkte für Erfolge:
    18
    Sprachen:
    C, Assembler
    BRVC statt BRNE. Das MSB muß nur inkrementiert werden, wenn ein Übertrag auftritt (wenn ich mich recht erinnere).
     
  3. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    223
    Zustimmungen:
    17
    Punkte für Erfolge:
    18
    Sprachen:
    C, Assembler
    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.
     
  4. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.901
    Zustimmungen:
    43
    Punkte für Erfolge:
    48
    Sprachen:
    BascomAVR, Assembler
    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.
     
  5. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.901
    Zustimmungen:
    43
    Punkte für Erfolge:
    48
    Sprachen:
    BascomAVR, Assembler
    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...)
     
  6. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    223
    Zustimmungen:
    17
    Punkte für Erfolge:
    18
    Sprachen:
    C, Assembler
    Tja, lange ist es her. Da habe ich wohl das Overflow mit dem Carry-Flag verwechselt.
    Logisch richtig wäre es hier das Carry zu verwenden, aber in diesem Fall kommt man mit dem Zero-Flag zum gleichen Ergebnis.
     
  7. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    223
    Zustimmungen:
    17
    Punkte für Erfolge:
    18
    Sprachen:
    C, Assembler
    Dann muß man bei größeren Zahlen erst alles invertieren und dann addieren.
     
  8. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.901
    Zustimmungen:
    43
    Punkte für Erfolge:
    48
    Sprachen:
    BascomAVR, Assembler
    Ja, aber andersrum als gedacht... NEG-->
    C=Not(Z), also Jacke wie Hose...
    Genau.
     
  9. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    223
    Zustimmungen:
    17
    Punkte für Erfolge:
    18
    Sprachen:
    C, Assembler
    Ja, das war mir schon klar... ;)
     
  10. TommyB

    TommyB Premium Benutzer

    Registriert seit:
    17. Mai 2010
    Beiträge:
    1.667
    Zustimmungen:
    53
    Punkte für Erfolge:
    48
    Sprachen:
    Assembler, LunaAVR, VB.Net, Python, C#
    Jetzt hat @Dirk ein Déjà-vu :D (Insider)
     
    Dirk gefällt das.
  11. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.901
    Zustimmungen:
    43
    Punkte für Erfolge:
    48
    Sprachen:
    BascomAVR, Assembler
    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)
     
  12. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    223
    Zustimmungen:
    17
    Punkte für Erfolge:
    18
    Sprachen:
    C, Assembler
    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

    Unsere immer weiter wachsende Community beschäftigt sich mit Themenbereichen rund um Mikrocontroller- und Kleinstrechnersysteme. Neben den Themen Design von Schaltungen, Layout und Software, beschäftigen wir uns auch mit der herkömmlichen Elektrotechnik.

    Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  • Coffee Time

    Unser makerconnect-Team arbeitet hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und unser eigener makerconnekt-Server regelmäßig gewartet wird. Wir nehmen das Thema Datensicherung und Datenschutz sehr ernst und sind hier sehr aktiv, auch sorgen wir uns darum, dass alles Drumherum stimmt!

    Dir gefällt das Forum und die Arbeit unseres Teams und du möchtest es unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft, unser Team freut sich auch über eine Spende für die Kaffeekasse :-)
    Vielen Dank!
    Dein makerconnect-Team

    Spende uns! (Paypal)
  1. Diese Seite verwendet Cookies, um Inhalte zu personalisieren und die Seite optimal für dich anzupassen. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden