Forum: PC-Programmierung Assemblerprogrammierung


von Tobias Mehrl (Gast)


Lesenswert?

Hi Leute!

Ich will ein Programm schreiben, dass mir 5 Zahlen entgegennimmt und 
danach in einem Doppelwort abspeichert. Für das entgegennemen benutze 
ich ein Makro. Dieses Makro schreibt mir den ASCII-Code der Zahl in AL. 
In der Variable "Zahl" die als Doppelwort deklariert ist, sollen dann 
die 5 entgegengenommenen Zahlen abgespeichert sein. Mein Problem ist 
nun, dass ich nicht weiß wie ich den Inhalt von AL in die als Doppelwort 
deklararierte Variable "Zahl" hineinschreibe. Könnt ihr mir helfen?

Ich hab's jetzt schon mal zusammengebracht, mit dem Befehl MOV BYTE 
PTR[Zahl],BL den Inhalt von BL in Zahl zu kopieren. Das Problem ist aber 
jetzt, dass er mir in der Variable "Zahl" den vorher reinkopierten wert 
überschreibt. Was mach ich falsch?

Aussehen tut das jetzt so:

%noctls      ; Listing-Steueranweisungen werden nicht im Listing 
augegeben
%noincl      ; Incude-Dateien werden nicht im Listing ausgegeben

INCLUDE MACROS.ASM          ; Datei Macros.asm einbinden
ASSUME CS:CODE, DS:DATA     ; Segmentnamen bekannt geben
                            ; „CODE“ wird Codesegment, „DATA“ wird 
Datensegment

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
++
DATA        SEGMENT         ; Beginn des Segmentes „DATA“

    Zahl        DD            0h

DATA        ENDS            ; Ende des Segmentes „DATA“
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
++

;----------------------------------------------------------------------- 
--------------------------------------------------------
CODE         SEGMENT             ; Beginn des Segmentes „CODE“

Anfang:
            MOV AX, DATA    ; Datensegmentadresse ins ;Register AX
            MOV DS, AX      ; Inhalt von Register AX ins Register DS

            MOV AX,0h       ; AX auf 0 setzen
            MOV BX,0h       ; BX auf 0 setzen
            MOV CX,5h       ; Abbruchbedingung von LOOP in CX schreiben
            MOV DX,0h       ; DX auf 0 setzen

        Marke1:
            Read_KBD_and_Echo     ; Makro zum Einlesen einer Zahl 
aufrufen
            MOV BL,AL            ; Momentanen Inhalt von AL in BL 
speichern
            MOV BYTE PTR [Zahl + 2]
            LOOP Marke1









            Terminate_Program      ; Makro Terminate_Program aufrufen

CODE        ENDS                   ; Ende des Segmentes „CODE“
;----------------------------------------------------------------------- 
--------------------------------------------------------

END Anfang                            ; Ende des Programms
                                      ; Programm wird bei Anfang 
gestartet

von Lasse S. (cowz) Benutzerseite


Lesenswert?

Welchen Assembler du nutzt, willst du uns nicht verraten? :)

von XXX (Gast)


Lesenswert?

Hallo

Shiften dürfte nicht so ganz danebenliegen! Wie die Befehle für
deinen Assembler aussehen, sagt dir das Handbuch.

Gruß
Joachim

von Skua (Gast)


Lesenswert?

Angenommen das ist x86 Assembler.

> MOV BYTE PTR [Zahl + 2]
Wo ist hier der zweite Operand

> LOOP Marke1
Den Befehl LOOP kenn ich nicht ist das auch ein Macro?
Wo ist die Bedingung für die 5 Durchläufe?

gugge da
http://www.i8086.de/asm/8086-88-asm-stosb.html

von Skua (Gast)


Lesenswert?

Achja Doppelwort hat nur 4 Byte wie das mit 5 Zeichen Passt ist mir ein 
Rätsel.

Formuliere noch mal klarer was du willst (sollst), beachte Zahl ist 
nicht Ziffer.

von Rolf Magnus (Gast)


Lesenswert?

> Den Befehl LOOP kenn ich nicht ist das auch ein Macro?

Nein, das ist ein normaler Assembler-Befehl. Er dekrementiert CX und 
springt zur angegebenen Sprungmarke, falls es danach nicht 0 ist.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Skua schrieb:
> Achja Doppelwort hat nur 4 Byte wie das mit 5 Zeichen Passt ist mir ein
> Rätsel.

