MASM vs NASM



  • schraubendreher schrieb:

    wo muss ich denn im folgenden Programm das getch einfügen?[...]habs schon bisschen probiert aber nicht herausgefunden

    Ok, dann helfe ich dir mal etwas auf die Spruenge. 😉
    Wo du die 2 Zeilen sinnvollerweise einfuegen koenntest, habe ich bereits beschrieben. Falls der Assembler Probleme mit der Hex Notation in int 0x16 hat, schreib halt stattdessen int 16h. Dann kommentiere ich mal deinen Code noch etwas...

    segment code
    
     start:
     mov ax, data   ; Initialisierung
     mov ds, ax     ; des Datensegmentregisters
    
     mov dx, hello  ; Ausgabe eines mit dem Zeichen
     mov ah, 09h    ; "$" terminierten Strings in der
     int 21h        ; Konsole. (int 21h, Funktion 9)
    
     mov al, 0      ; Beenden des Programms
     mov ah, 4Ch    ; mit Exit Code 0
     int 21h        ; (int 21h, Funktion 4ch)
    
     segment data
     hello: db 'Hello World!', 13, 10, '$'
    


  • ok danke jetz hats geklappt 🙂

    start: 
     mov ax, data   ; data in ax kopieren
     mov ds, ax     ; ax in ds kopieren  warum nicht gleich mov ds, data?
    
     mov dx, hello  ; hello in dx verschieben
     mov ah, 09h    ; was ist ah und was bedeuten die ganzen h anweißungen?
                    ; warum heißt es nicht mov ah, dx weil in dx ist ja der text
     int 21h        ; Konsole. 
    
     mov al, 0      ; Beenden des Programms       was ist al?
     mov ah, 4Ch    ; mit Exit Code 0          was ist ah und 4Ch?
     int 21h        ; (int 21h, Funktion 4ch) 
    
     segment data 
     hello: db 'Hello World!', 13, 10, '$'  für was steht 13 und 10?
    

    Ich hab mal Kommentiert was ich da nicht ganz verstehe
    Ich mache grade dieses Tutorial:
    http://de.wikibooks.org/wiki/Assembler_(80x86_Prozessor)-Programmierung:_Das_erste_Assemblerprogramm
    Aber es wird nur der Code gepostet und mager erklärt.
    Ich hab mal gepostet was ich noch nicht verstehe,
    wäre gut wenn du das nochmal auf meine Fragen eingehst,
    aber wenn du nicht willst ist es auch ok



  • Warum nicht? Der Haufen Physik-Kram, der hier gerade vor mir liegt, bereitet mir wesentlich mehr Ungemach. 🤡

    Zu deinen Kommentaren:
    1. Die x86-CPU kann keine Konstanten direkt in Segmentregister kopieren. Daher der Umweg ueber das Allzweckregister ax.

    2. Keine Ahnung, was du hier genau im einzelnen meinst...
    Diese 3 Anweisungen fuehren zusammen die Textausgabe auf dem Bildschirm aus.

    Solche Aufrufe von DOS-Funktionen laufen idR. so, dass int 21h (also Aufruf der Interrupt-Routine hexadezimal 21) fuer einen Funktionsaufruf mit bestimmten Funktionsparametern steht. Die Parameter werden dieser Funktion in den Registern uebergeben.
    Dabei enthaelt das Register ah eine Indexnummer, um eine bestimmte Funktion auszuwaehlen, die dann mit Aufruf von int 21h ausgefuehrt werden soll.
    Je nach so gewaehlter Funktion werden dann evtl. weitere Parameter in bestimmten anderen Registern erwartet.

    zB. ist die Funktion 09 von int 21h (also ah=09h) die Ausgabe eines Strings in stdout. Die Speicheradresse des Strings wird dabei in den Registern ds und dx erwartet. Da du in dem Beispielcode ds am Anfang des Programms schon gesetzt hast, brauchst du vor dem Aufruf nur noch die Offsetadresse deines Strings nach dx kopieren.
    hello ist dabei einfach ein label, also ein Name fuer die Speicheradresse der direkt auf dieses label folgenden Daten (hier dein String) oder code. Dahinter verbirgt sich also letztendlich einfach eine konstante 16Bit-integer-zahl.

    Funktion 4c von int 21h beendet dagegen dein Programm. Der Exitcode (was du bei c als Parameter fuer return am Ende deines Programms schreiben wuerdest), wird von dieser Funktion im Register al erwartet.

    ... und so gibt es noch viele weitere Funktionen des Interrupt 21h.

    Wie gesagt: al und ah sind zwei 8Bit-Register, die zusammen das 16Bit-Register ax bilden - siehe dazu auch hier

    4ch ist eine Hexadezimalzahl. Das an die eigentliche Hex-Zahl angehaengte h kennzeichnet dabei das Zahlensystem.

    Zu dem Tutorial:
    Vielleicht kommst du mit dem Tutorial von Thomas Peschko erstmal weiter... Wirkte so beim Ueberfliegen auf mich zumindest recht ausfuehrlich.
    Bekommst du zB. hier



  • ah vielen dank 🙂
    das Tutorial bezieht sich denke ich auf TASM aber ich will ja NASM lernen.
    Dank deiner guten Erklärung verstehe ich jetzt das 1. Beispiel und dann lese ich mir nochmal den Grundlagen Teil des Tutorials durch, und dann werde ich das Tutorial schon weitermachen können.
    Das Problem ist denke ich das Assembler generell eine
    ziemlich komplexe Sprache ist.
    Aber Assembler ist ja viel kleiner als z.b. C++ oder?
    Da dürfte doch ein Tutorial z.b. das, welches ich grade mache reichen um Assembler einigermaßen zu beherrschen.
    Und die Kenntnisse sollten doch auch für RE reichen?



  • Schraubendreher schrieb:

    ah vielen dank 🙂
    das Tutorial bezieht sich denke ich auf TASM aber ich will ja NASM lernen.

    Hm... NASM, MASM oder TASM sind doch keine voellig verschiedenen Sprachen, die man einzeln "lernen" muesste.
    Alle diese Assembler benutzen die Intel-Syntax und wenn du dafuer erstmal ein Gefuehl hast, kannst du dir die paar Unterschiede im Praeprozessor auch schnell in der NASM-Hilfe anlesen.
    Zudem hat der NASM einen TASM-Modus (wie gsagt: schau in die Hilfe). 😉

    Schraubendreher schrieb:

    Das Problem ist denke ich das Assembler generell eine
    ziemlich komplexe Sprache ist.

    IMHO eigentlich gar nicht mal so. Hoechstens ungewohnt. Wenn du das Grundprinzip einmal durchschaut hast, ist es auch wirklich nicht schwer, auf andere Dialekte oder Architekturen umzusteigen.

    Schraubendreher schrieb:

    Aber Assembler ist ja viel kleiner als z.b. C++ oder?

    Was meinst du damit? Die mit Assembler erstellten Programme? Nicht unbedingt.

    Schraubendreher schrieb:

    Da dürfte doch ein Tutorial z.b. das, welches ich grade mache reichen um Assembler einigermaßen zu beherrschen.
    Und die Kenntnisse sollten doch auch für RE reichen?

    Was ist RE? Jo... Sollte gibt vielleicht einen gewissen Einstieg... Habe jetzt aber auch nicht viel davon gelesen.



  • Nobuo T schrieb:

    Was meinst du damit? Die mit Assembler erstellten Programme? Nicht unbedingt.
    Was ist RE? Jo... Sollte gibt vielleicht einen gewissen Einstieg... Habe jetzt aber auch nicht viel davon gelesen.

    also zu 1. Das die Sprache an sich kleiner ist das es halt weniger Funktionen usw gibt und man somit die Sprache schneller erlernen kann.
    und 2. meinte ich Reverse Engineering.



  • Achso, ja, mit 1 hast du wohl recht.
    Fuer "RE" brauchst du neben einem soliden Grundwissen allerdings auch noch einiges an Erfahrung. Da bezweifle ich eher, dass du nach dem Durcharbeiten von einigen Einsteigertutorials sonderlich weit kommst.



  • ich antworte mal auf den Thread, weile es auch was mit system ("PAUSE"); zu tun hat.
    Warum funktioniert das nicht? das fenster schließt sich.

    .model tiny ;Kleines Programm
    .code ; start des codes
    org 100h ; für ne com datei
    START:
    mov ah,09
    mov dx, offset derText
    int 21h ; ausführen
    xor ax, 0   ; ax = 0
    int 16h     ; -> Interrupt 0x16, Funktion 0
    ENDE:
    mov ah, 4ch ;sowas wie return
    int 21h ; ausfüren
    derText db 'Hello World!!',10d,13d,'$' ;Helloworld
    END START
    

    Und warum gibt der Assembler eine Meldung aus no stack?
    hab das aus diesem Tutorial
    http://www.it-helpnet.de/Dokumente/Programmierung/Assembler/Assembler Tutorial.html
    (das system("PAUSE") hab ich selber eingefügt)



  • mal kurz eine erklärung
    das mit dem stack hat sich geklärt.
    das problem war das ich eine exe gebaut hab aber es sollte eine com sein.
    wenn ich das programm im dos öffne geht es, aber wenn ich es ohne eingabeaufforderung öffne, schließt es sich wieder, aber warum?
    Außerdem verstehe ich nicht ganz was
    diese 3 Zeichen ,10d,13d,'$'
    hinter dem String sind.



  • mario1981 schrieb:

    ich antworte mal auf den Thread, weile es auch was mit system ("PAUSE"); zu tun hat.[...](das system("PAUSE") hab ich selber eingefügt)

    int 16h, Funktion 0 hat an sich nichts mit einem "system("PAUSE")" zu tun, es hat hier praktisch nur in etwa den gleichen Effekt, naemlich, dass auf eine Tastatureingabe gewartet wird.

    mario1981 schrieb:

    wenn ich das programm im dos öffne geht es, aber wenn ich es ohne eingabeaufforderung öffne, schließt es sich wieder, aber warum?

    Ein Konsolenfenster schliesst sich (AFAIK in allen Windows-NT-Versionen), sobald das darin laufende Programm beendet wird, bzw. es von keinem Programm mehr verwendet wird.
    Frag die Deppen von Microsoft, die die Konsole programmiert haben, warum das so ist.

    mario1981 schrieb:

    Warum funktioniert das nicht? das fenster schließt sich.

    Dein Problem liegt in dieser Zeile:

    xor ax, 0   ; ax = 0
    

    Wenn du dir mal anschaust, was eine xor-Verknuepfung tut, wird dir vermutlich auffallen, dass diese Zeile, anders als der Kommentar impliziert, genau gar nichts tut.
    um ax auf 0 zu setzen, vorxorst du es entweder mit sich selbst (xor ax, ax), oder schiebst eine 0 rein (mov ax, 0).

    mario1981 schrieb:

    Außerdem verstehe ich nicht ganz was
    diese 3 Zeichen ,10d,13d,'$'
    hinter dem String sind.

    ASCII 10 ist AFAIR der Wagenruecklauf (cursor in 1. Spalte) und 13 der Zeilenvorschub (Cursor eine Zeile nach unten setzen) ... oder anders herum...
    "$" terminiert den String fuer Ausgaben via int 21h, Funktion 9.



  • achso jetzt klappt es, danke.
    es klappt aber auch mit mov ah, 0 ? Also das mit der Eingabe.
    Und warum hat das Programm 2 ende ? Einmal ende und end start



  • in meinem Tutorial is das auch grade drangekommen:

    mov AH, 00h                ;Wenn wir ah = 1 setzen warten wir auf eine Tastatureingabe
      add AH, 01h                ;von 1 Zeichen. Das Zeichen steht nach dem INT 21h in al
      INT 21h                    ;aber das ist f?r uns hier unwichtig... ;)
    

    warum wird hier int 21h aufgerufen und das andere ist int 16h?



  • mario1981 schrieb:

    es klappt aber auch mit mov ah, 0 ? Also das mit der Eingabe.

    Funktionsnummern werden fuer die meisten DOS und BIOS Funktionen (wie diese hier) ueber das Register ah ausgewaehlt. Wird ax auf 0 gesetzt, wird ah als Teil von ax natuerlich auch 0.
    xor ax, ax ist klein und schnell, deshalb verwende ich es an dieser Stelle gern, statt ah einzeln auf 0 zu setzen.

    mario1981 schrieb:

    Und warum hat das Programm 2 ende ? Einmal ende und end start

    Hat es nicht. "ENDE:" ist einfach ein Label, das hier noch nicht einmal weiter verwendet wird. Der Name eines Labels ist weitgehend frei waehlbar und absolut willkuerlich.
    "END" kennzeichnet fuer TASM das Ende des Programms. Dahinter folgt der Name des Einstiegslabels, an dem das Programm startet.

    mario1981 schrieb:

    warum wird hier int 21h aufgerufen und das andere ist int 16h?

    Mit int 16h werden BIOS-Funktionen aufgerufen, int 21h sind Funktionen von DOS.
    Funktion 1 von int 21h tut wohl praktisch das gleiche wie Funktion 0 von int 16h. Welche von beiden du in DOS benutzt, ist in diesem Fall recht egal. Wird stdin, von dem Funktion 1 von int 21h AFAIR liest, nicht umgeleitet, wird hier intern moeglicherweise auch nur int 16h aufgerufen.


Anmelden zum Antworten