⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dasm_x86.lua

📁 采用C语言写的Lua的解释器的代码!Lua不用介绍了吧
💻 LUA
📖 第 1 页 / 共 4 页
字号:
    map_op[fn.."p_1"] = format("ff:DE%02Xr", nr)    map_op[fn.."p_2"] = format("fFf:DE%02Xr", nr)  end  map_op["fi"..name.."_1"] = format("xd:DA%Xm|xw:nDE%Xm", n, n)end-- FP conditional moves.for cc,n in pairs{ b=0, e=1, be=2, u=3, nb=4, ne=5, nbe=6, nu=7 } do  local n4 = n % 4  local nc = 56000 + n4 * 8 + (n-n4) * 64  map_op["fcmov"..cc.."_1"] = format("ff:%04Xr", nc) -- P6+  map_op["fcmov"..cc.."_2"] = format("Fff:%04XR", nc) -- P6+end-- SSE FP arithmetic ops.for name,n in pairs{ sqrt = 1, add = 8, mul = 9,		     sub = 12, min = 13, div = 14, max = 15 } do  map_op[name.."ps_2"] = format("rmo:0F5%XrM", n)  map_op[name.."ss_2"] = format("rro:F30F5%XrM|rx/od:", n)  map_op[name.."pd_2"] = format("rmo:660F5%XrM", n)  map_op[name.."sd_2"] = format("rro:F20F5%XrM|rx/oq:", n)end-------------------------------------------------------------------------------- Process pattern string.local function dopattern(pat, args, sz, op)  local digit, addin  local opcode = 0  local szov = sz  -- Limit number of section buffer positions used by a single dasm_put().  -- A single opcode needs a maximum of 2 positions. !x64  if secpos+2 > maxsecpos then wflush() end  -- Process each character.  for c in gmatch(pat, ".") do    if match(c, "%x") then	-- Hex digit.      digit = byte(c) - 48      if digit > 48 then digit = digit - 39      elseif digit > 16 then digit = digit - 7 end      opcode = opcode*16 + digit      addin = nil    elseif c == "n" then	-- Disable operand size mods for opcode.      szov = nil    elseif c == "r" then	-- Merge 1st operand regno. into opcode.      addin = args[1].reg; opcode = opcode + addin    elseif c == "R" then	-- Merge 2nd operand regno. into opcode.      addin = args[2].reg; opcode = opcode + addin    elseif c == "m" or c == "M" then	-- Encode ModRM/SIB.      if addin then	opcode = opcode - addin		-- Undo regno opcode merge.      else	addin = opcode % 16		-- Undo last digit.	opcode = (opcode - addin) / 16      end      wputop(szov, opcode); opcode = nil      local imark = (sub(pat, -1) == "I") -- Force a mark (ugly).      -- Put ModRM/SIB with regno/last digit as spare.      wputmrmsib(args[c == "m" and 1 or 2], addin, imark)    else      if opcode then wputop(szov, opcode); opcode = nil end -- Flush opcode.      if c == "o" or c == "O" then	-- Offset (pure 32 bit displacement).	wputdarg(args[c == "o" and 1 or 2].disp)      else	-- Anything else is an immediate operand.	local a = args[#args]	local mode, imm = a.mode, a.imm	if mode == "iJ" and not match("iIJ", c) then	  werror("bad operand size for label")	end	if c == "S" then	  wputsbarg(imm)	elseif c == "U" then	  wputbarg(imm)	elseif c == "W" then	  wputwarg(imm)	elseif c == "i" or c == "I" then	  if mode == "iJ" then	    wputlabel("IMM_", imm, 1)	  elseif mode == "iI" and c == "I" then	    waction(sz == "w" and "IMM_WB" or "IMM_DB", imm)	  else	    wputszarg(sz, imm)	  end	elseif c == "J" then	  if mode == "iPJ" then	    waction("REL_A", imm) -- !x64 (secpos)	  else	    wputlabel("REL_", imm, 2)	  end	else	  werror("bad char `"..c.."' in pattern `"..pat.."' for `"..op.."'")	end      end    end  end  if opcode then wputop(szov, opcode) endend-------------------------------------------------------------------------------- Mapping of operand modes to short names. Suppress output with '#'.local map_modename = {  r = "reg", R = "eax", C = "cl", x = "mem", m = "mrm", i = "imm",  f = "stx", F = "st0", J = "lbl", ["1"] = "1",  I = "#", S = "#", O = "#",}-- Return a table/string showing all possible operand modes.local function templatehelp(template, nparams)  if nparams == 0 then return "" end  local t = {}  for tm in gmatch(template, "[^%|]+") do    local s = map_modename[sub(tm, 1, 1)]    s = s..gsub(sub(tm, 2, nparams), ".", function(c)      return ", "..map_modename[c]    end)    if not match(s, "#") then t[#t+1] = s end  end  return tend-- Match operand modes against mode match part of template.local function matchtm(tm, args)  for i=1,#args do    if not match(args[i].mode, sub(tm, i, i)) then return end  end  return trueend-- Handle opcodes defined with template strings.map_op[".template__"] = function(params, template, nparams)  if not params then return templatehelp(template, nparams) end  local args = {}  -- Zero-operand opcodes have no match part.  if #params == 0 then    dopattern(template, args, "d", params.op)    return  end  -- Determine common operand size (coerce undefined size) or flag as mixed.  local sz, szmix  for i,p in ipairs(params) do    args[i] = parseoperand(p)    local nsz = args[i].opsize    if nsz then      if sz and sz ~= nsz then szmix = true else sz = nsz end    end  end  -- Try all match:pattern pairs (separated by '|').  local gotmatch, lastpat  for tm in gmatch(template, "[^%|]+") do    -- Split off size match (starts after mode match) and pattern string.    local szm, pat = match(tm, "^(.-):(.*)$", #args+1)    if pat == "" then pat = lastpat else lastpat = pat end    if matchtm(tm, args) then      local prefix = sub(szm, 1, 1)      if prefix == "/" then -- Match both operand sizes.	if args[1].opsize == sub(szm, 2, 2) and	   args[2].opsize == sub(szm, 3, 3) then	  dopattern(pat, args, sz, params.op) -- Process pattern string.	  return	end      else -- Match common operand size.	local szp = sz	if szm == "" then szm = "dwb" end -- Default size match.	if prefix == "1" then szp = args[1].opsize; szmix = nil	elseif prefix == "2" then szp = args[2].opsize; szmix = nil end	if not szmix and (prefix == "." or match(szm, szp or "#")) then	  dopattern(pat, args, szp, params.op) -- Process pattern string.	  return	end      end      gotmatch = true    end  end  local msg = "bad operand mode"  if gotmatch then    if szmix then      msg = "mixed operand size"    else      msg = sz and "bad operand size" or "missing operand size"    end  end  werror(msg.." in `"..opmodestr(params.op, args).."'")end-------------------------------------------------------------------------------- Pseudo-opcodes for data storage.local function op_data(params)  if not params then return "imm..." end  local sz = sub(params.op, 2, 2)  if sz == "a" then sz = addrsize end  for _,p in ipairs(params) do    local a = parseoperand(p)    if sub(a.mode, 1, 1) ~= "i" or (a.opsize and a.opsize ~= sz) then      werror("bad mode or size in `"..p.."'")    end    if a.mode == "iJ" then      wputlabel("IMM_", a.imm, 1)    else      wputszarg(sz, a.imm)    end  endendmap_op[".byte_*"] = op_datamap_op[".sbyte_*"] = op_datamap_op[".word_*"] = op_datamap_op[".dword_*"] = op_datamap_op[".aword_*"] = op_data-------------------------------------------------------------------------------- Pseudo-opcode to mark the position where the action list is to be emitted.map_op[".actionlist_1"] = function(params)  if not params then return "cvar" end  local name = params[1] -- No syntax check. You get to keep the pieces.  wline(function(out) writeactions(out, name) end)end-- Pseudo-opcode to mark the position where the global enum is to be emitted.map_op[".globals_1"] = function(params)  if not params then return "prefix" end  local prefix = params[1] -- No syntax check. You get to keep the pieces.  wline(function(out) writeglobals(out, prefix) end)end-------------------------------------------------------------------------------- Label pseudo-opcode (converted from trailing colon form).map_op[".label_2"] = function(params)  if not params then return "[1-9] | ->global | =>pcexpr  [, addr]" end  local a = parseoperand(params[1])  local mode, imm = a.mode, a.imm  if type(imm) == "number" and (mode == "iJ" or (imm >= 1 and imm <= 9)) then    -- Local label (1: ... 9:) or global label (->global:).    waction("LABEL_LG", nil, 1)    wputxb(imm)  elseif mode == "iJ" then    -- PC label (=>pcexpr:).    waction("LABEL_PC", imm)  else    werror("bad label definition")  end  -- SETLABEL must immediately follow LABEL_LG/LABEL_PC.  local addr = params[2]  if addr then    local a = parseoperand(params[2])    if a.mode == "iPJ" then      waction("SETLABEL", a.imm) -- !x64 (secpos)    else      werror("bad label assignment")    end  endendmap_op[".label_1"] = map_op[".label_2"]-------------------------------------------------------------------------------- Alignment pseudo-opcode.map_op[".align_1"] = function(params)  if not params then return "numpow2" end  local align = tonumber(params[1]) or map_opsizenum[map_opsize[params[1]]]  if align then    local x = align    -- Must be a power of 2 in the range (2 ... 256).    for i=1,8 do      x = x / 2      if x == 1 then	waction("ALIGN", nil, 1)	wputxb(align-1) -- Action byte is 2**n-1.	return      end    end  end  werror("bad alignment")end-- Spacing pseudo-opcode.map_op[".space_2"] = function(params)  if not params then return "num [, filler]" end  waction("SPACE", params[1])  local fill = params[2]  if fill then    fill = tonumber(fill)    if not fill or fill < 0 or fill > 255 then werror("bad filler") end  end  wputxb(fill or 0)endmap_op[".space_1"] = map_op[".space_2"]-------------------------------------------------------------------------------- Pseudo-opcode for (primitive) type definitions (map to C types).map_op[".type_3"] = function(params, nparams)  if not params then    return nparams == 2 and "name, ctype" or "name, ctype, reg"  end  local name, ctype, reg = params[1], params[2], params[3]  if not match(name, "^[%a_][%w_]*$") then    werror("bad type name `"..name.."'")  end  local tp = map_type[name]  if tp then    werror("duplicate type `"..name.."'")  end  if reg and not map_reg_valid_base[reg] then    werror("bad base register `"..(map_reg_rev[reg] or reg).."'")  end  -- Add #type to defines. A bit unclean to put it in map_archdef.  map_archdef["#"..name] = "sizeof("..ctype..")"  -- Add new type and emit shortcut define.  local num = ctypenum + 1  map_type[name] = {    ctype = ctype,    ctypefmt = format("Dt%X(%%s)", num),    reg = reg,  }  wline(format("#define Dt%X(_V) (int)&(((%s *)0)_V)", num, ctype))  ctypenum = numendmap_op[".type_2"] = map_op[".type_3"]-- Dump type definitions.local function dumptypes(out, lvl)  local t = {}  for name in pairs(map_type) do t[#t+1] = name end  sort(t)  out:write("Type definitions:\n")  for _,name in ipairs(t) do    local tp = map_type[name]    local reg = tp.reg and map_reg_rev[tp.reg] or ""    out:write(format("  %-20s %-20s %s\n", name, tp.ctype, reg))  end  out:write("\n")end-------------------------------------------------------------------------------- Set the current section.function _M.section(num)  waction("SECTION")  wputxb(num)  wflush(true) -- SECTION is a terminal action.end-------------------------------------------------------------------------------- Dump architecture description.function _M.dumparch(out)  out:write(format("DynASM %s version %s, released %s\n\n",    _info.arch, _info.version, _info.release))  dumpregs(out)  dumpactions(out)end-- Dump all user defined elements.function _M.dumpdef(out, lvl)  dumptypes(out, lvl)  dumpglobals(out, lvl)end-------------------------------------------------------------------------------- Pass callbacks from/to the DynASM core.function _M.passcb(wl, we, wf, ww)  wline, werror, wfatal, wwarn = wl, we, wf, ww  return wflushend-- Setup the arch-specific module.function _M.setup(arch, opt)  g_arch, g_opt = arch, optend-- Merge the core maps and the arch-specific maps.function _M.mergemaps(map_coreop, map_def)  setmetatable(map_op, { __index = map_coreop })  setmetatable(map_def, { __index = map_archdef })  return map_op, map_defendreturn _M------------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -