<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 探索Lua5.2內部實現:虛擬機指令(2) MOVE & LOAD | name | args | desc | |---|---|---| | OP_MOVE | A B | R(A) := R(B) | OP_MOVE用來將寄存器B中的值拷貝到寄存器A中。由于Lua是register based vm,大部分的指令都是直接對寄存器進行操作,而不需要對數據進行壓棧和彈棧,所以需要OP_MOVE指令的地方并不多。最直接的使用之處就是將一個local變量復制給另一個local變量時: ~~~ local?a;?? local?b?=?a;?? ~~~ ~~~ 1???[1]?LOADNIL?????0?0?? 2???[2]?MOVE????????1?0?? 3???[2]?RETURN??????0?1?? ~~~ 在編譯過程中,Lua會將每個local變量都分配到一個指定的寄存器中。在運行期,lua使用local變量所對應的寄存器id來操作local變量,而local變量的名字除了提供debug信息外,沒有其他作用。 在這里a被分配給register 0,b被分配給register 1。第二行的MOVE表示將a(register 0)的值賦給b(register 1)。其他使用的地方基本都是對寄存器的位置有特殊要求的地方,比如函數參數的傳遞等等。 | name | args | desc | |---|---|---| | OP_LOADK | A Bx | R(A) := Kst(Bx) | LOADK將Bx表示的常量表中的常量值裝載到寄存器A中。很多其他指令,比如數學操作指令,其本身可以直接從常量表中索引操作數,所以可以不依賴于LOADK指令。 ~~~ local?a=1;?? local?b="foo";?? ~~~ ~~~ 1???[1]?LOADK???????0?-1????;?1?? 2???[2]?LOADK???????1?-2????;?"foo"?? 3???[2]?RETURN??????0?1?? onstants?(2)?for?0x80048eb0:?? 1???1?? 2???"foo"??? ~~~ | name | args | desc | |---|---|---| | OP_LOADKX | A | R(A) := Kst(extra arg) | LOADKX是lua5.2新加入的指令。當需要生成LOADK指令時,如果需要索引的常量id超出了Bx所能表示的有效范圍,那么就生成一個LOADKX指令,取代LOADK指令,并且接下來立即生成一個EXTRAARG指令,并用其Ax來存放這個id。5.2的這個改動使得一個函數可以處理超過262143個常量。 | name | args | desc | |---|---|---| | OP_LOADBOOL | A B C | R(A) := (Bool)B; if (C) pc++ | LOADBOOL將B所表示的boolean值裝載到寄存器A中。B使用0和1分別代表false和true。C也表示一個boolean值,如果C為1,就跳過下一個指令。 ` local?a?=?true;??` ~~~ 1???[1]?LOADBOOL????0?1?0?? 2???[1]?RETURN??????0?1??? ~~~ C在這里的作用比較特殊。要了解C的具體用處,首先要知道lua中對于邏輯和關系表達式是如何處理的,比如: ` local?a?=?1?` 對于上面的代碼,一般我們會認為lua應該先對1<2求出一個boolean值,然后放入到a中。然而實際上產生出來的代碼為: ~~~ 1???[1]?LT??????????1?-1?-2?;?1?2?? 2???[1]?JMP?????????0?1?;?to?4?? 3???[1]?LOADBOOL????0?0?1?? 4???[1]?LOADBOOL????0?1?0?? 5???[1]?RETURN??????0?1?? onstants?(2)?for?0x80048eb0:?? 1???1?? 2???2??? ~~~ 可以看到,lua生成了LT和JMP指令,另外再加上兩個LOADBOOL對于a賦予不同的boolean值。LT(后面會詳細講解)指令本身并不產生一個boolean結果值,而是配合后面緊跟的JMP實現true和false的不同跳轉。如果LT評估為true,就繼續執行,也就是執行到JMP,然后調轉到4,對a賦予true;否則就跳過下一條指令到達第三行,對a賦予false,并且跳過下一個指令。所以上面的代碼實際的意思被轉化為: ~~~ local?a;?? if?1? ????a?=?true;?? else?? ????a?=?false;?? end?? ~~~ 邏輯或者關系表達式之所以被設計成這個樣子,主要是為if語句和循環語句所做的優化。不用將整個表達式估值成一個boolean值后再決定跳轉路徑,而是評估過程中就可以直接跳轉,節省了很多指令。 C的作用就是配合這種使用邏輯或關系表達式進行賦值的操作,他節省了后面必須跟的一個JMP指令。 | name | args | desc | |---|---|---| | OP_LOADNIL | A B | R(A), R(A+1), ..., R(A+B) := nil | LOADNIL將使用A到B所表示范圍的寄存器賦值成nil。用范圍表示寄存器主要為了對以下情況進行優化: ~~~ local?a,b,c;?? ~~~ ~~~ 1???[1]?LOADNIL?????0?2?? 2???[1]?RETURN??????0?1??? ~~~ 對于連續的local變量聲明,使用一條LOADNIL指令就可以完成,而不需要分別進行賦值。 對于一下情況 ~~~ local?a;?? local?b?=?0;?? local?c;?? ~~~ ~~~ 1???[1]?LOADNIL?????0?0?? 2???[2]?LOADK???????1?-1????;?0?? 3???[3]?LOADNIL?????2?0??? ~~~ 在Lua5.2中,a和c不能被合并成一個LOADNIL指令。所以以上寫法理論上會生成更多的指令,應該予以避免,而改寫成 ~~~ local?a,c;?? local?b?=?0; ? ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看