Es ist zu vermuten, daß der TO fünf Ziffern einlesen will, und diese als 
fünfstellige Dezimalzahl interpretieren will.

Damit ist es mit einer einfachen Schiebeoperation natürlich gar nicht 
mehr getan, da muss gerechnet werden.

Der Algorithmus sieht so aus:

- Ziel = 0  (32-Bit-Wert)

- Zeichen einlesen
- Zeichen in Ziffer umwandeln (0x30 -> 0, 0x39 -> 9)
- Ziel += Ziffer  (erste Stelle)

- Zeichen einlesen
- Zeichen in Ziffer umwandeln (0x30 -> 0, 0x39 -> 9)
- Ziel *= 10
- Ziel += Ziffer (zweite Stelle)

- Zeichen einlesen
- Zeichen in Ziffer umwandeln (0x30 -> 0, 0x39 -> 9)
- Ziel *= 10
- Ziel += Ziffer (dritte Stelle)

- Zeichen einlesen
- Zeichen in Ziffer umwandeln (0x30 -> 0, 0x39 -> 9)
- Ziel *= 10
- Ziel += Ziffer (vierte Stelle)

- Zeichen einlesen
- Zeichen in Ziffer umwandeln (0x30 -> 0, 0x39 -> 9)
- Ziel *= 10
- Ziel += Ziffer (fünfte Stelle)

Erweiterung:

Wird beim nach dem Einlesen der Zeichen festgestellt, daß es sich nicht 
um eine Ziffer handelt, kann die Prozedur abgebrochen werden, "Ziel" 
enthält dann den bisher eingegebenen Wert, was die Eingabe auch von ein- 
bis vierstelligen Zahlen ermöglicht.

Im Gegensatz zu den hier oft programmierten µCs kann der x86 
multiplizieren, daher sollte eine Umsetzung des obigen Algorithmus kein 
riesiges Problem darstellen.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Rufus t. Firefly schrieb:
> Im Gegensatz zu den hier oft programmierten µCs kann der x86
> multiplizieren
Also viele AVRs haben aber auch einen Multiplizierer an Board, den man 
auch per Assembler ansprechen kann auf vielfältige Weise ;)

von ingo (Gast)


Lesenswert?

> Den Befehl LOOP kenn ich nicht ist das auch ein Macro?

Soweit ich mich errinnern kann, ist LOOP <Marke> so etwas:

dec cx
jrnz marke

also ideal für (16Bit) Zählschleifen.

mfG ingo

von Rolf Magnus (Gast)


Lesenswert?

Läubi .. schrieb:
> Also viele AVRs haben aber auch einen Multiplizierer an Board

Alle ATmegas und deren Derivate (z.B. AT90CAN128).

von Skua (Gast)


Lesenswert?

@Rolf Magnus + Ingo

Danke muss mir irgendwie entfallen sein.
Hab seit ca. 3 Jahren kein x86 Assembler genutzt.

von Tobias Mehrl (Gast)


Lesenswert?

Hey Leute!

Danke für eure Hilfe!

Der Algorithmus von rufus hat mir sehr weitergeholfen. Wenn ich nun mit 
diesem READ_KBD_and_ECHO eine Zeichen einlese, dann steht dieses Zeichen 
laut Makrobeschreibung in AL. Zusätzlich dazu steht in AH eine "1". 
Keine Ahnung wo diese "1" herkommt. Nun rechne ich das Zeichen in eine 
Zahl um und speichere es wieder in AL. Wie aber bekomme ich diese Zahl 
nun in das ganze AX? Einfach mit MOV geht's ja nicht weil MOV Befehle 
der Art AX,AL nicht erlaubt... Wie bekomme ich die Zahl dennoch von AL 
in AX?

Könnt ihr mir helfen?

von Skua (Gast)


Lesenswert?

AH = 01h kommt wohl vom Funktionsaufruf.

Einfach AH löschen.

XOR AH,AH

von Tobias Mehrl (Gast)


Lesenswert?

Gibts noch eine andere Möglichkeit AH zu löschen als mit XOR?

von Skua (Gast)


Lesenswert?

Klar
Mov AH,0

