Python 2.6.2的字节码指令集一览
生活随笔
收集整理的這篇文章主要介紹了
Python 2.6.2的字节码指令集一览
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
對Python的字節碼指令集感興趣但不知道從何下手么?執行這段代碼就能看到字節碼的列表:?
(格式:操作碼的十六進制(十進制): 操作碼的助記名)?
Python opcode list代碼??
助記名為“<n>”形式的是未使用的操作碼。?
既然叫“字節碼”,這些操作碼自然是以字節為單位的咯,于是最多只能表示256個不同的操作碼。Python實際上只用了百來個操作碼。?
操作碼小于90的為無參數的,指令僅包含操作碼自身,共1字節;大于等于90的,則每條指令在操作碼之后還帶有1個參數,參數長度為2字節,共3字節。?
Python程序的字節碼在運行時以PyStringObject的形式保存在PyCodeObject的co_code域里。co_code域只含有指令而不包含別的程序數據;變量名、常量等數據均放在別的域里。?
Python的字節碼指令集是基于棧的指令集。這里說的“棧”不是指函數調用棧,而是指專門用于求值的棧,可以稱為“求值?!?#xff08;evaluation stack)或者“操作數?!?#xff08;operand stack)。求值過程的臨時變量都放在求值棧上,指令集中的大部分都是與棧打交道。?
例如3 + 4會變成:?
Python bytecode代碼??
假設常量池中下標為0和1的項分別是3和4這兩個常量,則頭兩條指令分別將這兩個常量壓入求值棧,然后BINARY_ADD指令將求值棧棧頂的兩個值彈出,計算加法,并將結果再次壓入棧中。理解了這點,則Python的指令集基本上都能顧名思義。操作碼對應的具體意義可以在下面的官網文檔鏈接查到。?
但既然求值的參數和結果都放在求值棧上,那何必要帶參數的指令呢??
關鍵區別就是,帶參數的指令的參數都是一些由編譯器指定的常量,例如指向常量池的下標、函數的參數個數、跳轉指令的偏移量等。這些值不是Python對象,無法由程序員在源碼中顯式指定或操縱。?
而求值棧上放的則是在源碼中顯式指定的一些參與計算的值,或者計算后的中間結果。這些值都是Python對象,其行為遵循Python類型系統的規定。?
Python字節碼中所有控制流指令都是帶參數的,并且它們都不額外從求值棧取任何參數。這使得Python字節碼程序的控制流在編譯時就確定下來,或者說是可靜態確定的。這樣可以降低控制流被程序代碼破壞的風險,也方便了解釋器的實現。?
python.org上關于Python字節碼的詳細介紹文檔我只找到了一份,是對應 Python 2.5.2的字節碼列表 。Python 2.6.2中大部分指令與這份文檔中的相同,但有些細節不同,例如文檔中說DUP_TOPX的參數范圍是1-5,但在Python 2.6.2里實際上只允許2-3的范圍。?
在Python 3.x中字節碼有了新的調整,至少PRINT_*系列的字節碼都取消了。本帖開頭的代碼在Python 3.x上也可以運行,有興趣的同學可以對比看看。?
對Python字節碼的解釋方式感興趣的同學,可以從 ceval.c 入手,觀察Python虛擬機的核心——PyEval_EvalFrameEx()的實現。
對于python 3.0也是上述方法:
輸出指令:
0x00(000): <0> 0x01(001): POP_TOP 0x02(002): ROT_TWO 0x03(003): ROT_THREE 0x04(004): DUP_TOP 0x05(005): DUP_TOP_TWO 0x06(006): <6> 0x07(007): <7> 0x08(008): <8> 0x09(009): NOP 0x0A(010): UNARY_POSITIVE 0x0B(011): UNARY_NEGATIVE 0x0C(012): UNARY_NOT 0x0D(013): <13> 0x0E(014): <14> 0x0F(015): UNARY_INVERT 0x10(016): BINARY_MATRIX_MULTIPLY 0x11(017): INPLACE_MATRIX_MULTIPLY 0x12(018): <18> 0x13(019): BINARY_POWER 0x14(020): BINARY_MULTIPLY 0x15(021): <21> 0x16(022): BINARY_MODULO 0x17(023): BINARY_ADD 0x18(024): BINARY_SUBTRACT 0x19(025): BINARY_SUBSCR 0x1A(026): BINARY_FLOOR_DIVIDE 0x1B(027): BINARY_TRUE_DIVIDE 0x1C(028): INPLACE_FLOOR_DIVIDE 0x1D(029): INPLACE_TRUE_DIVIDE 0x1E(030): <30> 0x1F(031): <31> 0x20(032): <32> 0x21(033): <33> 0x22(034): <34> 0x23(035): <35> 0x24(036): <36> 0x25(037): <37> 0x26(038): <38> 0x27(039): <39> 0x28(040): <40> 0x29(041): <41> 0x2A(042): <42> 0x2B(043): <43> 0x2C(044): <44> 0x2D(045): <45> 0x2E(046): <46> 0x2F(047): <47> 0x30(048): <48> 0x31(049): <49> 0x32(050): GET_AITER 0x33(051): GET_ANEXT 0x34(052): BEFORE_ASYNC_WITH 0x35(053): <53> 0x36(054): <54> 0x37(055): INPLACE_ADD 0x38(056): INPLACE_SUBTRACT 0x39(057): INPLACE_MULTIPLY 0x3A(058): <58> 0x3B(059): INPLACE_MODULO 0x3C(060): STORE_SUBSCR 0x3D(061): DELETE_SUBSCR 0x3E(062): BINARY_LSHIFT 0x3F(063): BINARY_RSHIFT 0x40(064): BINARY_AND 0x41(065): BINARY_XOR 0x42(066): BINARY_OR 0x43(067): INPLACE_POWER 0x44(068): GET_ITER 0x45(069): GET_YIELD_FROM_ITER 0x46(070): PRINT_EXPR 0x47(071): LOAD_BUILD_CLASS 0x48(072): YIELD_FROM 0x49(073): GET_AWAITABLE 0x4A(074): <74> 0x4B(075): INPLACE_LSHIFT 0x4C(076): INPLACE_RSHIFT 0x4D(077): INPLACE_AND 0x4E(078): INPLACE_XOR 0x4F(079): INPLACE_OR 0x50(080): BREAK_LOOP 0x51(081): WITH_CLEANUP_START 0x52(082): WITH_CLEANUP_FINISH 0x53(083): RETURN_VALUE 0x54(084): IMPORT_STAR 0x55(085): SETUP_ANNOTATIONS 0x56(086): YIELD_VALUE 0x57(087): POP_BLOCK 0x58(088): END_FINALLY 0x59(089): POP_EXCEPT 0x5A(090): STORE_NAME 0x5B(091): DELETE_NAME 0x5C(092): UNPACK_SEQUENCE 0x5D(093): FOR_ITER 0x5E(094): UNPACK_EX 0x5F(095): STORE_ATTR 0x60(096): DELETE_ATTR 0x61(097): STORE_GLOBAL 0x62(098): DELETE_GLOBAL 0x63(099): <99> 0x64(100): LOAD_CONST 0x65(101): LOAD_NAME 0x66(102): BUILD_TUPLE 0x67(103): BUILD_LIST 0x68(104): BUILD_SET 0x69(105): BUILD_MAP 0x6A(106): LOAD_ATTR 0x6B(107): COMPARE_OP 0x6C(108): IMPORT_NAME 0x6D(109): IMPORT_FROM 0x6E(110): JUMP_FORWARD 0x6F(111): JUMP_IF_FALSE_OR_POP 0x70(112): JUMP_IF_TRUE_OR_POP 0x71(113): JUMP_ABSOLUTE 0x72(114): POP_JUMP_IF_FALSE 0x73(115): POP_JUMP_IF_TRUE 0x74(116): LOAD_GLOBAL 0x75(117): <117> 0x76(118): <118> 0x77(119): CONTINUE_LOOP 0x78(120): SETUP_LOOP 0x79(121): SETUP_EXCEPT 0x7A(122): SETUP_FINALLY 0x7B(123): <123> 0x7C(124): LOAD_FAST 0x7D(125): STORE_FAST 0x7E(126): DELETE_FAST 0x7F(127): STORE_ANNOTATION 0x80(128): <128> 0x81(129): <129> 0x82(130): RAISE_VARARGS 0x83(131): CALL_FUNCTION 0x84(132): MAKE_FUNCTION 0x85(133): BUILD_SLICE 0x86(134): <134> 0x87(135): LOAD_CLOSURE 0x88(136): LOAD_DEREF 0x89(137): STORE_DEREF 0x8A(138): DELETE_DEREF 0x8B(139): <139> 0x8C(140): <140> 0x8D(141): CALL_FUNCTION_KW 0x8E(142): CALL_FUNCTION_EX 0x8F(143): SETUP_WITH 0x90(144): EXTENDED_ARG 0x91(145): LIST_APPEND 0x92(146): SET_ADD 0x93(147): MAP_ADD 0x94(148): LOAD_CLASSDEREF 0x95(149): BUILD_LIST_UNPACK 0x96(150): BUILD_MAP_UNPACK 0x97(151): BUILD_MAP_UNPACK_WITH_CALL 0x98(152): BUILD_TUPLE_UNPACK 0x99(153): BUILD_SET_UNPACK 0x9A(154): SETUP_ASYNC_WITH 0x9B(155): FORMAT_VALUE 0x9C(156): BUILD_CONST_KEY_MAP 0x9D(157): BUILD_STRING 0x9E(158): BUILD_TUPLE_UNPACK_WITH_CALL 0x9F(159): <159> 0xA0(160): <160> 0xA1(161): <161> 0xA2(162): <162> 0xA3(163): <163> 0xA4(164): <164> 0xA5(165): <165> 0xA6(166): <166> 0xA7(167): <167> 0xA8(168): <168> 0xA9(169): <169> 0xAA(170): <170> 0xAB(171): <171> 0xAC(172): <172> 0xAD(173): <173> 0xAE(174): <174> 0xAF(175): <175> 0xB0(176): <176> 0xB1(177): <177> 0xB2(178): <178> 0xB3(179): <179> 0xB4(180): <180> 0xB5(181): <181> 0xB6(182): <182> 0xB7(183): <183> 0xB8(184): <184> 0xB9(185): <185> 0xBA(186): <186> 0xBB(187): <187> 0xBC(188): <188> 0xBD(189): <189> 0xBE(190): <190> 0xBF(191): <191> 0xC0(192): <192> 0xC1(193): <193> 0xC2(194): <194> 0xC3(195): <195> 0xC4(196): <196> 0xC5(197): <197> 0xC6(198): <198> 0xC7(199): <199> 0xC8(200): <200> 0xC9(201): <201> 0xCA(202): <202> 0xCB(203): <203> 0xCC(204): <204> 0xCD(205): <205> 0xCE(206): <206> 0xCF(207): <207> 0xD0(208): <208> 0xD1(209): <209> 0xD2(210): <210> 0xD3(211): <211> 0xD4(212): <212> 0xD5(213): <213> 0xD6(214): <214> 0xD7(215): <215> 0xD8(216): <216> 0xD9(217): <217> 0xDA(218): <218> 0xDB(219): <219> 0xDC(220): <220> 0xDD(221): <221> 0xDE(222): <222> 0xDF(223): <223> 0xE0(224): <224> 0xE1(225): <225> 0xE2(226): <226> 0xE3(227): <227> 0xE4(228): <228> 0xE5(229): <229> 0xE6(230): <230> 0xE7(231): <231> 0xE8(232): <232> 0xE9(233): <233> 0xEA(234): <234> 0xEB(235): <235> 0xEC(236): <236> 0xED(237): <237> 0xEE(238): <238> 0xEF(239): <239> 0xF0(240): <240> 0xF1(241): <241> 0xF2(242): <242> 0xF3(243): <243> 0xF4(244): <244> 0xF5(245): <245> 0xF6(246): <246> 0xF7(247): <247> 0xF8(248): <248> 0xF9(249): <249> 0xFA(250): <250> 0xFB(251): <251> 0xFC(252): <252> 0xFD(253): <253> 0xFE(254): <254> 0xFF(255): <255>
總結
以上是生活随笔為你收集整理的Python 2.6.2的字节码指令集一览的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OCLint 初探
- 下一篇: 50个正能量励志小故事精选