Vorzeichen-Bit invertieren (Betrag einer Zahl) ---- x86



  • Hallo!

    Mir liegt eine beliebige vorzeichenbehaftete 16-Bit-Zahl vor.
    Von dieser Zahl soll der Betrag gebildet werden.

    Mein kleines Programm dazu:

    .CODE
    START:  MOV     AX,8000H 
            CLC               ;Carry-Flag vorsichtshalber auf 0 setzen.
            SHL     AX,1      ;Vorzeichen-Bit nach CF.
            JC      M         ;Wenn CF 0, dann
            ADD     AX,8000H  ;die 16-Bit-Folge 100...00 zu AX addieren,
            JMP     ENDE      ;um das Vorzeichen-Bit auf 1 zu setzen.
    
    M:      SHR     AX,1      ;Ansonsten 0 als Vorzeichen-Bit setzen.
    ENDE:   BIN_BCD_AX        ;Zahl in AX dezimal anzeigen. 
            MOV     AH,4CH
            INT     21H
            END     START
    

    Allerdings erscheint mir meine Lösung leicht primitiv.
    Hätte da jemand eine bessere anzubieten? Mit einer Bit-Maske vll. (mir fällt zumindest nicht ein, wie mans machen könnte)?



  • Ach Mist, zwischen

    JC M
    und
    ADD AX,8000H

    muss noch "SHR AX,1" rein. Sorry. 😞



  • Ich glaub, ich bin verwirrt... Jedenfalls ist mir jetzt eingefallen, dass ich nur das Vorzeichen-Bit von einer 1 zu einer Null ändern muss und das geht ja mit

    der Bitmaske: 0111...1111 und der logischen Verknüpfung AND.

    Sry!



  • Zunaechst mal ist deine 1. Loesung auch nach Verbesserung nicht unbedingt primitiv, sondern vor allem falsch.
    Und zu deiner 2. Idee:
    Einfachheit halber mal ein Beispiel mit 8Bit integers, also -1 = 1111 1111
    Dann -1 & 0111 1111 = 127 != 1 -> nicht so sinnvoll.

    Mein Vorschlag:
    1. Kopier den int in ein allg. Register (zB. ax)
    2. teste, ob negativ (es gibt selbst beim x86 mehr als genug Moeglichkeiten, ein Register zu testen, ohne es zu veraendern). Eine simple und praktische Methode waere zB. der test-Befehl, also "test ax, ax". Dadurch wird das sign-Flag (s) entsprechend dem Wert in ax gesetzt.
    3. wenn positiv, nichts machen (s=0 - zB. also mit jns raus springen)
    wenn negativ, Wert negieren. Dazu gibt es beim x86 den schoenen, kleinen Befehl "neg".

    ... Ist also im Wesentlichen mit 3 Befehlen erledigt.



  • ging das nicht irgendwie so ähnlich?

    cdw
    xor ax,dx 
    sub ax,dx
    

    mit der absicht, den eventuell teuren fehlspung zu sparen.



  • Hm, gute Idee eigentlich. 👍
    Weiss nur nicht, ob cdw der richtige Befehl ist. 😃 AFAIR erweitert der nur al auf ah.



  • Nobuo T schrieb:

    Hm, gute Idee eigentlich. 👍
    Weiss nur nicht, ob cdw der richtige Befehl ist. 😃 AFAIR erweitert der nur al auf ah.

    du beschreibst cbw (convert byte to word)
    ich meinte cwd (convert word to doubleword)


Log in to reply