Das mit dem XOR ist nur alte gewohnheit das es früher schneller war.


auch hilfreich
http://www.cs.cmu.edu/~ralf/files.html

von Tobias Mehrl (Gast)


Lesenswert?

So, also dank eurer Hilfe sieht das ganze jetzt so aus:

Anfang:
      MOV AX, DATA      ; Datensegmentadresse ins ;Register AX
      MOV DS, AX        ; Inhalt von Register AX ins Register DS

      MOV AX,0h        ; AX auf 0 setzen
      MOV BX,0h        ; BX auf 0 setzen
      MOV CX,0h        ; CX auf 0 setzen
      MOV DX,0h        ; DX auf 0 setzen

      Read_KBD_and_Echo    ; 1. Zeichen einlesen
      SUB AL,30h        ; 1. Zeichen in 1. Zahl umrechnen
      XOR AH,AH        ; Funktionsaufruf löschen
      MOV BX,10000      ; 10000 in BX speichern
      MUL BX          ; Inhalt von AX mit BX multiplizieren
      MOV CX,AX        ; AX in DX zwischenspeichern

      Read_KBD_and_Echo    ; 2. Zeichen einlesen
      SUB AL,30h        ; 2. Zeichen in 2. Zahl umrechnen
      XOR AH,AH        ; Funktionsaufruf löschen
      MOV BX,1000        ; 1000 in BX speichern
      MUL BX          ; Inhalt von AX mit BX multiplizieren
      ADD CX,AX        ; CX mit AX addieren und in DX speichern

      Read_KBD_and_Echo    ; 3. Zeichen einlesen
      SUB AL,30h        ; 3. Zeichen in 3. Zahl umrechnen
      XOR AH,AH        ; Funktionsaufruf löschen
      MOV BX,100        ; 100 in BX speichern
      MUL BX          ; Inhalt von AX mit BX multiplizieren
      ADD CX,AX        ; CX mit AX addieren und in DX speichern

      Read_KBD_and_Echo    ; 4. Zeichen einlesen
      SUB AL,30h        ; 4. Zeichen in 4. Zahl umrechnen
      XOR AH,AH        ; Funktionsaufruf löschen
      MOV BX,10        ; 10 in BX speichern
      MUL BX          ; Inhalt von AX mit BX multiplizieren
      ADD CX,AX        ; CX mit AX addieren und in DX speichern

      Read_KBD_and_Echo    ; 5. Zeichen einlesen
      SUB AL,30h        ; 5. Zeichen in 5. Zahl umrechnen
      XOR AH,AH        ; Funktionsaufruf löschen
      ADD CX,AX        ; CX mit AX addieren und in DX speichern


Nun hab ich aber doch noch einige Fragen. Nämlich: Mit 5 Zahlen die man 
eingeben soll ist die größte Zahl 99999. Diese Zahl entspricht 1869Fh. 
Wenn ich nun mein Programm mit dieser "Zahl" 99999 füttere, dann steht 
in AX 869Fh. Das ist klar, weil ich mich momentan noch nicht um den 
Übertrag kümmere. Wie aber mach ich das am besten? Irgendwie muss ich 
wahrscheinlich noch die Stelle um irgendein Codeschnipsel ergänzen an 
der addiert bzw. multipliziert wird, denn nur an diesen beiden Stellen 
kann überhaupt ein Übertrag entstehen. Wie aber fang ich das da ab?

Könnt ihr mir nochmal helfen?

von Tobias Mehrl (Gast)


Lesenswert?

Noch eine Frage. Ich soll nun die berechnete Zahl auf dem Bildschirm 
mittig ausgeben. Ich hab jetzt schon einige Zeit damit verbracht Antwort 
in meinem Assemblerbuch zu finden, aber über die Makros Display_Char und 
Display_String kann ich leider keine weiteren Informationen finden. Vor 
allem stell ich es mir schwierig vor, da ja die Zahl als Hex im Register 
vorliegt und ich soll ja bestimmt nicht die Hex-Zahl sondern die 
Dezimalzahl ausgeben... Wie gesagt, ich weiß nicht wie das gehen soll...

Vielleicht helft ihr mir einfach nochmal! Dankeschön!

von Skua (Gast)


Lesenswert?

