📄 dynasm_examples.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html><head><title>DynASM Examples</title><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"><meta name="Author" content="Mike Pall"><meta name="Copyright" content="Copyright (C) 2005-2007, Mike Pall"><meta name="Language" content="en"><link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"><link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"></head><body><div id="site"><a href="http://luajit.org/"><span>Lua<span id="logo">JIT</span></span></a></div><div id="head"><h1>DynASM Examples</h1></div><div id="nav"><ul><li><a href="index.html">Index</a></li><li><a href="luajit.html">LuaJIT</a><ul><li><a href="luajit_features.html">Features</a></li><li><a href="luajit_install.html">Installation</a></li><li><a href="luajit_run.html">Running</a></li><li><a href="luajit_api.html">API Extensions</a></li><li><a href="luajit_intro.html">Introduction</a></li><li><a href="luajit_performance.html">Performance</a></li><li><a href="luajit_debug.html">Debugging</a></li><li><a href="luajit_changes.html">Changes</a></li></ul></li><li><a href="coco.html">Coco</a><ul><li><a href="coco_portability.html">Portability</a></li><li><a href="coco_api.html">API Extensions</a></li><li><a href="coco_changes.html">Changes</a></li></ul></li><li><a href="dynasm.html">DynASM</a><ul><li><a href="dynasm_features.html">Features</a></li><li><a class="current" href="dynasm_examples.html">Examples</a></li></ul></li><li><a href="http://luajit.org/download.html">Download <span class="ext">»</span></a></li></ul></div><div id="main"><h2>A Simple Example</h2><p>To get you started, here is a simple code snippet to be pre-processed.The lines starting with '|' (the pipe symbol) are for DynASM:</p><pre> if (ptr != NULL) { | mov eax, foo+17 | mov edx, [eax+esi*2+0x20] | add ebx, [ecx+bar(ptr, 9)] }</pre><p>After pre-processing you get:</p><pre> if (ptr != NULL) { dasm_put(Dst, 123, foo+17, bar(ptr, 9)); }</pre><p style="font-size: 80%;">Note: yes, you usually get the assembler code as comments and properCPP directives to match them up with the source. I've omittedthem here for clarity. Oh and BTW: the pipe symbols probablyline up much more nicely in your editor than in a browser.</p><p>Here 123 is an offset into the action list buffer thatholds the partially specified machine code. Without goinginto too much detail, the embedded C library implements atiny bytecode engine that takes the action list as input andoutputs machine code. It basically copies machine code snippetsfrom the action list and merges them with the argumentspassed in by <tt>dasm_put()</tt>.</p><p>The arguments can be any kind of C expressions. In practicaluse most of them evaluate to constants (e.g. structure offsets).Your C compiler should generate very compact code out of it.</p><p>The embedded C library knows only what's absolutely needed togenerate proper machine code for the target CPU (e.g. variabledisplacement sizes, variable branch offset sizes and so on).It doesn't have a clue about other atrocities like x86 opcodeencodings — and it doesn't need to. This dramaticallyreduces the minimum required code size to around 2K [sic!].</p><p>The action list buffer itself has a pretty compact encoding, too.E.g. the whole action list buffer for an early version of LuaJITneeds only around 3K.</p><h2>Advanced Features</h2><p>Here's a real-life example taken from LuaJIT that shows someadvanced features like type maps, macros and how to accessC structures:</p><pre>|.type L, lua_State, esi // L.|.type BASE, TValue, ebx // L->base.|.type TOP, TValue, edi // L->top.|.type CI, CallInfo, ecx // L->ci.|.type LCL, LClosure, eax // L->ci->func->value.|.type UPVAL, UpVal|.macro copyslot, D, S, R1, R2, R3| mov R1, S.value; mov R2, S.value.na[1]; mov R3, S.tt| mov D.value, R1; mov D.value.na[1], R2; mov D.tt, R3|.endmacro|.macro copyslot, D, S; copyslot D, S, ecx, edx, eax; .endmacro|.macro getLCL, reg||if (!J->pt->is_vararg) {| mov LCL:reg, BASE[-1].value||} else {| mov CI, L->ci| mov TOP, CI->func| mov LCL:reg, TOP->value||}|.endmacro|.macro getLCL; getLCL eax; .endmacro[...]static void jit_op_getupval(jit_State *J, int dest, int uvidx){ | getLCL | mov UPVAL:ecx, LCL->upvals[uvidx] | mov TOP, UPVAL:ecx->v | copyslot BASE[dest], TOP[0]}</pre><p>And here is the pre-processed output (stripped a bit for clarity):</p><pre>#define Dt1(_V) (int)&(((lua_State *)0)_V)[...]static void jit_op_getupval(jit_State *J, int dest, int uvidx){ if (!J->pt->is_vararg) { dasm_put(Dst, 1164, Dt2([-1].value)); } else { dasm_put(Dst, 1168, Dt1(->ci), Dt4(->func), Dt3(->value)); } dasm_put(Dst, 1178, Dt5(->upvals[uvidx]), DtF(->v), Dt3([0].value), Dt3([0].value.na[1]), Dt3([0].tt), Dt2([dest].value), Dt2([dest].value.na[1]), Dt2([dest].tt));}</pre><br class="flush"></div><div id="foot"><hr class="hide">Copyright © 2005-2007 Mike Pall<span class="noprint">·<a href="contact.html">Contact</a></span></div></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -