Home

Erste Bekanntschaft
mit dem MASM32 SDK

Testprogramm zum Einlesen
der Programmaufrufparameter

MASM32-
Infoseite

MASM32 SDK (Windows Konsole):
PROC, ENDP, PROT, INVOLVE und APIs

Wohl die meisten Befehle eines Assemblerquellprogramms betreffen den Prozessor (Central Processing Unit, CPU). Weitere Befehle eines Assemblierprogramms dienen dazu, das Assemblierprogramm für besondere Tätigkeiten zu steuern. Diese Befehle werden als Pseudoassemblerbefehle, Pseudobefehle, Assembleranweisungen, Assemblerdirektiven, Direktiven u.ä. bezeichnet.

Diese Webseite behandelt die Assemblerdirektiven PROC, ENDP, PROT und INVOLVE. In diesem Zusammenhang wird auf Anwendungsschnittstellen (APIs Application Programming Interfaces, API in der Einzahl) und die beiden Assemblierungsduchläufe (Pass 1 und Pass 2) kurz eingegangen.

Funktionen und Prozeduren
Bei Prozeduren und bei Funktionen handelt es sich um Unterprogramme. Sie werden - je nach Fall - mit oder ohne Parameter aufgerufen. Prozeduren geben an ihrem Aufrufer keinen Rückgabewert zurück. Funktionen geben mindestens einen Rückgabewert zurück.

Zur Definition von Prozeduren und bei Funktionen steuert das im MASM32 SDK genutzte Assemblierprogramm ML das Direktivenpaar PROC und ENDP bei. PROC, ENDP, PROT und INVOLVE haben allesamt etwas mit Unterprogrammaufrufen zu tun.

Glaubt man der üblichen Assemblerliteratur, so muss ein Assemblerunterprogramm mit PROC eingeleitet werden sein Schluss muss ENDP gekennzeichnet werden. Was dabei verschwiegen wird: Man muss das Pärchen PROC und ENDP nur dann verwenden, wenn es erforderlich ist. Unterprogramme lassen sich auch ohne dies beiden Assemblerdirektiven schreiben. Ich habe mir deshalb angewöhnt, PROC und ENDP nur dann zu schreiben, wenn es erforderlich ist. Beispielsweise kann man die Befehlssequenzen

main proc
    cls
    print "Hello World",13,10
    ret
main endp
des Progrämmchens aus der  i vorigen Webseite platzsparend so schreiben:
main: cls
      print "Hello World",13,10
      ret

Wenn das Unterprogramm jedoch Definitionen verwendet, die nur für dies Unterprogramm gültig sein sollen, so ist zumeist sinnvoll, es mit PROC und ENDP vom übrigen Quelltext abzugrenzen. Solche Definitionen werden als „lokale Definitionen” bezeichnet.
Weshalb steht zumeist?. Das beim MASM32 SDK genutzte ML-Assemblierprogramm kennt anonyme Sprungmarken (Anonymous Labels). Eine solche Sprungmarke wird mit @@: definiert. Mit @F lässt sich die nächste anonyme Sprungmarke ansteuern, mit @B kommt man zur vorhergehenden anonymen Sprungmarke zurück.

Eine Verschachtelung von anonymen Sprungmarken ist nicht möglich. Beispiel:

       XOR EAX, EAX
       MOV ECX, 10
 @@:   CMP EAX, 5
       JE      @F
       INC     EAX
       LOOP    @B
       JMP     Weiter
       
 @@:   MOV EAX,20
Die beiden Direktiven PROTO und INVOKE erleichtern das Nutzen von definierten Aufrufschnittstellen für Dynamic Link Libraries (DLLs). Die DLL-Dateien residieren in verschiedenen Ordnern auf dem PC. Man bezeichnet dies Gesamtheit von Aufrufschnittstellen als von Application Programming Interface (API). Allerdings ist die Bezeichnung API mehrdeutig. Ich spreche von API, wenn ich die Aufrufschnittstellen einer bestimmten Funktion meine. Entsprechend bezeichnet bei mir APIs mehrere Aufrufschnittstellen.

