Welche virtuelle Machine um x86 Assembler zu lernen?



  • Ich habe zwei alte Bücher vom Franzis Verlag zum Thema Assemblerprogrammierung für den x86 ergattern können. Der Autor ist Wolfgang Link.

    Die Programmbeispiele wurden damals für MS-DOS und MASM und TASM geschrieben, entsprechend richtet sich das Buch an so eine Umgebung mit dem durch DOS gegebenen uneingeschränkten Hardwarezugriff.

    Dies ist für mich allerdings kein Problem, da ich sowohl MS-DOS als auch MASM habe.

    Jetzt möchte ich die beiden Bücher allerdings auf einem modernen Rechner in meiner gewohnten Betriebssystemumgebung durcharbeiten
    und das ganze daher in einer Virtuellen Machine laufen lassen.
    Allerdings weiß ich nicht, welche hier am besten geeignet wäre, immerhin machen die Programmbeispiele sicher auch irgendwelche größeren Zugriffe auf die HW, z.B. auch auf den PC Speaker. Die virtuelle Umgebung sollte das also alles können.

    Was wäre hier am besten geeignet?

    Zur Verfügung stünde:

    1. VirtualBox
    2. Qemu
    3. Bochs

    aber auch

    4. DOSBox

    Bei der DOSBox würde ich dann natürlich nur MASM einrichten müssen. Bei den anderen muss ich noch zusätzlich MS-DOS installieren.
    Aber das sollte kein Problem sein, das wichtigste ist mir erstmal
    die Harwdarekompatibiltität, also Qualität der emulierten/simulierten Umgebung, damit die Programmbeispiele alle funktionieren.

    Als nächstes hätte der Komfort Vorrang, da ich zwischen der virtuellen Umgebung und dem Hostsystem ständig wechseln muss.

    PS:
    NASM kenne ich, inline Assembler kenne ich auch, aber ich will halt streng nach dem Buch arbeiten, daher brauche ich eine DOS Umgebung und auf einem alten Rechner wollte ich das auch nicht mehr machen, also geht nur eine virtuelle/simulierte Umgebung.



  • Moin.

    Ich selber habe nur die DOSBox ausprobiert. Sonst boote ich MSDOS 6.22 oder MSDOS 7 von CD oder 2GB-USB-Stick. Innerhalb der DOSBox ist es auch möglich in den Protectedmode zu schalten(DOSBox-Konfiguration ändern), um z.B. den linearen frambuffer im 4.GB zu verwenden. Doch das VESA-VBE-Bios der verwendeten Grafikkarte kann mit DOSBox nicht verwendewt werden, sondern nur ein emuliertes VBE-Bios mit veralteten Modenummern eines VBE 1.x -Bios. Weil DOSBox nur für alte DOS-Spiele kompatibel gemacht wurde und dafür nicht das VBE-Bios von der verwendeten Graffikkarte verwendet. DOSBox kennt auch keinen CTTY-Befehl.

    Wenn man auf diese Dinge verzichten kann, dann ist die DOSBox bestens geeignet um damit MASM 5 zu verwenden. Jedoch kennt MASM 5 noch keine MMX-Befehle die erst mit MASM 6 integriert wurden. MASM 6+ kann man aber nicht unter DOS verwenden, sondern nur unter Windows. Zusammen mit dem 16 Bit-Linker von MASM 5 kann man damit aber ebenfalls 16 Bit-DOS-Anwendungen erzeugen. Wenn man MMX-Befehle(auch CPUID-Befehl) mit MASM 5 verwenden möchte, dannn muss man solche Befehle von Hand coden und als Bytes in den Code mit einfügen.
    Beispiel:

    START: mov      eax, 1              ; request for feature flags
           DB 0Fh, 0A2h                 ; CPUID instruction
           test     edx, 00800000h      ;  is MMX feature flag(bit 23) set ?
           jz  NOMMX                    ; NEIN, kein MMX
    

    Ich meine wenn man eh ein DOS erst installieren muss, dann kann man auch gleich auf eine Simulation verzichten und nur DOS booten. Bei einem Mainboard mit UEFI-Bios wird man dafür den Kompatibilitäts-Mode im BIOS verwenden müssen, weil sonst kann man kein DOS booten.

    Dirk



  • Wenn mit DOSBox gearbeitet wird, können auch neure MASM Versionen benutzt werde, da ja nur das Ergebniss in DOSBox laufen muss ;-).
    Zum linken brauch man einen 16 Bit linker, den man z.B. im MASM32 SDK finden kann (link16.exe). Zum assemblieren muss ab MASM Version 7+ die Option /omf benutzt werden.

    Wenn SIMD Befehle, dann bitte SSEx und nicht der olle MMX Befehlssatz.



  • Moin.

    MinMaxMean schrieb:

    Wenn mit DOSBox gearbeitet wird, können auch neure MASM Versionen benutzt werde, da ja nur das Ergebniss in DOSBox laufen muss ;-).

    Ja genau.

    Zum linken brauch man einen 16 Bit linker, den man z.B. im MASM32 SDK finden kann (link16.exe).

    16 Bit linker: http://download.microsoft.com/download/vc15/Update/1/WIN98/EN-US/Lnk563.exe

    Zum assemblieren muss ab MASM Version 7+ die Option /omf benutzt werden.

    Aha. Ich habe bisher nur MASM 5 und MASM 6.14 verwendet.

    Batchdatei für MASM 5:
    @ECHO OFF
    MASM /Z %1.asm,%1.obj,%1.lst,%1.crf
    if ERRORLEVEL 1 goto ENDE
    CREF %1.crf,%1.ref
    if ERRORLEVEL 1 goto ENDE
    LINK /CP:1 %1.obj,%1.exe,%1.map,,
    if ERRORLEVEL 1 goto ENDE
    if exist *.crf del *.crf
    if exist *.obj del *.obj
    :ENDE

    Batchdatei für MASM 6 mit 16 Bit Linker (Zum Ausführen unter 32 bit-Windows):
    @ECHO OFF
    ML /c /Zm %1.asm
    if ERRORLEVEL 1 goto ENDE
    LINK /CP:1 %1.obj,%1.exe,,,
    if exist *.obj del *.obj
    if exist *.map del *.map
    :ENDE

    Wenn SIMD Befehle, dann bitte SSEx und nicht der olle MMX Befehlssatz.

    Vermutlich läßt sich auch in den 64 bit Longmode schalten und damit Advanced Vector Extensions(AVX)-Befehle verwenden.(Habe ich selber noch nicht getestet.)

    Allerdings existieren MMX-Befehle schon seit der Einführung des Pentium MMX, womit die Anzahl alter Rechner die es unterstützen höher ist. Besonders auf älteren Rechnern macht es Sinn Assembler zu verwenden, weil diese Rechner am meisten davon profitieren, wenn man eine optimierten Code verwendet. Für moderne Rechner sind die Compiler für Hochsprachen mit Assembler kaum noch zu toppen.

    Dirk



  • Hier ist ein Rohgerüst für 80386/80387 zum Editieren:

    AAADUMMY.ASM

    .MODEL SMALL                          ; Programm möglichst klein halten
    .386P                                 ; 32-Bit Prozessor und Protect-Mode
    .387                                  ; Fließpunkt/-komma (Co-Prozessor)
    
      CODE SEGMENT use16 'CODE'
     assume cs:CODE,ds:DATEN,ss:STAPEL
     org 100h
    
    START:    mov      ax, DATEN
              mov      ds, ax
    
    ;-------------------------------------
           DB  0EAh                       ; Prefetch-Puffer löschen:
           DW  (OFFSET BEGINN)            ; Die folgenden Zeilen erzeugen
           DW  (SEG BEGINN)               ; das Kommando JMP FAR CS:BEGINN
    ;-------------------------------------
     org START + ((($-START)/16)*16)+16   ; Code-Ausrichtung(Alignment)
    ;-------------------------------------
    BEGINN:
    
    ;-------------------------------------
    RAUS:     xor      cl, cl             ; kein Fehler
    BACK:     mov      al, cl             ; ERRORLEVEL holen
              mov      ah, 4Ch            ; Rücksprung, Programm-Ende
              int    21h
    ;-------------------------------------
    ;    U N T E R - R O U T I N E N
    ;-------------------------------------
     org START + ((($-START)/16)*16)+16
    ;-------------------------------------
    
              ret
    ;-------------------------------------
      CODE ends
    ;-------------------------------------
    ;      D A T E N - B E R E I C H
    ;-------------------------------------
      DATEN SEGMENT use32 'DATA'
     org 0
    ;-------------------------------------
    WERT   DD ?
    ;-------------------------------------
      DATEN ends
    ;-------------------------------------
      STAPEL SEGMENT use16 STACK 'STACK'
           DB 10h dup (0)
      STAPEL ends
    ;-------------------------------------
     end
    

    Dirk



  • freecrac schrieb:

    Vermutlich läßt sich auch in den 64 bit Longmode schalten und damit Advanced Vector Extensions(AVX)-Befehle verwenden.(Habe ich selber noch nicht getestet.)

    AVX kann auch im Real Mode verwendet werden, dann aber nur mit 8 YMM Registern (genau wie in den 32 Bit Moden).

    freecrac schrieb:

    Allerdings existieren MMX-Befehle schon seit der Einführung des Pentium MMX, womit die Anzahl alter Rechner die es unterstützen höher ist.

    MMX hat keine eigenen Register, so das immer der Konflikt mit FPU Code besteht. Zudem ist SSE(2) so weit verbreitet (nach mehr als 10 Jahren), das man es als Minimum voraussetzen kann.

    freecrac schrieb:

    Für moderne Rechner sind die Compiler für Hochsprachen mit Assembler kaum noch zu toppen.

    Das halte ich für ein Märchen, verbreite von Menschen mit wenig praktischer Erfahrung.

    Grüße



  • MinMaxMean schrieb:

    freecrac schrieb:

    Vermutlich läßt sich auch in den 64 bit Longmode schalten und damit Advanced Vector Extensions(AVX)-Befehle verwenden.(Habe ich selber noch nicht getestet.)

    AVX kann auch im Real Mode verwendet werden, dann aber nur mit 8 YMM Registern (genau wie in den 32 Bit Moden).

    Gut zu wissen.

    freecrac schrieb:

    Allerdings existieren MMX-Befehle schon seit der Einführung des Pentium MMX, womit die Anzahl alter Rechner die es unterstützen höher ist.

    MMX hat keine eigenen Register, so das immer der Konflikt mit FPU Code besteht.

    Ja genau. Aber wenn man den Code aufteilt in seperate Bereiche kann man den Konflikt bestimmt etwas entschärfen.

    Zudem ist SSE(2) so weit verbreitet (nach mehr als 10 Jahren), das man es als Minimum voraussetzen kann.

    OK. (Wie schnell die Zeit doch vergeht...)

    freecrac schrieb:

    Für moderne Rechner sind die Compiler für Hochsprachen mit Assembler kaum noch zu toppen.

    Das halte ich für ein Märchen, verbreitet von Menschen mit wenig praktischer Erfahrung.

    Grüße

    Mhm, ich denke als Anfänder in Assembler hat man eher noch wenig Erfahrungen. Und Code-Optimierung ist doch wohl eher ein spezieller Fall, der zum anfänglichen Lernen der Sprache nicht unbedingt mit dazu gehört, oder nicht?

    (Ich selber habe anderseits noch kein einziges C listing compiliert und kann solche Märchen auch nicht immer glauben.)

    Dirk


Anmelden zum Antworten