owned this note
owned this note
Published
Linked with GitHub
# 系統程式期中報告
> **筆記閱讀於系統程式 - 第 9 章、虛擬機器加上部分自己的理解**
參考資料
https://www.slideshare.net/ccckmit/9-128033151
http://sp1.wdfiles.com/local--files/slide/ch09.pdf
程式碼閱讀自系統程式 第十二章 系統軟體實作 看完部分了解
https://www.slideshare.net/ccckmit/12-73472945
---
**虛擬機的架構**
**虛擬機的類型**
* 原生式
* 寄生式
1. 記憶體機 2. 暫存器機 3. 堆疊機
甚麼是虛擬機?
在硬體平台上提供一個虛擬的環境讓應用程式執行
甚麼是記憶體機?
可以直接對記憶體變數進行運算
甚麼是堆疊機?
必須將變數載入暫存器中,才能進行運算
甚麼是暫存器機?
取出堆疊上層元素進行運算,然後將結果存回堆疊之中
* 記憶體機的組合語言
```
= 0 sum
= 0 i
Foro:
CMP i 10
J > _FORO
+ sum i TO
= TO sum
+ i 1 i
J FORO
_FORO:
RET sum
```
```
= 0 sum ; 將變數sum初始化為0
= 0 i ; 將變數i初始化為0
Foro: ; 迴圈的標籤
CMP i 10 ; 比較變數i和10
J > _FORO ; 如果i大於10,跳轉到_FORO標籤
+ sum i ; 將變數i的值加到變數sum上
TO sum ; 將計算結果存回變數sum中
+ i 1 ; 將變數i增加1
J FORO ; 跳轉回FORO標籤,進行下一次迴圈
_FORO: ; 迴圈結束後的標籤
RET sum ; 返回變數sum的值
```
* 暫存器機的組合語言
```
LDI R1, 0
ST R1, sum
LDI R2, 0
ST R2, i
LDI R3, 1
LDI R4, 10
FORO:
CMP R2, R4
JGT _FORO
ADD R1, R1, R2
ADD R2, R2, R3
JMP FORO
FORO:
ST R1, sum
RET
i: RESW 1
sum: RESW 1
```
```
LDI R1, 0 ; 載入立即值0到暫存器R1
ST R1, sum ; 將R1的值存儲到變數sum中
LDI R2, 0 ; 載入立即值0到暫存器R2
ST R2, i ; 將R2的值存儲到變數i中
LDI R3, 1 ; 載入立即值1到暫存器R3
LDI R4, 10 ; 載入立即值10到暫存器R4
FORO: ; 迴圈的標籤
CMP R2, R4 ; 比較R2和R4的值
JGT _FORO ; 如果R2大於R4,則跳轉到_FORO標籤
ADD R1, R1, R2 ; 將R1和R2的值相加,並將結果存回R1
ADD R2, R2, R3 ; 將R2和R3的值相加,並將結果存回R2
JMP FORO ; 跳轉回FORO標籤,進行下一次迴圈
_FORO: ; 迴圈結束後的標籤
ST R1, sum ; 將R1的值存儲到變數sum中
RET ; 返回
i: RESW 1 ; 定義變數i,佔用1個字的記憶體空間
sum: RESW 1 ; 定義變數sum,佔用1個字的記憶體空間
```
* 堆疊機的組合語言
```
PUSH 0
POP sum
PUSH 0
pop i
FORO:
PUSH i
PUSH 10
CMP
PUSH _FORO
JGT
PUSH sum
PUSH i
ADD
pop sum
PUSH i
PUSH i
ADD
pop i
PUSH FORO
JMP
_FORO:
PUSH sum
RET
i_ RESW 1
sum RESW 1
```
```
PUSH 0 ; 將值0壓入堆疊
POP sum ; 將堆疊頂部的值彈出並存儲到變數sum中
PUSH 0 ; 將值0壓入堆疊
POP i ; 將堆疊頂部的值彈出並存儲到變數i中
FORO: ; 迴圈的標籤
PUSH i ; 將變數i的值壓入堆疊
PUSH 10 ; 將值10壓入堆疊
CMP ; 比較堆疊頂部的兩個值
PUSH _FORO ; 將標籤_FORO壓入堆疊
JGT ; 如果前一次比較結果大於,則跳轉到堆疊頂部的標籤
PUSH sum ; 將變數sum的值壓入堆疊
PUSH i ; 將變數i的值壓入堆疊
ADD ; 從堆疊頂部彈出兩個值,相加後再壓入堆疊
POP sum ; 將堆疊頂部的值彈出並存儲到變數sum中
PUSH i ; 將變數i的值壓入堆疊
PUSH i ; 將變數i的值壓入堆疊
ADD ; 從堆疊頂部彈出兩個值,相加後再壓入堆疊
POP i ; 將堆疊頂部的值彈出並存儲到變數i中
PUSH FORO ; 將標籤FORO壓入堆疊
JMP ; 無條件跳轉到堆疊頂部的標籤
_FORO: ; 迴圈結束後的標籤
PUSH sum ; 將變數sum的值壓入堆疊
RET ; 返回
i_ RESW 1 ; 定義變數i,佔用1個字的記憶體空間
sum RESW 1 ; 定義變數sum,佔用1個字的記憶體空間
```
**堆疊機的adi指令執行過程示意圖**
![](https://hackmd.io/_uploads/SJ0cZgbIh.png)
ADI 指令用於將一個常數與堆疊頂部的數據進行相加
**adi(Add Immediate)**
**堆疊機的執行過程**
![](https://hackmd.io/_uploads/BkzkD0e8h.png)
* **CPU0虛擬機**
![](https://hackmd.io/_uploads/ryBco0xI2.png)
指令擷取階段 將指令從記憶體取到 IR
![](https://hackmd.io/_uploads/HJLz2Ae8n.png)
指令解碼
![](https://hackmd.io/_uploads/BJWr6AxL3.png)
儲存指令
![](https://hackmd.io/_uploads/SyQuaReI2.png)
運算指令
![](https://hackmd.io/_uploads/ryePRAgUh.png)
跳躍指令
![](https://hackmd.io/_uploads/B14FRRgIh.png)
堆疊指令
![](https://hackmd.io/_uploads/HyuQyyW83.png)
* **JVM虛擬機**
![](https://hackmd.io/_uploads/ryZ6dkZI2.png)
![](https://hackmd.io/_uploads/SkJeHJbL3.png)
J與C的執行模式對照
![](https://hackmd.io/_uploads/SythtJbIn.png)
![](https://hackmd.io/_uploads/r1DXCsV82.png)
bytecode是針對JVM的執行環境,是Java編譯器將Java源代碼編譯成的一系列指令