CIL 如何用于发出网络/http 请求?

How is CIL used to make network / http requests?

我可以在这里看到 CIL 指令列表:

https://en.wikipedia.org/wiki/List_of_CIL_instructions

我的理解是CIL在CLR中是运行。但是,我看不出如何使用这些指令中的任何一个来发出 http 请求(这在 CLR 中显然是可能的)。

None 的代码似乎是关于获取外部信息的。

我错过了什么?

它也没有创建文件的说明。您观察到使用普通 CIL 时,有些任务根本无法完成,这是有道理的。打开套接字、写入磁盘、在屏幕上绘图等任务既不能由单个 CIL 指令完成,也不能完全分解为这些指令。

x86 汇编代码没有说明使用 PC 扬声器播放声音,但显然可以使用它来完成(不是完整的示例):

mov al, 0x36
out 0x43, al
mov ax, 11931
out 0x40, al
mov al, ah
out 0x40, al

此处,out 可用于将值写入 CPU 特定端口。这是与 "outside world" 交流的一种方式。在这种情况下,CPU 会尽可能地运行和解释代码,它只理解端口号的含义。它可能与串行端口通信,或者只是在某处更改一些电压,但是此时,我们遇到了硬件,因此这里不再有"instructions",只有电。

CIL 没有 out 操作码,因为那将是非常不安全且无法验证的。相反(这可能是您所要求的),它具有方法的代码实现属性以指定在何处查找特定方法的实现。

ImplAttr ::= … | cil | native | runtime

These attributes are mutually exclusive; they specify the type of code the method contains.

cil specifies that the method body consists of cil code. Unless the method is declared abstract, the body of the method shall be provided if cil is used.

native specifies that a method was implemented using native code, tied to a specific processor for which it was generated. native methods shall not have a body but instead refer to a native method that declares the body. Typically, the PInvoke functionality of the CLI is used to refer to a native method.

runtime specifies that the implementation of the method is automatically provided by the runtime and is primarily used for the methods of delegates. (ECMA-335)

标有cil的方法应具有由CIL操作码组成的主体,native应指示主体位于某处的本机指令中,runtime离开执行任务运行时的方法。 call 操作码用于像往常一样调用这些方法。

这种方法的一个例子:

.method assembly hidebysig static pinvokeimpl("kernel32.dll" autochar lasterr winapi bestfit:off) 
    bool  DeleteFile(string path) cil managed preservesig
{
}

出于某种原因,ildasm 显示 cil managed,根据 ECMA-335,这与 pinvokeimpl 直接冲突。它应该是 native unmanaged,我不确定为什么 ildasm 会显示这个。

调用外部方法的机制有P/Invoke、QCall、FCall。可以找到关于它们的有用信息 here。这是为 CIL 代码定义的与系统或运行时交互的唯一合法方式。

What am I missing?

你的逻辑链是这样的:

  • 所有类型的所有 CLR 方法都使用一系列 CIL 指令实现
  • CIL 指令只能执行某些任务
  • 有些任务需要 CIL 中没有的指令组合。
  • 因此有些任务在 CLR 方法中是不可能的。

然后您注意到结论是错误的,并且正确地注意到该逻辑链中的某个步骤一定是错误的。

错的是第一个。不要求方法由一大块 CIL 实现,然后将其集成到本机代码中。特别是用 extern 修饰符标记的 C# 方法是通过将控制转移到声明中提到的(可能是非托管代码)DLL 来实现的。因此,可以从 CLR 下的程序 运行 调用用其他语言编写的执行 CLR 管理之外的事情的代码。