Erstmal
Anfang:
      MOV AX, DATA      ; Datensegmentadresse ins ;Register AX
      MOV DS, AX        ; Inhalt von Register AX ins Register DS

      MOV AX,0h        ; AX auf 0 setzen
      MOV BX,0h        ; BX auf 0 setzen
      MOV CX,0h        ; CX auf 0 setzen
      MOV DX,0h        ; DX auf 0 setzen

      Read_KBD_and_Echo    ; 1. Zeichen einlesen
      SUB AL,30h        ; 1. Zeichen in 1. Zahl umrechnen
      XOR AH,AH        ; Funktionsaufruf löschen
      PUSH BX
      MOV BX,10000      ; 10000 in BX speichern
      MUL BX          ; Inhalt von AX mit BX multiplizieren
      POP BX
      MOV CX,AX        ; DX:AX in BX:CX zwischenspeichern
      MOV BX,DX

      Read_KBD_and_Echo    ; 2. Zeichen einlesen
      SUB AL,30h        ; 2. Zeichen in 2. Zahl umrechnen
      XOR AH,AH        ; Funktionsaufruf löschen
      PUSH BX
      MOV BX,1000        ; 1000 in BX speichern
      MUL BX          ; Inhalt von AX mit BX multiplizieren
      POP BX
      ADD CX,AX        ; addiere DX:AX auf BX:CX
      ADC BX,DX

      Read_KBD_and_Echo    ; 3. Zeichen einlesen
      SUB AL,30h        ; 3. Zeichen in 3. Zahl umrechnen
      XOR AH,AH        ; Funktionsaufruf löschen
      MOV BX,100        ; 100 in BX speichern
      MUL BX          ; Inhalt von AX mit BX multiplizieren
      ADD CX,AX        ; addiere DX:AX auf BX:CX
      ADC BX,DX

      Read_KBD_and_Echo    ; 4. Zeichen einlesen
      SUB AL,30h        ; 4. Zeichen in 4. Zahl umrechnen
      XOR AH,AH        ; Funktionsaufruf löschen
      PUSH BX
      MOV BX,10        ; 10 in BX speichern
      MUL BX          ; Inhalt von AX mit BX multiplizieren
      POP BX
      ADD CX,AX        ; addiere DX:AX auf BX:CX
      ADC BX,DX

      Read_KBD_and_Echo    ; 5. Zeichen einlesen
      SUB AL,30h        ; 5. Zeichen in 5. Zahl umrechnen
      XOR AH,AH        ; Funktionsaufruf löschen
      ADD CX,AX        ;  addiere DX:AX auf BX:CX
      ADC BX,DX

von Tobias Mehrl (Gast)


Lesenswert?

Hm, Danke für deine Mühe, aber die Befehle Push, Pop und ADC haben wir 
noch nicht durchgenommen. Gibt es keine andere Möglichkeit?

von Skua (Gast)


Lesenswert?

Anstatt PUSH POP kannst du das ganze auch im Datensegment speichern.
An ADC geht kaum ein weg vorbei.
Umständlich:
     ADD BX,AX
     JNC Labelx   ; Kein Überlauf
     ADD CX,1     ; bei Überlauf 1 Addieren (INC CX ginge auch)
Labelx:

von Skua (Gast)


Lesenswert?

Bitte im letzten Beispiel CX und BX tauschen.

von Eggy (Gast)


Lesenswert?

Erst mal die Frage: Wieso willst Du kein XOR verwenden um Register zu 
nullen? Das ist die einfachste und schnellste Möglichkeit... da Dein 
Sourcecode kommentiert ist spielt das also keine Rolle.

Dann eine andere Frage: Was ist mit SI und DI? Die kann man doch auch 
bentutzen... oder hab ich da was falsch in Erinnerung?

