MASM vs NASM



  • danke erstmal.
    Warum sollte man dafür kein Assembler brauchen?
    Disassembler geben doch Assembler code aus also muss man Assembler können O.o
    Und noch was anderes ich hab mal so zum test mit NASM ein Hello world beispielt erstellt also eine exe aber die Dos geht nur kurz auf und wieder zu.
    Wie kann ich dieses (windows übliche) problem lösen?



  • und warum benutzt du NASM?
    Was hat es für vorteile?
    Habe gehört TASM und MASM sind die einzigen 2 die in der heutigen zeit noch benutzt werden



  • Schraubendreher schrieb:

    Warum sollte man dafür kein Assembler brauchen?
    Disassembler geben doch Assembler code aus also muss man Assembler können O.o

    Ich schrieb nicht, dass du zum reverse engineering kein Assembler koennen musst, sondern dass du fuer diesen Prozess idR. keinen Assembler (vgl. Compiler fuer Hochsprachencode), also weder NASM noch MASM, brauchen wirst.

    Schraubendreher schrieb:

    Und noch was anderes ich hab mal so zum test mit NASM ein Hello world beispielt erstellt also eine exe aber die Dos geht nur kurz auf und wieder zu.
    Wie kann ich dieses (windows übliche) problem lösen?

    Genau wie bei allen Konsolenprogrammen: Starte es von der Konsole aus oder bau ein getch in dein Programm ein.

    Schraubendreher schrieb:

    und warum benutzt du NASM?
    Was hat es für vorteile?

    Es ist frei, open source, flexibel und recht up to date - hat eigentlich so ziemlich alles, was ein brauchbarer Assembler so haben sollte.

    Schraubendreher schrieb:

    Habe gehört TASM und MASM sind die einzigen 2 die in der heutigen zeit noch benutzt werden

    Dem wuerde ich widersprechen. TASM ist langsam hoffnungslos veraltet und die einzigen Gruende MASM zu benutzen waeren IMHO eine Vorliebe fuer dessen Macro-Skripte, Tutorials fuer MASM oder die Tatsache, dass er beim Visual Studio halt mit dabei ist.



  • ok danke dir 😃
    finde es klasse das es in diesem forum einen so nette Mod gibt,
    das gibt es selten in der Thematik Assembler.
    Werde nun auch NASM lernen.

    Einfach ein getch(); unten am quellcode einfügen?

    Kannst du mir mehr Infos über Reverse Engineering geben?
    Was für einen Assembler Code gibt ein Disassembler aus?
    Und diesen Code kann ich dann verändern wie ich will und dann wieder
    Compilieren?



  • Schraubendreher schrieb:

    ok danke dir 😃
    finde es klasse das es in diesem forum einen so nette Mod gibt,
    das gibt es selten in der Thematik Assembler.

    Danke auch. 😃

    Schraubendreher schrieb:

    Einfach ein getch(); unten am quellcode einfügen?

    Das waere ja kein Assembler...
    Fuer DOS muesste es folgendes tun - eingefuegt zwischen der Textausgabe und den Befehlen zum Beenden:

    xor ax, ax   ; ax = 0
    int 0x16     ; -> Interrupt 0x16, Funktion 0
    

    Schraubendreher schrieb:

    Kannst du mir mehr Infos über Reverse Engineering geben?

    Ich koennte jetzt auch nur googlen...

    Schraubendreher schrieb:

    Was für einen Assembler Code gibt ein Disassembler aus?
    Und diesen Code kann ich dann verändern wie ich will und dann wieder
    Compilieren?

    Kommt auf den Disassembler an. Der ndisasm (NASM Disassembler) wird wohl zB. NASM-kompatiblen Code ausspucken. Es gibt aber auch welche, die einfach einen Assemblercode in Intelsyntax ausspucken, der sich so nicht wieder assemblieren laesst.
    Ob das so allgemein einfach funktioniert, ein Programm zu disassemblieren, irgendwas rumzubasteln und dann wieder zu assemblieren, wuerde ich nun nicht unbedingt beschwoeren...



  • ok danke und noch eine letzte Frage.
    Ich hab mal zum Spaß mit ndis ein Programm disassembliert.
    Jedoch gibt es den Code direkt in der Console aus.
    Aber da kann man es ja nicht rauskopieren oO
    Oder doch?



  • In der Konsole kannst du oft per ">file.txt" (Dateinamen natuerlich entsprechend ersetzen) am Ende einer Kommandozeile eine Programmausgabe in eine Datei umleiten.
    Also zB.

    nasm >info.txt
    

    [edit]
    Ok, habe mir das gerade nochmal angeschaut:
    Der ndisasm ist scheinbar einer der einfacheren Disassembler.
    Der Code ist nicht direkt NASM-Kompatibel, er erkennt keine Programmformate, nimmt keine Strukturierung vor (macht also zB. auch keinen Unterschied zwischen Daten und Code), usw.

    Zum reverse engineering wuerde ich auch eher die Arbeit mit einem Debugger empfehlen. Da sieht man wenigstens direkt, was der Code macht.

    Wenn du ein Programm veraendern musst, von dem du keine Quellcodes hast, wird es wie angedeutet tatsaechlich schwierig.
    Wenn du nur wenig aendern musst, laesst sich das praktisch wohl noch am ehesten mit einem Hex-Editor machen.
    [/edit]



  • wo muss ich denn im folgenden Programm das getch einfügen?

    segment code
    
     start:
     mov ax, data
     mov ds, ax
    
     mov dx, hello
     mov ah, 09h
     int 21h
    
     mov al, 0
     mov ah, 4Ch
     int 21h
    
     segment data
     hello: db 'Hello World!', 13, 10, '$'
    

    habs schon bisschen probiert aber nicht herausgefunden



  • 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?


Anmelden zum Antworten