简单虚拟机
把在其它平台运行的指令集,虚拟一个环境出来执行。
大概就是把指令集翻译成汇编形式。
数值操作指令直接对应就好。
主要是转换流程控制语句。
for循环--
循环本身流程 code_c
lx1: do something
lx2 : jmp lx1
这样就没法停下来。
在循环流程前加一个跳转开关。
jmp lx2+1
然后加上条件跳转
lx1:icmp i,c_count
[feq] jmp lx2+1
do something
add i,1
lx2: jmp lx1
if else--
本身流程
lx1:do something1
lx2: do something2
条件跳转开关
icmp c1,value
[feq] jmp lx2
lx1:do something1
lx2:do something2
跳转开关和上层语言写起来逻辑有点相反。关心的目标是后面的指令地址。
函数实现
流程控制
指令寄存器 eip
参数传递
有说是传给寄存器,
有说是传到栈,
返回值
看着都是通过寄存器传递,如果返回值是数组之类较大的,就返回地址。
函数内部
寄存器的使用。
公用寄存器 天然就能传递数据。
在内部函数中又要求不受干扰,像内部变量。需要保存寄存器的前值,并在使用后复原。
需要一个存储池来维持寄存器。--栈
执行配套的动作。
用之前把寄存器压栈。返回前把寄存器出栈。
空间来换取流程。
递归--
fibo(int eax)
cmp eax, 1
je _get_out
cmp eax, 2
je _get_out
move edx eax --保存传入参数
sub eax ,1 --(n-1)
call fibo(eax) --递归调用
move ebx eax --保存返回值
sub eax ,2 --(n-2)
call fibo(eax) --递归调用
move ecx eax --保存返回值
move eax,ebx
add eax,ecx //返回值相加
ret
寄存器状态。
1.程序外的值。。 eax=4
push ....
edx =eax
1.1 eax =3
push...
edx=eax
1.1.1 eax 2
ret 1
1.1 ebx=1
1.1.2 eax=1
ret 1
1.1 ecx=1
一切都是操作寄存器的感觉。
数据复制也是先读到寄存器,再写到内存。