Und zu guter letzt: Register die man benutzt sollte man sichern, 
initialisieren (z. B. mit 0x00 bzw 0x0000) und zum Schluss wieder 
herstellen (lernst Du später bei PUSH and POP ;)), nur um die Frage zu 
beantworten wieso DH 1 war: Weil es ein anderer Programmteil (Dein 
eigener oder ein anderer) so hinterlassen hat und möglicherweise so auch 
wieder benötigt (z. B. im Falle nach dme Aufruf von Unterroutinen). Da 
ich, bis jetzt, nur WinASM genutzt hatte (16 Bit-Coding hab ich recht 
früh fallen gelassen) weiß ich dass manche Register frei zur Verfügung 
stehen, manch andere nicht. Das ist so zumindest unter 
Windows-API-Programmierung. EAX, ESI und EDI sind z. B. solche freien, 
deren Werte sind undefiniert nach einem API-Call. Alle anderen muss man 
sichern und wieder herstellen. Daher mein letzter Tipp, da ich den Rest 
des Codes nicht kenne schadet ein Hinweis sicher nicht. Man sollte sich 
das gleich angewöhnen um spätere, unerwartete Fehler zu vermeiden.

Last but not least: Du willst Zahlen einlesen? Dann stell auch sicher 
dass die Eingabe eine Zahl war, man kann nicht einfach einen Wert 
abziehen und hoffen dass draus eine Zahl wird! So was kann in einer 
bösen Sicherheitslücke enden und man sollte sich von Anfang an 
angewöhnen Eingabefehler abzufangen, also erst prüfen ob es eine Zahl 
war, falls nicht muss eine Fehlermeldung ausgegeben werden und die 
Eingabe beginnt von vorne. Besser wäre natürlich wenn der Benutzer gar 
keine Zahlen erst eingeben kann... ob das bei "Read_KBD_and_Echo" weiß 
ich aber nicht, falls das der Fall ist ignoriere meinen Einwand. ;)

So, das wars von mir... interessant dass ich noch was davon behalten 
habe ^^

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Tobias Mehrl schrieb:
> Der Algorithmus von rufus hat mir sehr weitergeholfen.

Und warum hast Du es dann doch anders gemacht? Würdest Du jeweils das 
Ergebnis mit 10 multiplizieren, hättest Du die Chance, auch Zahlen mit 
weniger als 5 Stellen einlesen zu können. So aber ist die erste Ziffer 
immer der Zehntausenderwert.

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

@Tobias

die Kommentare deiner Assemblerbefehle könntest du noch optimieren.


einfache Regel:

Kommentiere nicht WAS du machst, sondern WARUM du es machst. Schreibe 
einen Kommentar hinein, den du auch noch in 5 Jahren direkt verstehst, 
und wo du nicht grübeln mußt "warum hatte ich denn jetzt eigentlich 
genau diesen Befehl hier verwendet"?

--> Das Ziel sollte sein: "Eine Zeile Kommentar ist wertvoller als eine 
Zeile Code"

Beispiele:

1.

      MOV AX,0h        ; AX auf 0 setzen
      MOV BX,10000      ; 10000 in BX speichern

Kommetare wie die zuvor genannten sind ziemlich "unnütz". DAS die 
Befehle genau das machen was du daneben geschrieben hast, steht im 
Datenblatt des Prozessors/Assemblerbefehls. Was die Intention ist, in 
deinem Algorithmus genau diesen Wert zu nutzen, steht jedoch nicht im 
Datenblatt


2.

      XOR AH,AH        ; Funktionsaufruf löschen

DASS damit der AH auf den Wert "0" gesetzt wird ist mit ein bischen 
Datenblattstudium zu identifizieren (anstelle des "tricky" XOR hätte ich 
hier ein MOV Statement empfohlen). Aber wieso wird dadurch ein 
"Funktionsaufruf gelöscht"?




3.
      SUB AL,30h        ; 1. Zeichen in 1. Zahl umrechnen

uhhh, Magie greift um sich. Eine Zahl wird umgerechnet. WIESO?
Kommentar-Vorschlag z.B.

ASCII "0" = 0x30 ... ASCII "9" = 0x39.
ACSII-Offset subtrahieren, um echte Binärzahl zu erhalten.

von asm guru (Gast)


Lesenswert?

>Vor allem stell ich es mir schwierig vor, da ja die Zahl als Hex im >Register
>vorliegt und ich soll ja bestimmt nicht die Hex-Zahl sondern die
>Dezimalzahl ausgeben... Wie gesagt, ich weiß nicht wie das gehen soll...

Eine reine Hex-Zahl kannst du in Decimal umwandeln wenn du fortlaufend 
durch 10 teilst. Die Reste pushst du in einer Schleife auf den Stack und 
liest sie dann, in einer zweiten schleife, wieder runter und gibst sie 
aus. (Aber Vorsicht, die X86-Division ist ein Befehl den du sehr gut 
verstehen musst.) Vor der Ausgabe musst natürlich noch auf Ascii (mit 
Addition) konvertieren.

