2012-03-23 12 views
11

Ich lerne Assembler in meiner Freizeit. Kann jemand erklären, warum .maxstack scheint, in diesem Programm optional zu sein. Ich habe versucht, die Antwort online und in meinem Buch ohne so viel Glück zu finden, dh das Programm kompilieren und ausführen mit .maxstack kommentiert out:Warum ist die .MaxStack-Richtlinie in MSIL-Code optional?

//Add.il 
//Add Two Numbers 

.assembly extern mscorlib {} 

.assembly Add 
{ 
    .ver 1:0:1:0 
} 
.module add.exe 

.method static void main() cil managed 
{ 
    //.maxstack 2 
    .entrypoint 

    ldstr "The sum of 50 and 30 is = " 
    call void [mscorlib]System.Console::Write (string) 

    ldc.i4.s 50 
    ldc.i4 30  
    add 
    call void [mscorlib]System.Console::Write (int32) 
    ret 
} 

ich das Programm in der Befehlszeile am Kompilieren des ILASM Werkzeug und dann wird das erzeugte ausführbare ausgeführt.

Antwort

12

Ich denke, Ihre Verwirrung rührt von einem Missverständnis her, was .maxstack tatsächlich tut. Es ist ein einfacher Fehler zu machen, weil es scheint, als würde es einen Fehler bei der Ausführung verursachen. Überraschenderweise hat diese bestimmte Richtlinie tatsächlich nichts mit der mit Stack-Größe zur Laufzeit, stattdessen wird es speziell bei der Code-Verifikation verwendet.

Von Partition III - Abschnitt 1.7.4

Hinweis: maxstack zur Analyse des Programms bezieht, nicht auf die Größe des Stapels zur Laufzeit. Es gibt nicht die maximale Größe eines Stack-Frames in Bytes an, sondern die Anzahl der Elemente, die von einem Analyse-Tool verfolgt werden müssen.

Der Code wird unverifizierbar. Im selben Abschnitt wird darauf hingewiesen, dass jede konforme Implementierung keine Unterstützung einer Methode mit einem ungültigen maximalen Stack-Wert benötigt. Allerdings heißt es nicht, dass es nicht sein muss, und ganz klar, die Laufzeit führt den Code aus. Wenn es also keinen Effekt zu haben scheint, warum sollte man es überhaupt haben?

Ob Sie es glauben oder nicht, standardmäßig läuft das .NET-Framework unverifiable Code. Es war wirklich schwierig für mich, herauszufinden, wie Verifikation in .NET 4.0 zu ermöglichen, aber wenn Sie auf CAS wenden Sie Ihr Programm (mit .maxstack 1) wird mit

Unbehandelte Ausnahme aufhören läuft: System.InvalidProgramException: Common Language Runtime hat ein ungültiges Programm erkannt. an Haupt()

des Halt im Verstand, nicht überprüfbare der Code kann in jeder Umgebung nicht ausgeführt werden, die nicht volles Vertrauen hat (in der Regel Baugruppen aus dem Internet). Wenn das für Sie nicht wichtig ist, können Sie einen ungültigen Wert angeben, der keinen Unterschied macht. Wenn der Code selbst noch korrekt ist, wird es gut laufen; natürlich, wenn es tatsächlich ein Problem mit dem IL-Stack gibt, wird es eine InvalidProgramException werfen.

0

Wenn ich mich richtig erinnere, ist die Standardstapelgröße 8, wenn die Anweisung weggelassen wird.

+1

das habe ich zuerst gedacht, aber das Programm läuft immer noch wenn ich den .maxstack im obigen Programm auf 1 setze. Es sollte 2 oder höher sein für das Programm was ich sehen kann. – w0051977

+0

Nur raten hier, aber vielleicht ILASM ist schlau genug zu erkennen, dass 1 nicht genug wäre und überschreibt die Einstellung. –

+2

@ 500-InternalServerError, ist es nicht. Laut ILDASM enthält der emitierte Code tatsächlich ".maxstack 1". Und gemäß der Spezifikation sollte ein solcher Code ungültig und nicht verifizierbar sein. Und PEVerify schlägt die Überprüfung der Assembly tatsächlich fehl. Aber es läuft trotzdem gut. – svick