# 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)