Try   HackMD

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 為虛擬機的環境配置
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 並執行
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 共筆

在 driver.c 中加入 input 的參數

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

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 中

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