Beim Aufruf einer API sind keine, ein oder mehrerer Parameter anzugeben. Welches es sind, steht für rund 1500 APIs in der Datei Win32.hlp (Win32 Programmers Manual). Eine Bezugsquelle ist auf der Webseite  i MASM32 SDK: Wo finde ich Informationen? angegeben.

Grundsätzlich lassen sich die APIs mit dem normalen Assemblerbefehl CALL wie Unterprogramme aufrufen. Es wird angeraten, statt dessen die Direktive INVOKE zu nutzen. INVOKE arbeitet mit der Direktive PROTO (wie Prototyp) zusammen. Das bei PROTO für diese API hinterlegte Muster ermöglicht bei Verwendung von INVOKE eine formale Prüfung der Syntax des programmierten API-Aufrufs. Beispiel:

        INVOKE FunctionName, par1, ADDR par2, par3, ADDR par4
        mov retval, eax ;Rückgabewert von FunctionName
würde traditionell programmiert werden als:
        
        push offset par4
        push par3
        push offset par2
        push par1
        call FunctionName
        mov retval, eax ;Rückgabewert von FunctionName
Allerdings würde bei der traditionellen Programmierung die Aufrufparameter nicht bereits zur Assemblierungszeit auf Typ und Anzahl überprüft werden.

Damit die Überprüfung erfolgen kann, sind mit PROTO für bekannte APIs die Muster angelegt. Beispiele dazu stehen in der Datei \masm32\include\kernel32.inc. Diese Datei wird in das Assemblerquellprogramm mit INCLUDE eingelesen und erweitert es somit.

Unter MASM32 SDK sehen die INVOKE-Aufrufe ungewohnt aus, z.B. so:

invoke MessageBox, NULL, addr MsgBoxText, addr MsgBoxCaption, MB_OK
Die Bedeutung der nicht im dem Quellprogramm ersichtlichen Symbole enthüllt zumeist die Datei \masm32\include\windows.inc:
        TRUE	equ 1
        FALSE	equ 0
        NULL	equ 0
        MB_OK	equ 0

In der Version 11 des MASM32 SDK enthält die Datei \masm32\include\windows.inc über 26000 Zeilen!

Die zwei Durchläufe des Assemblierprogramms
Bei einer vollständigen Assemblierung liest das Assemblierprogramm den Assemblerquellcode zweimal vollständig zeilenweise durch.

Beim ersten Durchgang

  • wird geprüft, ob die Instruktionen zulässig sind,
  • wird der Speicherplatz für die Befehle und Daten bestimmt und Adresszuordnungszähler (location counter) geführt,
  • werden Werte von Konstanten soweit wie möglich eingetragen,
  • wird eine Symboltabelle (cross-reference table) erstellt, in der alle definierten Bezugsnamen (lables) eingetragen werden. Doppelte Labels werden als Fehler gemeldet.

Sofern beim ersten Durchgang mindestens ein Fehler entdeckt wurde, wird der Umstand gemeldet und der Assembliervorgang abgebrochen.

Beim zweiten Durchgang

  • werden symbolische Operanden anhand der Symboltabelle durch Bezüge auf Speicheradressen ersetzt,
  • wird sichergestellt, dass alle Befehle einen formal korrekten Aufbau haben,
  • werden die Befehle durch ihren Maschinencode ersetzt,
  • werden alle noch verbliebenen symbolischen Konstanten durch ihren Wert ersetzt,
  • wird, sofern in diesem Durchgang Fehler festgestellt wurden, dies gemeldet
  • wird, sofern kein Fehler festgestellt wurde, der generierte Objektcode für den Linker in eine Objektdatei (Endung .obj) ausgegeben.
Die Objektdatei wird später durch das Link-Programm in ein ausführbares Programm gewandelt. Die Objektdatei kann offene (d.h. nicht aufgelöste) Adressbezüge enthalten, die erst durch das Einlinken weiterer Objektdateien geschlossen werden. Das Verfahren mit mehreren Objektdateien wird beim MASM32 SDK intensiv verwendet.

Letztes Upload: 30.03.2017 um 14:29:14