课程名称 | 编译语言原理与编译 |
---|---|
实验项目 | 编译器入门 |
名称 | 概念 |
---|---|
编译器 | 将一种语言(通常为高级语言)翻译成另一种语言(通常为低级语言)的程序 |
解释器 | 是将目标代码解释为具体平台的机器码的程序 |
汇编器 | 是将汇编语言翻译成机器语言的程序 |
编译程序的逻辑过程/步骤 | 编译器的结构在逻辑上主要分为前端和后端,其中每一步骤将源程序的一种表达方式转化为另一表达方式 |
前端 | 编译器前端又可以分为词法分析、语法分析、语义分析和中间代码生成,词法分析主要是对源代码文件中的字符进行切割(分词),分成一个个符号并生成符号标记树。语法分析是对符号标记树中的标记进一步分析语法,并生成语法树,语义分析是对源代码上下文的整体检查,最后根据生成的正确语法树翻译成中间代码 |
后端 | 编译器后端主要是生成机器语言,并进行相关的代码优化,编译器生成的机器语言根据硬件平台的不同而不同 |
遍 | 是对源程序或者源程序的中间结果进行从头到尾的扫描依次,并且作出相应的处理,生成新的中间结果或者目标程序 |
中间语言 | 在翻译过程中,会出现一个或多个易于生成且能轻松翻译为目标程序的语言,例如语法树 |
机器语言 | 机器能直接识别的程序语言或指令代码,无需经过翻译,每一操作码在计算机内部都有相应的电路来完成它,或指不经翻译即可为机器直接理解和接受的程序语言或指令代码 |
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);
}
预编译
汇编代码
目标代码
由于使用MacOS且已有Win11及Ubuntu虚拟机,故暂不安装
MacOS内gcc版本
Ubuntu内gcc版本
语句 | 解释 |
---|---|
复合语句 | 由分隔符或括号将多个语句聚合在一起 |
赋值语句 | 这里指用运算的值改变某个变量的内存状态的语句 |
输出语句 | 这里指print函数 |
表达式 | 解释 |
---|---|
id | 指引用到的变量 |
num | 指实际运算时的数据 |
二元操作binop | 具体指±*/四个运算符 |
语句表达式序列 EseqExp | 这里起到了并列两个语句的作用 |
表达式列表 ExpList | 这里起到了并列两个表达式的作用 |
理解源代码与具体语法树节点的对应关系
将源代码的字符流进行词法分析生成符号流,再进行语法分析生成语法树,然后是语义分析生成新的语法树,最后生成中间代码。而具体语法树是一种中间代码,其中的结点对应了源代码中的一个个词素。
关键字,标识符,方法,参数,操作符,操作数
方法,参数,操作符,操作数这些词都称为词素,被映射为词法单元,它包含一个标识符和符号表标号,被当成一个个关键字。
int x = 12 * 30;
的抽象语法树查看中间语言含义,理解运算栈,局部变量的表示
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;
}
转化为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'
关键字:
理解汇编码与中间语言的关系
当目标语言为机器语言时,前端生成的中间代码经过优化成为后端的汇编生成打下基础。
理解代码优化的概念
所谓代码优化是指对程序代码进行等价(指不改变程序的运行结果)变换。程序代码可以是中间代码(如四元式代码),也可以是目标代码。等价的含义是使得变换后的代码运行结果与变换前代码运行结果相同。优化的含义是最终生成的目标代码短(运行时间更短、占用空间更小),时空效率优化。原则上,优化可以在编译的各个阶段进行,但最主要的一类是对中间代码进行优化,这类优化不依赖于具体的计算机。
//简单的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
}
}
.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
; 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
//简单的 F# 程序,对比C#的语法树结构
let x = 12 * 30
printf "%d" x
.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$_>.$_
无JIT Asm
//简单的 F# 程序,带递归
let rec fact n =
if n = 0 then 1 else n * fact (n - 1)
.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$_>.$_
; 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
//较复杂的 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");
}
}
.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
; 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
//自行安装 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");
}
}
注意:代码有修改