状态机这个想法来自jyy(ics.nju.edu.cn/~jyy/)
我们使用Java这种面向对象(更好的组织,维护代码)的编程语言来描述现实生活中存在的状态
class Person {
private int age;
}
使用Java描述的状态机,包含一个名称为age的属性
而JVM又维护着这个状态机
同时JVM也是一个状态机,被操作系统抽象为进程的方式管理着
现代操作系统需要运行各种各样的程序。为了管理这些程序的运行,操作系统提出了进程的抽象:每个进程都对应了一个运行中的程序。有了进程的抽象,应用程序在运行时仿佛独占了整个cpu(现代操作系统:原理与实现第五章76页)
在Java中使用age++修改状态,此时使用Java描述的状态机发生了改变
class Person {
private int age;
public void configAge() {
age++;
}
}
此时JVM做了什么呢?因为JVM是无法直接读懂我们写的代码,所以我们需要使用JDK提供的工具javac将代码编译为byte code
class Person {
private int age;
Person();
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public void configAge();
0: aload_0
1: dup
2: getfield #2 // Field age:I
5: iconst_1
6: iadd
7: putfield #2 // Field age:I
10: return
}
JVM解释,执行指令相对应的行为,而这个行为在JVM中被CPP描述了,而CPP描述的这个行为又会被编译器(clang/gcc)编译为当前CPU可以读懂的汇编代码(x86/asm),且符合当前OS规定的文件类型(linux: elf)
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], edi
add DWORD PTR [rbp-4], 1
那此时OS呢?CPU作为一个通电后不断取指 -> 译码 -> 执行的机器,代码最终被CPU执行,OS要做的就是按照的CPU手册所描述的行为,为每个进程维护一组寄存器的状态。
pushq %rbp
pushq %rbx
pushq %r12
pushq %r13
pushq %r14
pushq %r15
/* switch stack */
movq %rsp, TASK_threadsp(%rdi)
movq TASK_threadsp(%rsi), %rsp
#ifdef CONFIG_STACKPROTECTOR
movq TASK_stack_canary(%rsi), %rbx
movq %rbx, PER_CPU_VAR(fixed_percpu_data) + FIXED_stack_canary
#endif
/* restore callee-saved registers */
popq %r15
popq %r14
popq %r13
popq %r12
popq %rbx
popq %rbp