# 2017q3 Homework3 (simulator)
contributed by <`yusihlin`>
## 分析 full-stack-hello
* as : 將組合語言組譯產生對應的 elf file
* $ : constant integer
* \# : temp integer ( 也可寫作 register? )
* \ : string literal
* elf : 提供寫入讀取 elf 所需的函式
* vm : 虛擬機環境配置
* vm_regs 記錄程式執行的狀態
* __vm_env 為虛擬機的環境配置
```C
typedef struct {
size_t pc; // program counter.
size_t sp; // stack runs from the end of 'temps' region.
size_t from; // the immediate PC before last branch/return.
size_t to; // the immediate PC after last branch/return.
} vm_regs;
struct __vm_env {
vm_inst insts[INSTS_MAX_SIZE]; /* Program instructions */
vm_value cpool[CPOOL_MAX_SIZE]; /* Constant pool */
vm_value temps[TEMPS_MAX_SIZE]; /* Temporary storage */
vm_opcode_impl impl[OPCODE_IMPL_MAX_SIZE]; /* OPCODE impl */
vm_regs r;
int insts_count;
int cpool_count;
int temps_count;
};
```
* opcode : 實作用於虛擬機的指令集
* driver : 主程式部分,在後續允許接受輸入參數的判斷也須在這裡的 argv 新增,內涵指令說明與運行模式
* ASSEMBLE_AND_EVAL : 組譯並執行
* ASSEMBLE_AND_WRITE_ELF : 組譯後輸出 elf
* LOAD_ELF_AND_EVAL : 載入 elf 並執行
```Clike
Usage: as_exec [-w] [-x] [-o <out_file>] <in_file>
-w Assemble <in_file> and write to an ELF file, see -o below
-o if -w is specifed, <out_file> is used to store the object code
-x Load <in_file> and execute it
<in_file> the file name to be used by commands above
```
## 接受 --input 輸入參數
參考 [st9007a 共筆](https://hackmd.io/s/Hkf6pkPAb#接受輸入參數)
在 driver.c 中加入 --input 的參數
```C
else if (!strcmp(argv[i], "--input")) {
if (!argv[i+1])
FATAL(-1, "--input need an integer as argument, see -h\n");
input_val = atoi(argv[++i]);
}
```
在 vm.c 加入 vm_set_temp_value 存放 input_val
```C
inline void vm_set_temp_value(vm_env *env, int pos, int val)
{
vm_value v = {.type = INT};
v.value.vint = val;
env->temps[pos] = v;
}
```
回到 driver.c,不同 case 中將 input_val 存放在 #0 中
```C
vm_set_temp_value(env, 0, input_val);
```
## 實作 Fibonacci 數列
### Iterative
```
; if #0 = 0, print 0
jz #0, #13
sub #0 $1 #0
; initialize result, f(0) = 0, f(1) = 1
or $0 $0 #3
or $0 $0 #1
or $0 $1 #2
; iteration
sub #0 $1 #0
add #1 #2 #3
or #2 $0 #1
or #3 $0 #2
jz #0 #11
jgt #0 #5
; print result
print #3
halt
;print 0 if input = 0
print $0
halt
```
### Recursive
```
; initialize result
or $0 $0 #1
; call recursive function
call #4
; print result
print #1
halt
; recursion
xor #0 $1 #2 ;if input = 1, return
jnz #2 #8
add #1 $1 #1
ret
xor #0 $0 #2 ;if input = 0, return
jnz #2 #11
ret
; call f(n-1)
sub #0 $1 #0
call #4
; call f(n-2)
sub #0 $1 #0
call #4
add #0 $2 #0
ret
```