• ZUCC_编译语言原理与编译_实验03 编译器入门


    编译语言原理与编译实验报告

    课程名称编译语言原理与编译
    实验项目编译器入门

    实验目的

    • 了解语言的发展历史
    • 理解编译的主要阶段
    • 掌握基本的编译操作
    • 理解高级语言、语法树、 中间语言、机器语言等概念

    实验内容

    1、阅读课件、教材第1章,请说明下面的概念

    名称概念
    编译器将一种语言(通常为高级语言)翻译成另一种语言(通常为低级语言)的程序
    解释器是将目标代码解释为具体平台的机器码的程序
    汇编器是将汇编语言翻译成机器语言的程序
    编译程序的逻辑过程/步骤编译器的结构在逻辑上主要分为前端和后端,其中每一步骤将源程序的一种表达方式转化为另一表达方式
    前端编译器前端又可以分为词法分析、语法分析、语义分析和中间代码生成,词法分析主要是对源代码文件中的字符进行切割(分词),分成一个个符号并生成符号标记树。语法分析是对符号标记树中的标记进一步分析语法,并生成语法树,语义分析是对源代码上下文的整体检查,最后根据生成的正确语法树翻译成中间代码
    后端编译器后端主要是生成机器语言,并进行相关的代码优化,编译器生成的机器语言根据硬件平台的不同而不同
    是对源程序或者源程序的中间结果进行从头到尾的扫描依次,并且作出相应的处理,生成新的中间结果或者目标程序
    中间语言在翻译过程中,会出现一个或多个易于生成且能轻松翻译为目标程序的语言,例如语法树
    机器语言机器能直接识别的程序语言或指令代码,无需经过翻译,每一操作码在计算机内部都有相应的电路来完成它,或指不经翻译即可为机器直接理解和接受的程序语言或指令代码

    2、编译命令参数使用

    测试gcc编译器 -S -E -c 等参数使用(-E预编译 -S汇编代码 -c 目标代码)

    测试代码

    #include <stdio.h>
    
    int main()
    {
        int x;
        scanf("%d", &x);
        x=x+1;
        printf("Value of x:%d\n",x);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    image-20220316084254861

    预编译

    image-20220316084329580

    汇编代码

    image-20220316084623680

    目标代码

    image-20220316084723243

    https://godbolt.org/ 查看生成的汇编代码

    image-20220316082840088

    3、安装 WSL2

    由于使用MacOS且已有Win11及Ubuntu虚拟机,故暂不安装

    MacOS内gcc版本

    image-20220316085426476

    Ubuntu内gcc版本

    image-20220316084031118

    4、理解程序代码与抽象语法树的关系,理解如下的抽象语法树节点

    g1.3

    spl.ast

    语句解释
    复合语句由分隔符或括号将多个语句聚合在一起
    赋值语句这里指用运算的值改变某个变量的内存状态的语句
    输出语句这里指print函数
    表达式解释
    id指引用到的变量
    num指实际运算时的数据
    二元操作binop具体指±*/四个运算符
    语句表达式序列 EseqExp这里起到了并列两个语句的作用
    表达式列表 ExpList这里起到了并列两个表达式的作用

    5、查看具体语法树与 DotNet 中间语言IL 代码、JIT (即时编译)asm 代码的对应关系

    在线访问 https://sharplab.io/ 查看下面的C#、F#程序,理解如下知识点

    • 理解源代码与具体语法树节点的对应关系

      将源代码的字符流进行词法分析生成符号流,再进行语法分析生成语法树,然后是语义分析生成新的语法树,最后生成中间代码。而具体语法树是一种中间代码,其中的结点对应了源代码中的一个个词素。

    • 关键字,标识符,方法,参数,操作符,操作数

      方法,参数,操作符,操作数这些词都称为词素,被映射为词法单元,它包含一个标识符和符号表标号,被当成一个个关键字。

    参考题目4的图,画出 int x = 12 * 30;的抽象语法树

    image-20220323201605763

    中间语言IL

    查看中间语言含义,理解运算栈,局部变量的表示

    IL是.NET框架中中间语言(Intermediate Language)的缩写。使用.NET框架提供的编译器可以直接将源程序编译为.exe或.dll文件,但此时编译出来的程序代码并不是CPU能直接执行的机器代码,而是一种中间语言IL(Intermediate Language)的代码。

    例如有如下代码:

    private int add(int a, int b)
    {
      int c;
      c = a + b;
      return c;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    转化为IL语言有:

    .method 
    private hidebysig instance int32 'add'(int32 a,int32 b) cil managed
    {
      // 代码大小       11 (0xb)
      .maxstack  2
      .locals init ([0] int32 c,[1] int32 CS$1$0000) //声明局部变量 c 
      IL_0000:  nop
      IL_0001:  ldarg.1     //将索引为 1 的参数加载到计算堆栈上。
      IL_0002:  ldarg.2
      IL_0003:  add         //将两个值相加并将结果推送到计算堆栈上。
      IL_0004:  stloc.0    //从计算堆栈的顶部弹出当前值并将其存储到索引 0 处的局部变量列表中。
      IL_0005:  ldloc.0    //将索引 0 处的局部变量加载到计算堆栈上。
      IL_0006:  stloc.1    //从计算堆栈的顶部弹出当前值并将其存储到索引 1 处的局部变量列表中。
      IL_0007:  br.s       IL_0009   //无条件地将控制转移到目标指令 跳到IL_0009
      IL_0009:  ldloc.1    //将索引 1 处的局部变量加载到计算堆栈上。
      IL_000a:  ret        //从当前方法返回,并将返回值(如果存在)从调用方的计算堆栈推送到被调用方的计算堆栈上。
    } // end of method Form1::'add'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    关键字:

    1. .locals:在IL 中,方法参数按照它们在参数列表中的位置依次被引用。如果方法是静态或共享方法,那么参数0则是参数列表中的第1个参数。而对实例方法来说,参数0则是指 向该方法所在类的实例的指针(Me或者this)。方法中的所有局部变量都在.locals标记的段落中以同样的方式声明。
    2. ldarg:装载成员的一个参数,而LDARGA指令则装载参数的地址。变量由它们在.locals节中的位置标识。这些指令装载位置4及以后位置使用不同的语法,但是索引号仍然出现在指令中。
    3. stloc:负责把堆栈最顶端的条目存入一个局部变量。存储指令指定变量的句法规则通常和它们对应的装载指令类似。
    4. ldloc:把一个局部变量装入堆栈,另外还有一条LDLOCA指令把一个局部变量的地址(而非变量的内容)装入堆栈。变量由它们在.locals节的位置标识。这些指令装载位置4及以后位置使用不同的语法,但是索引号会出现在指令中。
    5. br:IL分支指令(以BR开头)根据堆栈最顶端的条目中的内容跳到其他指令。Br.S无条件地将控制转移到目标指令(短格式)。
    6. ret:从当前方法返回,并将返回值(如果存在)从调用方的计算堆栈推送到被调用方的计算堆栈上。

    汇编码 JIT Asm

    理解汇编码与中间语言的关系

    当目标语言为机器语言时,前端生成的中间代码经过优化成为后端的汇编生成打下基础。

    理解代码优化的概念

    所谓代码优化是指对程序代码进行等价(指不改变程序的运行结果)变换。程序代码可以是中间代码(如四元式代码),也可以是目标代码。等价的含义是使得变换后的代码运行结果与变换前代码运行结果相同。优化的含义是最终生成的目标代码短(运行时间更短、占用空间更小),时空效率优化。原则上,优化可以在编译的各个阶段进行,但最主要的一类是对中间代码进行优化,这类优化不依赖于具体的计算机。

    //简单的C#程序
    using System;
    //Class declaration
    class Test {
        //Method declaration
        static void Main() {
            //Statement 1
            int x = 12 * 30;
            //Statement 2
            Console.WriteLine (x);
            //End of method    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    .assembly _
    {
        .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = (
            01 00 08 00 00 00 00 00
        )
        .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = (
            01 00 01 00 54 02 16 57 72 61 70 4e 6f 6e 45 78
            63 65 70 74 69 6f 6e 54 68 72 6f 77 73 01
        )
        .custom instance void [System.Private.CoreLib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [System.Private.CoreLib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = (
            01 00 07 01 00 00 00 00
        )
        .permissionset reqmin = (
            2e 01 80 92 53 79 73 74 65 6d 2e 53 65 63 75 72
            69 74 79 2e 50 65 72 6d 69 73 73 69 6f 6e 73 2e
            53 65 63 75 72 69 74 79 50 65 72 6d 69 73 73 69
            6f 6e 41 74 74 72 69 62 75 74 65 2c 20 53 79 73
            74 65 6d 2e 50 72 69 76 61 74 65 2e 43 6f 72 65
            4c 69 62 2c 20 56 65 72 73 69 6f 6e 3d 36 2e 30
            2e 30 2e 30 2c 20 43 75 6c 74 75 72 65 3d 6e 65
            75 74 72 61 6c 2c 20 50 75 62 6c 69 63 4b 65 79
            54 6f 6b 65 6e 3d 37 63 65 63 38 35 64 37 62 65
            61 37 37 39 38 65 15 01 54 02 10 53 6b 69 70 56
            65 72 69 66 69 63 61 74 69 6f 6e 01
        )
        .hash algorithm 0x00008004 // SHA1
        .ver 0:0:0:0
    }
    
    .class private auto ansi '<Module>'
    {
    } // end of class <Module>
    
    .class private auto ansi beforefieldinit Test
        extends [System.Private.CoreLib]System.Object
    {
        // Methods
        .method private hidebysig static 
            void Main () cil managed 
        {
            // Method begins at RVA 0x2050
            // Code size 15 (0xf)
            .maxstack 1
            .locals init (
                [0] int32 x
            )
    
            IL_0000: nop
            IL_0001: ldc.i4 360
            IL_0006: stloc.0
            IL_0007: ldloc.0
            IL_0008: call void [System.Console]System.Console::WriteLine(int32)
            IL_000d: nop
            IL_000e: ret
        } // end of method Test::Main
    
        .method public hidebysig specialname rtspecialname 
            instance void .ctor () cil managed 
        {
            // Method begins at RVA 0x206b
            // Code size 8 (0x8)
            .maxstack 8
    
            IL_0000: ldarg.0
            IL_0001: call instance void [System.Private.CoreLib]System.Object::.ctor()
            IL_0006: nop
            IL_0007: ret
        } // end of method Test::.ctor
    
    } // end of class Test
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    ; Core CLR 6.0.121.56705 on x86
    
    Test..ctor()
        L0000: push ebp
        L0001: mov ebp, esp
        L0003: push eax
        L0004: mov [ebp-4], ecx
        L0007: cmp dword ptr [0xaccc190], 0
        L000e: je short L0015
        L0010: call 0x65694bc0
        L0015: mov ecx, [ebp-4]
        L0018: call System.Object..ctor()
        L001d: nop
        L001e: nop
        L001f: mov esp, ebp
        L0021: pop ebp
        L0022: ret
    
    Test.Main()
        L0000: push ebp
        L0001: mov ebp, esp
        L0003: push eax
        L0004: xor eax, eax
        L0006: mov [ebp-4], eax
        L0009: cmp dword ptr [0xaccc190], 0
        L0010: je short L0017
        L0012: call 0x65694bc0
        L0017: nop
        L0018: mov dword ptr [ebp-4], 0x168
        L001f: mov ecx, [ebp-4]
        L0022: call System.Console.WriteLine(Int32)
        L0027: nop
        L0028: nop
        L0029: mov esp, ebp
        L002b: pop ebp
        L002c: ret
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    //简单的 F# 程序,对比C#的语法树结构
    let x = 12 * 30
    printf "%d" x
    
    • 1
    • 2
    • 3
    .assembly _
    {
        .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, int32, int32) = (
            01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00
        )
        .hash algorithm 0x00008004 // SHA1
        .ver 0:0:0:0
    }
    
    .class private auto ansi '<Module>'
        extends [System.Runtime]System.Object
    {
    } // end of class <Module>
    
    .class public auto ansi abstract sealed _
        extends [System.Runtime]System.Object
    {
        .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = (
            01 00 07 00 00 00 00 00
        )
        // Methods
        .method public specialname static 
            valuetype [System.Private.CoreLib]System.Int32 get_x () cil managed 
        {
            .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
                01 00 00 00
            )
            .custom instance void [System.Private.CoreLib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = (
                01 00 00 00
            )
            // Method begins at RVA 0x2050
            // Code size 6 (0x6)
            .maxstack 8
    
            IL_0000: ldc.i4 360
            IL_0005: ret
        } // end of method _::get_x
    
        .method assembly specialname static 
            class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<valuetype [System.Private.CoreLib]System.Int32, class [FSharp.Core]Microsoft.FSharp.Core.Unit>, class [System.Private.CoreLib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit> get_format@1 () cil managed 
        {
            // Method begins at RVA 0x2058
            // Code size 6 (0x6)
            .maxstack 8
    
            IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<valuetype [System.Private.CoreLib]System.Int32, class [FSharp.Core]Microsoft.FSharp.Core.Unit>, class [System.Private.CoreLib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit> '<StartupCode$_>.$_'::format@1
            IL_0005: ret
        } // end of method _::get_format@1
    
        // Properties
        .property valuetype [System.Private.CoreLib]System.Int32 x()
        {
            .get valuetype [System.Private.CoreLib]System.Int32 _::get_x()
        }
        .property class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<valuetype [System.Private.CoreLib]System.Int32, class [FSharp.Core]Microsoft.FSharp.Core.Unit>, class [System.Private.CoreLib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit> format@1()
        {
            .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = (
                01 00 09 00 00 00 00 00
            )
            .get class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<valuetype [System.Private.CoreLib]System.Int32, class [FSharp.Core]Microsoft.FSharp.Core.Unit>, class [System.Private.CoreLib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit> _::get_format@1()
        }
    
    } // end of class _
    
    .class private auto ansi abstract sealed '<StartupCode$_>.$_'
        extends [System.Runtime]System.Object
    {
        // Fields
        .field assembly static initonly class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<valuetype [System.Private.CoreLib]System.Int32, class [FSharp.Core]Microsoft.FSharp.Core.Unit>, class [System.Private.CoreLib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit> format@1
        .custom instance void [System.Private.CoreLib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [System.Private.CoreLib]System.Diagnostics.DebuggerBrowsableState) = (
            01 00 00 00 00 00 00 00
        )
        .field assembly static int32 init@
        .custom instance void [System.Private.CoreLib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [System.Private.CoreLib]System.Diagnostics.DebuggerBrowsableState) = (
            01 00 00 00 00 00 00 00
        )
        .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
            01 00 00 00
        )
        .custom instance void [System.Private.CoreLib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = (
            01 00 00 00
        )
    
        // Methods
        .method private specialname rtspecialname static 
            void .cctor () cil managed 
        {
            // Method begins at RVA 0x2060
            // Code size 42 (0x2a)
            .maxstack 8
    
            IL_0000: ldstr "%d"
            IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<valuetype [System.Private.CoreLib]System.Int32, class [FSharp.Core]Microsoft.FSharp.Core.Unit>, class [System.Private.CoreLib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit, valuetype [System.Private.CoreLib]System.Int32>::.ctor(class [System.Private.CoreLib]System.String)
            IL_000a: stsfld class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<valuetype [System.Private.CoreLib]System.Int32, class [FSharp.Core]Microsoft.FSharp.Core.Unit>, class [System.Private.CoreLib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit> '<StartupCode$_>.$_'::format@1
            IL_000f: call class [netstandard]System.IO.TextWriter [netstandard]System.Console::get_Out()
            IL_0014: call class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<valuetype [System.Private.CoreLib]System.Int32, class [FSharp.Core]Microsoft.FSharp.Core.Unit>, class [System.Private.CoreLib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit> _::get_format@1()
            IL_0019: call !!0 [FSharp.Core]Microsoft.FSharp.Core.PrintfModule::PrintFormatToTextWriter<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<valuetype [System.Private.CoreLib]System.Int32, class [FSharp.Core]Microsoft.FSharp.Core.Unit>>(class [System.Private.CoreLib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<!!0, class [System.Private.CoreLib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit>)
            IL_001e: ldc.i4 360
            IL_0023: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<valuetype [System.Private.CoreLib]System.Int32, class [FSharp.Core]Microsoft.FSharp.Core.Unit>::Invoke(!0)
            IL_0028: pop
            IL_0029: ret
        } // end of method $_::.cctor
    
    } // end of class <StartupCode$_>.$_
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104

    无JIT Asm

    //简单的 F# 程序,带递归    
    let rec fact n = 
    if n = 0 then 1 else n * fact (n - 1)
    
    • 1
    • 2
    • 3
    .assembly _
    {
        .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, int32, int32) = (
            01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00
        )
        .hash algorithm 0x00008004 // SHA1
        .ver 0:0:0:0
    }
    
    .class private auto ansi '<Module>'
        extends [System.Runtime]System.Object
    {
    } // end of class <Module>
    
    .class public auto ansi abstract sealed _
        extends [System.Runtime]System.Object
    {
        .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = (
            01 00 07 00 00 00 00 00
        )
        // Methods
        .method public static 
            valuetype [System.Private.CoreLib]System.Int32 fact (
                valuetype [System.Private.CoreLib]System.Int32 n
            ) cil managed 
        {
            // Method begins at RVA 0x2050
            // Code size 16 (0x10)
            .maxstack 8
    
            IL_0000: ldarg.0
            IL_0001: brtrue.s IL_0005
    
            IL_0003: ldc.i4.1
            IL_0004: ret
    
            IL_0005: ldarg.0
            IL_0006: ldarg.0
            IL_0007: ldc.i4.1
            IL_0008: sub
            IL_0009: call valuetype [System.Private.CoreLib]System.Int32 _::fact(valuetype [System.Private.CoreLib]System.Int32)
            IL_000e: mul
            IL_000f: ret
        } // end of method _::fact
    
    } // end of class _
    
    .class private auto ansi abstract sealed '<StartupCode$_>.$_'
        extends [System.Runtime]System.Object
    {
    } // end of class <StartupCode$_>.$_
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    ; Core CLR 6.0.121.56705 on x86
    
    _.fact(System.Int32)
        L0000: push esi
        L0001: mov esi, ecx
        L0003: test esi, esi
        L0005: jne short L000e
        L0007: mov eax, 1
        L000c: pop esi
        L000d: ret
        L000e: lea ecx, [esi-1]
        L0011: call dword ptr [0xad8c68c]
        L0017: imul eax, esi
        L001a: pop esi
        L001b: ret
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    //较复杂的 C# 程序
    using System;
    public class Fibonacci {
        public static long Fib(int m) {
            if (m == 0) return 1;
            else if (m == 1) return 1;
            else return Fib(m - 1) + Fib(m - 2);
        }
        
        public static void
            Main(string[] args) {
            int m = Convert.ToInt32(args[0]);
            System.Console.WriteLine(Fib(m) + "\n");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    .assembly _
    {
        .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = (
            01 00 08 00 00 00 00 00
        )
        .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = (
            01 00 01 00 54 02 16 57 72 61 70 4e 6f 6e 45 78
            63 65 70 74 69 6f 6e 54 68 72 6f 77 73 01
        )
        .custom instance void [System.Private.CoreLib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [System.Private.CoreLib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = (
            01 00 07 01 00 00 00 00
        )
        .permissionset reqmin = (
            2e 01 80 92 53 79 73 74 65 6d 2e 53 65 63 75 72
            69 74 79 2e 50 65 72 6d 69 73 73 69 6f 6e 73 2e
            53 65 63 75 72 69 74 79 50 65 72 6d 69 73 73 69
            6f 6e 41 74 74 72 69 62 75 74 65 2c 20 53 79 73
            74 65 6d 2e 50 72 69 76 61 74 65 2e 43 6f 72 65
            4c 69 62 2c 20 56 65 72 73 69 6f 6e 3d 36 2e 30
            2e 30 2e 30 2c 20 43 75 6c 74 75 72 65 3d 6e 65
            75 74 72 61 6c 2c 20 50 75 62 6c 69 63 4b 65 79
            54 6f 6b 65 6e 3d 37 63 65 63 38 35 64 37 62 65
            61 37 37 39 38 65 15 01 54 02 10 53 6b 69 70 56
            65 72 69 66 69 63 61 74 69 6f 6e 01
        )
        .hash algorithm 0x00008004 // SHA1
        .ver 0:0:0:0
    }
    
    .class private auto ansi '<Module>'
    {
    } // end of class <Module>
    
    .class public auto ansi beforefieldinit Fibonacci
        extends [System.Private.CoreLib]System.Object
    {
        // Methods
        .method public hidebysig static 
            int64 Fib (
                int32 m
            ) cil managed 
        {
            // Method begins at RVA 0x2050
            // Code size 49 (0x31)
            .maxstack 3
            .locals init (
                [0] bool,
                [1] int64,
                [2] bool
            )
    
            IL_0000: nop
            IL_0001: ldarg.0
            IL_0002: ldc.i4.0
            IL_0003: ceq
            IL_0005: stloc.0
            // sequence point: hidden
            IL_0006: ldloc.0
            IL_0007: brfalse.s IL_000e
    
            IL_0009: ldc.i4.1
            IL_000a: conv.i8
            IL_000b: stloc.1
            IL_000c: br.s IL_002f
    
            IL_000e: ldarg.0
            IL_000f: ldc.i4.1
            IL_0010: ceq
            IL_0012: stloc.2
            // sequence point: hidden
            IL_0013: ldloc.2
            IL_0014: brfalse.s IL_001b
    
            IL_0016: ldc.i4.1
            IL_0017: conv.i8
            IL_0018: stloc.1
            IL_0019: br.s IL_002f
    
            IL_001b: ldarg.0
            IL_001c: ldc.i4.1
            IL_001d: sub
            IL_001e: call int64 Fibonacci::Fib(int32)
            IL_0023: ldarg.0
            IL_0024: ldc.i4.2
            IL_0025: sub
            IL_0026: call int64 Fibonacci::Fib(int32)
            IL_002b: add
            IL_002c: stloc.1
            IL_002d: br.s IL_002f
    
            IL_002f: ldloc.1
            IL_0030: ret
        } // end of method Fibonacci::Fib
    
        .method public hidebysig static 
            void Main (
                string[] args
            ) cil managed 
        {
            // Method begins at RVA 0x2090
            // Code size 41 (0x29)
            .maxstack 2
            .locals init (
                [0] int32 m,
                [1] int64
            )
    
            IL_0000: nop
            IL_0001: ldarg.0
            IL_0002: ldc.i4.0
            IL_0003: ldelem.ref
            IL_0004: call int32 [System.Private.CoreLib]System.Convert::ToInt32(string)
            IL_0009: stloc.0
            IL_000a: ldloc.0
            IL_000b: call int64 Fibonacci::Fib(int32)
            IL_0010: stloc.1
            IL_0011: ldloca.s 1
            IL_0013: call instance string [System.Private.CoreLib]System.Int64::ToString()
            IL_0018: ldstr "\n"
            IL_001d: call string [System.Private.CoreLib]System.String::Concat(string, string)
            IL_0022: call void [System.Console]System.Console::WriteLine(string)
            IL_0027: nop
            IL_0028: ret
        } // end of method Fibonacci::Main
    
        .method public hidebysig specialname rtspecialname 
            instance void .ctor () cil managed 
        {
            // Method begins at RVA 0x20c5
            // Code size 8 (0x8)
            .maxstack 8
    
            IL_0000: ldarg.0
            IL_0001: call instance void [System.Private.CoreLib]System.Object::.ctor()
            IL_0006: nop
            IL_0007: ret
        } // end of method Fibonacci::.ctor
    
    } // end of class Fibonacci
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    ; Core CLR 6.0.121.56705 on x86
    
    Fibonacci..ctor()
        L0000: push ebp
        L0001: mov ebp, esp
        L0003: push eax
        L0004: mov [ebp-4], ecx
        L0007: cmp dword ptr [0xe12c190], 0
        L000e: je short L0015
        L0010: call 0x65694bc0
        L0015: mov ecx, [ebp-4]
        L0018: call System.Object..ctor()
        L001d: nop
        L001e: nop
        L001f: mov esp, ebp
        L0021: pop ebp
        L0022: ret
    
    Fibonacci.Fib(Int32)
        L0000: push ebp
        L0001: mov ebp, esp
        L0003: sub esp, 0x2c
        L0006: xor eax, eax
        L0008: mov [ebp-8], eax
        L000b: mov [ebp-0x10], eax
        L000e: mov [ebp-0xc], eax
        L0011: mov [ebp-0x14], eax
        L0014: mov [ebp-4], ecx
        L0017: cmp dword ptr [0xe12c190], 0
        L001e: je short L0025
        L0020: call 0x65694bc0
        L0025: nop
        L0026: cmp dword ptr [ebp-4], 0
        L002a: sete cl
        L002d: movzx ecx, cl
        L0030: mov [ebp-8], ecx
        L0033: cmp dword ptr [ebp-8], 0
        L0037: je short L0052
        L0039: mov dword ptr [ebp-0x28], 1
        L0040: mov ecx, [ebp-0x28]
        L0043: mov eax, [ebp-0x28]
        L0046: sar eax, 0x1f
        L0049: mov [ebp-0x10], ecx
        L004c: mov [ebp-0xc], eax
        L004f: nop
        L0050: jmp short L00b5
        L0052: cmp dword ptr [ebp-4], 1
        L0056: sete cl
        L0059: movzx ecx, cl
        L005c: mov [ebp-0x14], ecx
        L005f: cmp dword ptr [ebp-0x14], 0
        L0063: je short L007e
        L0065: mov dword ptr [ebp-0x2c], 1
        L006c: mov ecx, [ebp-0x2c]
        L006f: mov eax, [ebp-0x2c]
        L0072: sar eax, 0x1f
        L0075: mov [ebp-0x10], ecx
        L0078: mov [ebp-0xc], eax
        L007b: nop
        L007c: jmp short L00b5
        L007e: mov ecx, [ebp-4]
        L0081: dec ecx
        L0082: call dword ptr [0xe12c6c4]
        L0088: mov [ebp-0x1c], eax
        L008b: mov [ebp-0x18], edx
        L008e: mov ecx, [ebp-4]
        L0091: add ecx, 0xfffffffe
        L0094: call dword ptr [0xe12c6c4]
        L009a: mov [ebp-0x24], eax
        L009d: mov [ebp-0x20], edx
        L00a0: mov eax, [ebp-0x1c]
        L00a3: mov edx, [ebp-0x18]
        L00a6: add eax, [ebp-0x24]
        L00a9: adc edx, [ebp-0x20]
        L00ac: mov [ebp-0x10], eax
        L00af: mov [ebp-0xc], edx
        L00b2: nop
        L00b3: jmp short L00b5
        L00b5: mov eax, [ebp-0x10]
        L00b8: mov edx, [ebp-0xc]
        L00bb: mov esp, ebp
        L00bd: pop ebp
        L00be: ret
    
    Fibonacci.Main(System.String[])
        L0000: push ebp
        L0001: mov ebp, esp
        L0003: sub esp, 0x24
        L0006: vxorps xmm4, xmm4, xmm4
        L000a: vmovdqu [ebp-0x24], xmm4
        L000f: vmovdqu [ebp-0x14], xmm4
        L0014: mov [ebp-4], ecx
        L0017: cmp dword ptr [0xe12c190], 0
        L001e: je short L0025
        L0020: call 0x65694bc0
        L0025: nop
        L0026: mov ecx, [ebp-4]
        L0029: xor eax, eax
        L002b: cmp eax, [ecx+4]
        L002e: jb short L0035
        L0030: call 0x65695fc0
        L0035: lea ecx, [ecx+eax*4+8]
        L0039: mov ecx, [ecx]
        L003b: call System.Convert.ToInt32(System.String)
        L0040: mov [ebp-0x14], eax
        L0043: mov ecx, [ebp-0x14]
        L0046: mov [ebp-8], ecx
        L0049: mov ecx, [ebp-8]
        L004c: call Fibonacci.Fib(Int32)
        L0051: mov [ebp-0x1c], eax
        L0054: mov [ebp-0x18], edx
        L0057: mov ecx, [ebp-0x1c]
        L005a: mov eax, [ebp-0x18]
        L005d: mov [ebp-0x10], ecx
        L0060: mov [ebp-0xc], eax
        L0063: lea ecx, [ebp-0x10]
        L0066: call System.Int64.ToString()
        L006b: mov [ebp-0x20], eax
        L006e: mov edx, [0x89c5238]
        L0074: mov ecx, [ebp-0x20]
        L0077: call System.String.Concat(System.String, System.String)
        L007c: mov [ebp-0x24], eax
        L007f: mov ecx, [ebp-0x24]
        L0082: call System.Console.WriteLine(System.String)
        L0087: nop
        L0088: nop
        L0089: mov esp, ebp
        L008b: pop ebp
        L008c: ret
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129

    6、下载LinqPad查看C#代码的具体语法树与抽象语法树 (自选)请说明具体语法树,与抽象语法树的区别

    1. 同一语言的每一个语法都会给出不同的具体语法树,但抽象语法树的结果应该是相同的
    2. 抽象语法树不关注语法生成它们的方式,专注于编程构造也就是运算符
    3. 抽象语法树使用运算符/操作作为根节点和内部节点,并使用操作数作为子节点。与具体语法树不同,抽象语法树不使用内部节点来表示语法规则。抽象语法树并不代表真实语法中的每个细节(这就是为什么它们被称为抽象) - 例如,省略了节点和括号等细节。与同一语言构造的解析树相比,抽象语法树是密集的。

    image-20220323205129503

    7、编译与反编译Java代码 (自选)

    //自行安装 jdk 。。可以使用 javac, javap 代码如下:
    //Fibonacci.java
    public class Fibonacci {
        public static long fib(int m) {
            if (m == 0) {
                return 1;
            } else if (m == 1) {
                return 1;
            } else {
                return fib(m - 1) + fib(m - 2);
            }
        }
        public static void main(String[] args) {
            int m =Integer.parseInt(args[0]);
            System.out.println(fib(m) + "\n");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    注意:代码有修改

    image-20220316154226507

    image-20220316154539179

  • 相关阅读:
    SPark学习笔记:12 Spark Streaming 的简单应用WordCount
    唤醒手腕 Matlab 游戏编程常用技术知识点详细教程(更新中)
    谈谈 ArrayList
    gateway
    C语言网络编程
    Python线程详解
    APISpace 迎国庆
    python 中的迭代器和生成器简单介绍
    Matlab学习——变量与档案存取
    git进阶
  • 原文地址:https://blog.csdn.net/OwemShu/article/details/125377618