# 2017q3 Homework3 (simulator)
###### tags: `進階電腦系統理論與實作 (Fall 2017)`
contributed by < `jcyztw` >
## 輸入參數
trace 程式碼之後,找到 `as_exec` 執行檔的程式進入點:`driver.c` 的 `main()`,接著著手加入可帶入計算費氏數列的自訂參數(`-f`)的程式碼。加入 `-f` 參數選項的基本字串處理後,首先在 vm 執行前(`vm_run`)前先把 input 帶入到我們寫的計算費氏數列的程式中。
目前只有對 `ASSEMBLE_AND_EVAL` 這個case 作處理
(輸入參數方式舉例:`./as_exec -f [input] tests/fib-iterative.s`):
```
switch (req) {
case ASSEMBLE_AND_EVAL: {
vm_env *env = vm_new();
assemble_from_fd(env, in_fd);
if (fib_input >= 0) {
vm_set_temp_int_value(env, 0, fib_input);
}
hook_opcodes(env);
vm_run(env);
vm_free(env);
break;
}
...
}
```
此處新增一個函式 `vm_set_temp_int_value()` 用來存取 `env` 這個變數( data type:`vm_env`,此變數存放我們寫的程式所有指令、每個指令的 operand 等等的資訊),用來把 input 放到我們指定的 register 中。
```
<vm.c>
void vm_set_temp_int_value(vm_env *env, int id, int val)
{
env->temps[id].value.vint = val;
}
```
接著來看看目前已經寫好的費氏數列計算程式( recursive 版本待補 (>_< ;) )
### Iterative (`fib-iterative.s`)
```=
;First get parameter from user input
add $0 #0 #0
;Return value if input is equal to 0 or 1
add #0 $0 #3
jz #0 #13
sub #0 $1 #4
jz #4 #13
;Store loop counter in #4 if input greater than 1
sub #0 $2 #4
;fib(0)=0 and fib(1)=1
add $0 $0 #1
add $0 $1 #2
add #1 #2 #3
add #2 $0 #1
add #3 $0 #2
sub #4 $1 #4
jge #4 #8
print #3
```
透過先前提過的 `vm_set_temp_int_value()` 函式,已將 input 紀錄到 `#0` 中(第 2 行)。接著判斷 input 值是否為 0 或 1(第 4 到第 7 行),若是,則跳到最後印出結果(第 18 行);若否,則透過 loop 的方式計算出結果 (第 9 到 第 17 行)。(注:目前尚未針對 input 大於 62 的情況作處理)
commit 程式碼出現問題,還不知道原因是什麼,處理中。
:::danger
文字訊息不要用圖片表示!
:notes: jserv
:::
> 已修正,謝謝老師的提醒!
> [name="jcyztw"]
>
```
...
[!] vm.c does not follow the consistent coding style.
Make sure you have run clang-format as the following:
clang-format -i vm.h
```
commit 失敗的原因是 `git commit` 之後 clang-format 有改過某幾個檔案的排版,導致這些檔案需要重新 `git add`。表示 commit 之前必須先用 clang-format 檢查排版,之後再 `git add`,如此一來後續的 commit 才不會出現這個問題。
## 參考資料
* 巨人的肩膀(同學共筆):[st9007a](https://hackmd.io/s/Hkf6pkPAb)
* 學習教材
* [現代處理器設計:原理和關鍵特徵](https://hackmd.io/s/Hk2CscGcl)
* [你所不知道的 C 語言:編譯器和最佳化原理篇](https://hackmd.io/s/Hy72937Me)