新聞中心

        EEPW首頁 > 電源與新能源 > 設(shè)計應(yīng)用 > 基于FPGA的M2M異構(gòu)虛擬化系統(tǒng)(二)

        基于FPGA的M2M異構(gòu)虛擬化系統(tǒng)(二)

        作者: 時間:2018-08-31 來源:網(wǎng)絡(luò) 收藏

        本文引用地址:http://www.104case.com/article/201808/388222.htm

        Table 1 寄存器映射

        8086

        MIPS

        AX

        s0(R16)

        CX

        s1(R17)

        DX

        s2(R18)

        BX

        s3(R19)

        SP

        s4(R20)

        BP

        s5(R21)

        SI

        s6(R22)

        DI

        s7(R23)

        CS

        t4(R12)

        DS

        t5(R13)

        ES

        t6(R14)

        SS

        t7(R15)

        IP

        t8(R24)

          除了這些寄存器外,還給8086提供了3個輔助寄存器,t0、t1和t2。t0一般作為參數(shù)寄存器或返回值寄存器,t1和t2一般作為臨時寄存器。這幾個寄存器的存在有很大的必要性。

          4.2.6.上下文切換

          從翻譯流程可以看出,整個過程有兩個運行環(huán)境。翻譯過程是在MIPS環(huán)境中,執(zhí)行則是在MIPS的8086虛擬環(huán)境中。但硬件只有MIPS的一套寄存器,8086的寄存器是映射到MIPS的寄存器。在切換運行環(huán)境時,要先保存當(dāng)前寄存器組,再載入新的寄存器組。方式可以有兩種。一種是將寄存器組保存至堆棧,另一種是將寄存器組保存至內(nèi)存。這里將其保存至內(nèi)存,因為這更利于調(diào)試,可將寄存器值調(diào)出來查看。

          上下文切換實現(xiàn):

          /**

          * context switch

          * @param type - 0:從x86切換到mips,other:從mips切換到x86

          */

          void _contextSwitch(int type) {

          if (type == _MIPS_TYPE) {

          _saveRegisters(_X86_TYPE);

          _loadRegisters(_MIPS_TYPE);

          } else {

          _saveRegisters(_MIPS_TYPE);

          _loadRegisters(_X86_TYPE);

          }

          }

          上下文切換的流程及實現(xiàn)如下。

          

          圖 34 寄存器組切換

          4.2.7.字節(jié)順序與邊界對齊問題

          字節(jié)序(Byte Order)一般有兩種:大端序(big-endian)和小端序(little-endian)。大端序是將最高有效字節(jié)(MSB,Most Significant Byte)存放至低地址,小端序則是將最低有效字節(jié)(LSB,Least Significant Byte)存放至低地址。MIPS采用的是大端序,而8086使用的是小端序。因此,在二進制翻譯中,必須要處理這種差異。

          8086在訪問內(nèi)存時,如果是字節(jié)操作,那么翻譯時,可以使用對應(yīng)的MIPS字節(jié)操作指令,如lb,sb等。字節(jié)的操作不會有字節(jié)序問題,處理多字節(jié)時會有字節(jié)序問題。8086訪問多字節(jié)時,不能使用相應(yīng)的MIPS指令,而應(yīng)拆分讀取,最后再拼湊。過程如圖 35所示。

          

          圖 35 字節(jié)序問題解決

          4.2.8.堆棧處理

          MIPS有一個堆棧寄存器$sp,8086則是使用一個堆棧段寄存器SS與一個堆棧指針寄存器SP,實際地址為段基址加偏移地址。本設(shè)計MIPS和8086各自有自己的堆棧空間。8086堆棧操作對象有寄存器、立即數(shù)、內(nèi)存等。這里以寄存器壓棧為例,出棧情況類似。壓棧時,首先要計算出絕對地址,然后將寄存器保存。計算地址方法:(SS 4) + IP,是一個20位地址,尋址1M。push AX時,是對一個16位寄存器壓棧,由上面的字節(jié)序分析可知,要拆分成兩個字節(jié)壓棧。這里為了簡便,直接對32位MIPS寄存器進行壓棧,因為8086寄存器只占用MIPS寄存器的高16位。這里,絕對地址是放在輔助寄存器里的,因此要對該輔助寄存器進行保存,以防止要壓棧的寄存器就是該輔助寄存器而造成壓棧失敗。我們是將該輔助寄存器保存在MIPS的堆棧中。

          4.2.9.操作數(shù)分析

          8086的操作數(shù)類型比較多樣,有寄存器、立即數(shù)、內(nèi)存等。每個類型的位寬還可以變化,有8位、16位之分。MIPS比較規(guī)則,寄存器為32位,立即數(shù)為16位。兩者之間的轉(zhuǎn)換是翻譯的重要方面。

          寄存器如果是16位,則可以直接映射到對應(yīng)MIPS寄存器的高16位。如果是8位寄存器,不管是高8位還是低8位,一般都要移出至輔助寄存器的高8位。移到高8位的原因是為了運算時能產(chǎn)生正確的標志位。運算完后再將運算結(jié)果搬回8086寄存器。

          立即數(shù)有3種情況:8位,16位及由8位符號擴展來的16位立即數(shù)。8位及8位符號擴展可直接以字節(jié)訪問內(nèi)存得到,16位立即數(shù)則要注意字節(jié)序問題,上面已分析過。

          內(nèi)存方面涉及到內(nèi)存地址及所指向的內(nèi)存內(nèi)容。內(nèi)存地址的拼接會在下文詳細分析,8086有多種段寄存器與偏移的組合方式。取內(nèi)存內(nèi)容時也會遇到字節(jié)序的問題。

          操作數(shù)類型示意圖如下。

          

          圖 36 操作數(shù)類型

          4.2.10.二進制翻譯及代碼生成

          這部分主要解析8086指令,將其拆分,并生成相應(yīng)的MIPS代碼。在具體解析指令之前,先研究下8086二進制機器碼的特點,抽出公共特征。以下幾張表均來自于[6]。

        Table 2 oo修飾位說明

        oo

        功能

        00

        如果mmm=110,那么位移量在操作碼后面,否則沒有使用位移量

        01

        操作碼后面是8位有符號的位移量

        10

        操作碼后面是16位有符號的位移量

        11

        mmm指定一個寄存器而不是一種尋址方式

        Table 3 16位寄存器/存儲器(mmm)字段描述

        mmm

        16位寄存器

        000

        DS:[BX+SI]

        001

        DS:[BX+DI]

        010

        SS:[BP+SI]

        011

        SS:[BP+DI]

        100

        DS:[SI]

        101

        DS:[DI]

        110

        SS:[BP]

        111

        DS:[BX]

        Table 4寄存器字段(rrr)的分配

        rrr

        w=0

        w=1

        000

        AL

        AX

        001

        CL

        CX

        010

        DL

        DX

        011

        BL

        BX

        100

        AH

        SP

        101

        CH

        BP

        110

        DH

        SI

        111

        BH

        DI

        Table 5 對段寄存器的寄存器字段(rrr)的分配

        rrr

        段寄存器

        000

        ES

        001

        CS

        010

        SS

        011

        DS

          對oo字段的解析如下。當(dāng)oo為00的時,mmm索引存儲器有點變化。當(dāng)mmm為110b時,并不是按照表3來索引SS:[BP],而是DS+16位偏移量,其余情況則是按照表3,偏移量為0。當(dāng)oo為01時,偏移量為8位有符號數(shù)。當(dāng)oo為10時,偏移量為16位有符號數(shù)。根據(jù)oo和mmm來計算內(nèi)存地址的過程如下。

          

          圖 37 計算內(nèi)存地址

          rrr字段的實現(xiàn)。當(dāng)w為1時,rrr對應(yīng)的是16位寄存器,可直接映射到MIPS寄存器的索引值。當(dāng)w為0時,rrr對應(yīng)的是8位寄存器,需要對其重新標號,將AL作為0開始標號。代碼實現(xiàn)中,寄存器對應(yīng)的宏如下,其中包含了段寄存器。

          #define _X86_AL 0

          #define _X86_CL 1

          #define _X86_DL 2

          #define _X86_BL 3

          #define _X86_AH 4

          #define _X86_CH 5

          #define _X86_DH 6

          #define _X86_BH 7

          #define _X86_AX _MIPS_S0 // 0 16

          #define _X86_CX _MIPS_S1 // 1 17

          #define _X86_DX _MIPS_S2 // 2 18

          #define _X86_BX _MIPS_S3 // 3 19

          #define _X86_SP _MIPS_S4 // 4 20

          #define _X86_BP _MIPS_S5 // 5 21

          #define _X86_SI _MIPS_S6 // 6 22

          #define _X86_DI _MIPS_S7 // 7 23

          #define _X86_CS _MIPS_T4 // 8 12

          #define _X86_DS _MIPS_T5 // 9 13

          #define _X86_ES _MIPS_T6 // 10 14

          #define _X86_SS _MIPS_T7 // 11 15

          #define _X86_IP _MIPS_T8 // 12 24

          8086二進制機器碼的主要字段已解析,還有個別字段。

          Table 6 其他字段

        字段

        說明

        d

        運算方向

        w

        是否為字

        s

        是否符號擴展

        disp

        位移量

        data

        數(shù)據(jù),如立即數(shù)

          翻譯時將二進制機器碼拆分成各個字段,然后根據(jù)其語義生成對應(yīng)的MIPS指令。一條8086指令一般要翻譯成多條MIPS指令,其中一條為核心指令,其余為輔助指令。如加法指令中,將內(nèi)容移出至輔助寄存器都是輔助指令,最終的加法是核心指令。一般,核心指令對應(yīng)MIPS的一條指令,因此,可將其抽象出來,實現(xiàn)函數(shù)如下。

          /**

          * x86運算與mips對應(yīng)關(guān)系

          */

          int _keyGenerate(int type, int rt, int rd, int **target) {

          int instruction;

          switch (type) {

          case _X86_ADD0:

          instruction = _gen_add(rd, rt, rd);

          break;

          case _X86_AND0:

          instruction = _gen_and(rd, rt, rd);

          break;

          case _X86_OR0:

          instruction = _gen_or(rd, rt, rd);

          break;

          case _X86_SUB0:

          instruction = _gen_sub(rd, rt, rd);

          break;

          case _X86_XOR0:

          instruction = _gen_xor(rd, rt, rd);

          break;

          case _X86_MOV3:

          instruction = _gen_add(rt, _MIPS_ZERO, rd);

          break;

          case _X86_CMP0:

          instruction = _gen_sub(rd, rt, _MIPS_ZERO);

          break;

          default:

          break;

          }

          *(*target)++ = instruction;

          return instruction;

          }


        上一頁 1 2 下一頁

        關(guān)鍵詞:

        評論


        相關(guān)推薦

        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 东丰县| 宜兴市| 通州区| 雷波县| 高青县| 祥云县| 凤庆县| 金寨县| 延安市| 新营市| 乌兰县| 泉州市| 资兴市| 上饶市| 凌源市| 巴彦县| 藁城市| 资源县| 上饶县| 博乐市| 天等县| 正镶白旗| 介休市| 聂荣县| 都昌县| 盐津县| 天镇县| 沅江市| 华池县| 睢宁县| 兴宁市| 察哈| 泗洪县| 阿合奇县| 封开县| 荣昌县| 云阳县| 黄石市| 武平县| 遂昌县| 肥城市|