Du bist bestimmt Student im Info-Kurs (das ist eine der typischen 
Aufgaben mit Fallstricken) und ich schätze mal selbst wenn du dich 
reinkniest, wirst du Tage brauchen bist du die ganze Aufgabe gelöst 
hast. Viel Erfolg!

von Tobias Mehrl (Gast)


Lesenswert?

@ asm Guru:

Also ich rechne ein Zahl von Hex in Dezimal so um:

     3:   3 ·     1 =      3
     7:   7 ·    16 =    112
     1:   1 ·   256 =    256
     B:  11 ·  4096 =  45056
                      ——————
                       45427

Wie du das meinst mit fortlaufen durch 10 teilen verstehe ich nicht. Von 
einer Hex-Zahl zurück auf eine Dezimalzahl komme ich doch nur mit dem 
oben gezeigten Schema... Das mit dem Stack mag dann einleuchten, 
funktioniert aber auch so lange nicht wie ich nicht die "Reste" meiner 
eingegebenen fünfstelligen Zahl habe!

von Karl H. (kbuchegg)


Lesenswert?

Tobias Mehrl schrieb:

> Wie du das meinst mit fortlaufen durch 10 teilen verstehe ich nicht.


  wie zerlegst du die Zahl 4598 in die einzelnen Ziffern?

   4598 % 10               macht  8
   4598 / 10   macht 459

   459 % 10                macht  9
   459 / 10    macht 45

   45 % 10                 macht  5
   45 / 10     macht 4

   4 % 10                  macht  4
   4 / 10      macht 0 -> fertig


Lies die Ziffern in den Modulo (%) Zeilen von unten nach oben.
Da steht  4  5  9  8
und die ursprüngliche Zahl war 4598



> Von
> einer Hex-Zahl zurück auf eine Dezimalzahl komme ich doch nur mit dem
> oben gezeigten Schema...

Du willst das Horner Schema anwenden.

Das besagt:
anstatt zu rechnen

   (4 * 1000) + (5 * 100) + (9 * 10) + (8*1)

kannst du auch rechnen

   (((((4) * 10) + 5) * 10) + 9) * 10 + 8

anstelle von unterschiedlichen Multiplikanden 1000, 100, 10 
multiplizierst du einfach immer nur mit 10

Die Zerlegung ist dann einfach nur die Umkehrung davon

von Karl H. (kbuchegg)


Lesenswert?

Wegstaben Verbuchsler schrieb:

> Kommentiere nicht WAS du machst, sondern WARUM du es machst.

Völlig richtig

> --> Das Ziel sollte sein: "Eine Zeile Kommentar ist wertvoller als eine
> Zeile Code"

Zugegeben: In Assembler ist das verdammt schwer bis unmöglich. Aber das 
Ziel ist eigentlich, dass der Code sein eigener Kommentar ist. D.h. ein 
wirklich guter Code braucht nicht unbedingt einen Kommentar, weil alles 
wichtige schon im Code steht.
Wie gesagt: In Assembler geht das nicht, aber in einer Hochsprache 
schon. zb durch die Wahl von Variablennamen und/oder Funktionsnamen kann 
ein Code ganz schön sprechend werden. Aber das hindert ja niemanden, 
auch in Assembler um zb die jeweils günstigste Zahlendarstellung zu 
kämpfen und sich so dem großen Ziel wenigstens ein bischen anzunähern.

In diesem Sinne ....

>       SUB AL,30h        ; 1. Zeichen in 1. Zahl umrechnen
>
> uhhh, Magie greift um sich. Eine Zahl wird umgerechnet. WIESO?
> Kommentar-Vorschlag z.B.
>
> ASCII "0" = 0x30 ... ASCII "9" = 0x39.
> ACSII-Offset subtrahieren, um echte Binärzahl zu erhalten.

... ist es hier die beste Lösung, auf einen Kommentar alle '0' abziehen 
zu verzichten, sondern gleich zu schreiben

        SUB  AL, '0'     ; aus dem Zeichen eine Zahl machen

das der ASCII Code für '0' die 0x30 ist, braucht niemand zu 
interessieren.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.