Python 2.6.2的字节码指令集一览

对Python的字节码指令集感兴趣但不知道从何下手么?执行这段代码就能看到字节码的列表: 

Python代码   收藏代码
  1. import opcode  
  2. for op in range(len(opcode.opname)):  
  3.   print('0x%.2X(%.3d): %s' % (op, op, opcode.opname[op]))  
在Python 2.6.2上运行的输出结果: 
(格式:操作码的十六进制(十进制): 操作码的助记名) 
Python opcode list代码   收藏代码
  1. 0x00(000): STOP_CODE  
  2. 0x01(001): POP_TOP  
  3. 0x02(002): ROT_TWO  
  4. 0x03(003): ROT_THREE  
  5. 0x04(004): DUP_TOP  
  6. 0x05(005): ROT_FOUR  
  7. 0x06(006): <6>  
  8. 0x07(007): <7>  
  9. 0x08(008): <8>  
  10. 0x09(009): NOP  
  11. 0x0A(010): UNARY_POSITIVE  
  12. 0x0B(011): UNARY_NEGATIVE  
  13. 0x0C(012): UNARY_NOT  
  14. 0x0D(013): UNARY_CONVERT  
  15. 0x0E(014): <14>  
  16. 0x0F(015): UNARY_INVERT  
  17. 0x10(016): <16>  
  18. 0x11(017): <17>  
  19. 0x12(018): LIST_APPEND  
  20. 0x13(019): BINARY_POWER  
  21. 0x14(020): BINARY_MULTIPLY  
  22. 0x15(021): BINARY_DIVIDE  
  23. 0x16(022): BINARY_MODULO  
  24. 0x17(023): BINARY_ADD  
  25. 0x18(024): BINARY_SUBTRACT  
  26. 0x19(025): BINARY_SUBSCR  
  27. 0x1A(026): BINARY_FLOOR_DIVIDE  
  28. 0x1B(027): BINARY_TRUE_DIVIDE  
  29. 0x1C(028): INPLACE_FLOOR_DIVIDE  
  30. 0x1D(029): INPLACE_TRUE_DIVIDE  
  31. 0x1E(030): SLICE+0  
  32. 0x1F(031): SLICE+1  
  33. 0x20(032): SLICE+2  
  34. 0x21(033): SLICE+3  
  35. 0x22(034): <34>  
  36. 0x23(035): <35>  
  37. 0x24(036): <36>  
  38. 0x25(037): <37>  
  39. 0x26(038): <38>  
  40. 0x27(039): <39>  
  41. 0x28(040): STORE_SLICE+0  
  42. 0x29(041): STORE_SLICE+1  
  43. 0x2A(042): STORE_SLICE+2  
  44. 0x2B(043): STORE_SLICE+3  
  45. 0x2C(044): <44>  
  46. 0x2D(045): <45>  
  47. 0x2E(046): <46>  
  48. 0x2F(047): <47>  
  49. 0x30(048): <48>  
  50. 0x31(049): <49>  
  51. 0x32(050): DELETE_SLICE+0  
  52. 0x33(051): DELETE_SLICE+1  
  53. 0x34(052): DELETE_SLICE+2  
  54. 0x35(053): DELETE_SLICE+3  
  55. 0x36(054): STORE_MAP  
  56. 0x37(055): INPLACE_ADD  
  57. 0x38(056): INPLACE_SUBTRACT  
  58. 0x39(057): INPLACE_MULTIPLY  
  59. 0x3A(058): INPLACE_DIVIDE  
  60. 0x3B(059): INPLACE_MODULO  
  61. 0x3C(060): STORE_SUBSCR  
  62. 0x3D(061): DELETE_SUBSCR  
  63. 0x3E(062): BINARY_LSHIFT  
  64. 0x3F(063): BINARY_RSHIFT  
  65. 0x40(064): BINARY_AND  
  66. 0x41(065): BINARY_XOR  
  67. 0x42(066): BINARY_OR  
  68. 0x43(067): INPLACE_POWER  
  69. 0x44(068): GET_ITER  
  70. 0x45(069): <69>  
  71. 0x46(070): PRINT_EXPR  
  72. 0x47(071): PRINT_ITEM  
  73. 0x48(072): PRINT_NEWLINE  
  74. 0x49(073): PRINT_ITEM_TO  
  75. 0x4A(074): PRINT_NEWLINE_TO  
  76. 0x4B(075): INPLACE_LSHIFT  
  77. 0x4C(076): INPLACE_RSHIFT  
  78. 0x4D(077): INPLACE_AND  
  79. 0x4E(078): INPLACE_XOR  
  80. 0x4F(079): INPLACE_OR  
  81. 0x50(080): BREAK_LOOP  
  82. 0x51(081): WITH_CLEANUP  
  83. 0x52(082): LOAD_LOCALS  
  84. 0x53(083): RETURN_VALUE  
  85. 0x54(084): IMPORT_STAR  
  86. 0x55(085): EXEC_STMT  
  87. 0x56(086): YIELD_VALUE  
  88. 0x57(087): POP_BLOCK  
  89. 0x58(088): END_FINALLY  
  90. 0x59(089): BUILD_CLASS  
  91. 0x5A(090): STORE_NAME  
  92. 0x5B(091): DELETE_NAME  
  93. 0x5C(092): UNPACK_SEQUENCE  
  94. 0x5D(093): FOR_ITER  
  95. 0x5E(094): <94>  
  96. 0x5F(095): STORE_ATTR  
  97. 0x60(096): DELETE_ATTR  
  98. 0x61(097): STORE_GLOBAL  
  99. 0x62(098): DELETE_GLOBAL  
  100. 0x63(099): DUP_TOPX  
  101. 0x64(100): LOAD_CONST  
  102. 0x65(101): LOAD_NAME  
  103. 0x66(102): BUILD_TUPLE  
  104. 0x67(103): BUILD_LIST  
  105. 0x68(104): BUILD_MAP  
  106. 0x69(105): LOAD_ATTR  
  107. 0x6A(106): COMPARE_OP  
  108. 0x6B(107): IMPORT_NAME  
  109. 0x6C(108): IMPORT_FROM  
  110. 0x6D(109): <109>  
  111. 0x6E(110): JUMP_FORWARD  
  112. 0x6F(111): JUMP_IF_FALSE  
  113. 0x70(112): JUMP_IF_TRUE  
  114. 0x71(113): JUMP_ABSOLUTE  
  115. 0x72(114): <114>  
  116. 0x73(115): <115>  
  117. 0x74(116): LOAD_GLOBAL  
  118. 0x75(117): <117>  
  119. 0x76(118): <118>  
  120. 0x77(119): CONTINUE_LOOP  
  121. 0x78(120): SETUP_LOOP  
  122. 0x79(121): SETUP_EXCEPT  
  123. 0x7A(122): SETUP_FINALLY  
  124. 0x7B(123): <123>  
  125. 0x7C(124): LOAD_FAST  
  126. 0x7D(125): STORE_FAST  
  127. 0x7E(126): DELETE_FAST  
  128. 0x7F(127): <127>  
  129. 0x80(128): <128>  
  130. 0x81(129): <129>  
  131. 0x82(130): RAISE_VARARGS  
  132. 0x83(131): CALL_FUNCTION  
  133. 0x84(132): MAKE_FUNCTION  
  134. 0x85(133): BUILD_SLICE  
  135. 0x86(134): MAKE_CLOSURE  
  136. 0x87(135): LOAD_CLOSURE  
  137. 0x88(136): LOAD_DEREF  
  138. 0x89(137): STORE_DEREF  
  139. 0x8A(138): <138>  
  140. 0x8B(139): <139>  
  141. 0x8C(140): CALL_FUNCTION_VAR  
  142. 0x8D(141): CALL_FUNCTION_KW  
  143. 0x8E(142): CALL_FUNCTION_VAR_KW  
  144. 0x8F(143): EXTENDED_ARG  
  145. 0x90(144): <144>  
  146. 0x91(145): <145>  
  147. 0x92(146): <146>  
  148. 0x93(147): <147>  
  149. 0x94(148): <148>  
  150. 0x95(149): <149>  
  151. 0x96(150): <150>  
  152. 0x97(151): <151>  
  153. 0x98(152): <152>  
  154. 0x99(153): <153>  
  155. 0x9A(154): <154>  
  156. 0x9B(155): <155>  
  157. 0x9C(156): <156>  
  158. 0x9D(157): <157>  
  159. 0x9E(158): <158>  
  160. 0x9F(159): <159>  
  161. 0xA0(160): <160>  
  162. 0xA1(161): <161>  
  163. 0xA2(162): <162>  
  164. 0xA3(163): <163>  
  165. 0xA4(164): <164>  
  166. 0xA5(165): <165>  
  167. 0xA6(166): <166>  
  168. 0xA7(167): <167>  
  169. 0xA8(168): <168>  
  170. 0xA9(169): <169>  
  171. 0xAA(170): <170>  
  172. 0xAB(171): <171>  
  173. 0xAC(172): <172>  
  174. 0xAD(173): <173>  
  175. 0xAE(174): <174>  
  176. 0xAF(175): <175>  
  177. 0xB0(176): <176>  
  178. 0xB1(177): <177>  
  179. 0xB2(178): <178>  
  180. 0xB3(179): <179>  
  181. 0xB4(180): <180>  
  182. 0xB5(181): <181>  
  183. 0xB6(182): <182>  
  184. 0xB7(183): <183>  
  185. 0xB8(184): <184>  
  186. 0xB9(185): <185>  
  187. 0xBA(186): <186>  
  188. 0xBB(187): <187>  
  189. 0xBC(188): <188>  
  190. 0xBD(189): <189>  
  191. 0xBE(190): <190>  
  192. 0xBF(191): <191>  
  193. 0xC0(192): <192>  
  194. 0xC1(193): <193>  
  195. 0xC2(194): <194>  
  196. 0xC3(195): <195>  
  197. 0xC4(196): <196>  
  198. 0xC5(197): <197>  
  199. 0xC6(198): <198>  
  200. 0xC7(199): <199>  
  201. 0xC8(200): <200>  
  202. 0xC9(201): <201>  
  203. 0xCA(202): <202>  
  204. 0xCB(203): <203>  
  205. 0xCC(204): <204>  
  206. 0xCD(205): <205>  
  207. 0xCE(206): <206>  
  208. 0xCF(207): <207>  
  209. 0xD0(208): <208>  
  210. 0xD1(209): <209>  
  211. 0xD2(210): <210>  
  212. 0xD3(211): <211>  
  213. 0xD4(212): <212>  
  214. 0xD5(213): <213>  
  215. 0xD6(214): <214>  
  216. 0xD7(215): <215>  
  217. 0xD8(216): <216>  
  218. 0xD9(217): <217>  
  219. 0xDA(218): <218>  
  220. 0xDB(219): <219>  
  221. 0xDC(220): <220>  
  222. 0xDD(221): <221>  
  223. 0xDE(222): <222>  
  224. 0xDF(223): <223>  
  225. 0xE0(224): <224>  
  226. 0xE1(225): <225>  
  227. 0xE2(226): <226>  
  228. 0xE3(227): <227>  
  229. 0xE4(228): <228>  
  230. 0xE5(229): <229>  
  231. 0xE6(230): <230>  
  232. 0xE7(231): <231>  
  233. 0xE8(232): <232>  
  234. 0xE9(233): <233>  
  235. 0xEA(234): <234>  
  236. 0xEB(235): <235>  
  237. 0xEC(236): <236>  
  238. 0xED(237): <237>  
  239. 0xEE(238): <238>  
  240. 0xEF(239): <239>  
  241. 0xF0(240): <240>  
  242. 0xF1(241): <241>  
  243. 0xF2(242): <242>  
  244. 0xF3(243): <243>  
  245. 0xF4(244): <244>  
  246. 0xF5(245): <245>  
  247. 0xF6(246): <246>  
  248. 0xF7(247): <247>  
  249. 0xF8(248): <248>  
  250. 0xF9(249): <249>  
  251. 0xFA(250): <250>  
  252. 0xFB(251): <251>  
  253. 0xFC(252): <252>  
  254. 0xFD(253): <253>  
  255. 0xFE(254): <254>  
  256. 0xFF(255): <255>  

助记名为“<n>”形式的是未使用的操作码。 

既然叫“字节码”,这些操作码自然是以字节为单位的咯,于是最多只能表示256个不同的操作码。Python实际上只用了百来个操作码。 
操作码小于90的为无参数的,指令仅包含操作码自身,共1字节;大于等于90的,则每条指令在操作码之后还带有1个参数,参数长度为2字节,共3字节。 
Python程序的字节码在运行时以PyStringObject的形式保存在PyCodeObject的co_code域里。co_code域只含有指令而不包含别的程序数据;变量名、常量等数据均放在别的域里。 

Python的字节码指令集是基于栈的指令集。这里说的“栈”不是指函数调用栈,而是指专门用于求值的栈,可以称为“求值栈”(evaluation stack)或者“操作数栈”(operand stack)。求值过程的临时变量都放在求值栈上,指令集中的大部分都是与栈打交道。 
例如3 + 4会变成: 
Python bytecode代码   收藏代码
  1. LOAD_CONST 0 (3)  
  2. LOAT_CONST 1 (4)  
  3. BINARY_ADD  

假设常量池中下标为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>




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值