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

📄 dasm_x86.lua

📁 采用C语言写的Lua的解释器的代码!Lua不用介绍了吧
💻 LUA
📖 第 1 页 / 共 4 页
字号:
      wputmodrm(t.xsc, t.xreg, 5)    else      -- Pure displacement.      wputmodrm(0, s, 5) -- [disp] -> (0, s, ebp)    end    wputdarg(disp)    return  end  local m  if tdisp == "number" then -- Check displacement size at assembly time.    if disp == 0 and t.reg ~= 5 then m = 0  -- [ebp] -> [ebp+0] (in SIB, too)    elseif disp >= -128 and disp <= 127 then m = 1    else m = 2 end  elseif tdisp == "table" then    m = 2  end  -- Index register present or esp as base register: need SIB encoding.  if t.xreg or t.reg == 4 then    wputmodrm(m or 2, s, 4) -- ModRM.    if (m == nil or imark) and tdisp ~= "table" then waction("MARK") end    wputmodrm(t.xsc or 0, t.xreg or 4, t.reg) -- SIB.  else    wputmodrm(m or 2, s, t.reg) -- ModRM.    if imark and (m == 1 or m == 2) then waction("MARK") end  end  -- Put displacement.  if m == 1 then wputsbarg(disp)  elseif m == 2 then wputdarg(disp)  elseif not m then waction("DISP", disp) endend-------------------------------------------------------------------------------- Return human-readable operand mode string.local function opmodestr(op, args)  local m = {}  for i=1,#args do    local a = args[i]    m[#m+1] = sub(a.mode, 1, 1)..(a.opsize or "?")  end  return op.." "..concat(m, ",")end-- Convert number to valid integer or nil.local function toint(expr)  local n = tonumber(expr)  if n then    if n % 1 ~= 0 or n < -2147483648 or n > 4294967295 then      werror("bad integer number `"..expr.."'")    end    return n  endend-- Parse immediate expression.local function immexpr(expr)  -- &expr (pointer)  if sub(expr, 1, 1) == "&" then    return "iPJ", format("(ptrdiff_t)(%s)", sub(expr,2))  end  local prefix = sub(expr, 1, 2)  -- =>expr (pc label reference)  if prefix == "=>" then    return "iJ", sub(expr, 3)  end  -- ->name (global label reference)  if prefix == "->" then    return "iJ", map_global[sub(expr, 3)]  end  -- [<>][1-9] (local label reference)  local dir, lnum = match(expr, "^([<>])([1-9])$")  if dir then -- Fwd: 247-255, Bkwd: 1-9.    return "iJ", lnum + (dir == ">" and 246 or 0)  end  -- expr (interpreted as immediate)  return "iI", exprend-- Parse displacement expression: +-num, +-expr, +-opsize*numlocal function dispexpr(expr)  local disp = expr == "" and 0 or toint(expr)  if disp then return disp end  local c, dispt = match(expr, "^([+-])%s*(.+)$")  if c == "+" then    expr = dispt  elseif not c then    werror("bad displacement expression `"..expr.."'")  end  local opsize, tailops = match(dispt, "^(%w+)%s*%*%s*(.+)$")  local ops, imm = map_opsize[opsize], toint(tailops)  if ops and imm then    if c == "-" then imm = -imm end    return imm*map_opsizenum[ops]  end  local mode, iexpr = immexpr(dispt)  if mode == "iJ" then    if c == "-" then werror("cannot invert label reference") end    return { iexpr }  end  return expr -- Need to return original signed expression.end-- Parse register or type expression.local function rtexpr(expr)  if not expr then return end  local tname, ovreg = match(expr, "^([%w_]+):(@[%w_]+)$")  local tp = map_type[tname or expr]  if tp then    local reg = ovreg or tp.reg    local rnum = map_reg_num[reg]    if not rnum then      werror("type `"..(tname or expr).."' needs a register override")    end    if not map_reg_valid_base[reg] then      werror("bad base register override `"..(map_reg_rev[reg] or reg).."'")    end    return reg, rnum, tp  end  return expr, map_reg_num[expr]end-- Parse operand and return { mode, opsize, reg, xreg, xsc, disp, imm }.local function parseoperand(param)  local t = {}  local expr = param  local opsize, tailops = match(param, "^(%w+)%s*(.+)$")  if opsize then    t.opsize = map_opsize[opsize]    if t.opsize then expr = tailops end  end  local br = match(expr, "^%[%s*(.-)%s*%]$")  repeat    if br then      t.mode = "xm"      -- [disp]      t.disp = toint(br)      if t.disp then	t.mode = "xmO"	break      end      -- [reg...]      local tp      local reg, tailr = match(br, "^([@%w_:]+)%s*(.*)$")      reg, t.reg, tp = rtexpr(reg)      if not t.reg then	-- [expr]	t.mode = "xmO"	t.disp = dispexpr("+"..br)	break      end      -- [xreg*xsc] or [xreg*xsc+-disp] or [xreg*xsc+-expr]      local xsc, tailsc = match(tailr, "^%*%s*([1248])%s*(.*)$")      if xsc then	if not map_reg_valid_index[reg] then	  werror("bad index register `"..map_reg_rev[reg].."'")	end	t.xsc = map_xsc[xsc]	t.xreg = t.reg	t.reg = nil	t.disp = dispexpr(tailsc)	break      end      if not map_reg_valid_base[reg] then	werror("bad base register `"..map_reg_rev[reg].."'")      end      -- [reg] or [reg+-disp]      t.disp = toint(tailr) or (tailr == "" and 0)      if t.disp then break end      -- [reg+xreg...]      local xreg, tailx = match(tailr, "^+%s*([@%w_:]+)%s*(.*)$")      xreg, t.xreg, tp = rtexpr(xreg)      if not t.xreg then	-- [reg+-expr]	t.disp = dispexpr(tailr)	break      end      if not map_reg_valid_index[xreg] then	werror("bad index register `"..map_reg_rev[xreg].."'")      end      -- [reg+xreg*xsc...]      local xsc, tailsc = match(tailx, "^%*%s*([1248])%s*(.*)$")      if xsc then	t.xsc = map_xsc[xsc]	tailx = tailsc      end      -- [...] or [...+-disp] or [...+-expr]      t.disp = dispexpr(tailx)    else      -- imm or opsize*imm      local imm = toint(expr)      if not imm and sub(expr, 1, 1) == "*" and t.opsize then	imm = toint(sub(expr, 2))	if imm then	  imm = imm * map_opsizenum[t.opsize]	  t.opsize = nil	end      end      if imm then	if t.opsize then werror("bad operand size override") end	local m = "i"	if imm == 1 then m = m.."1" end	if imm >= 4294967168 and imm <= 4294967295 then imm = imm-4294967296 end	if imm >= -128 and imm <= 127 then m = m.."S" end	t.imm = imm	t.mode = m	break      end      local tp      local reg, tailr = match(expr, "^([@%w_:]+)%s*(.*)$")      reg, t.reg, tp = rtexpr(reg)      if t.reg then	-- reg	if tailr == "" then	  if t.opsize then werror("bad operand size override") end	  t.opsize = map_reg_opsize[reg]	  if t.opsize == "f" then	    t.mode = t.reg == 0 and "fF" or "f"	  else	    if reg == "@w4" then wwarn("bad idea, try again with `esp'") end	    t.mode = t.reg == 0 and "rmR" or (reg == "@b1" and "rmC" or "rm")	  end	  break	end	-- type[idx], type[idx].field, type->field -> [reg+offset_expr]	if not tp then werror("bad operand `"..param.."'") end	t.mode = "xm"	t.disp = format(tp.ctypefmt, tailr)      else	t.mode, t.imm = immexpr(expr)	if sub(t.mode, -1) == "J" then	  if t.opsize and t.opsize ~= addrsize then	    werror("bad operand size override")	  end	  t.opsize = addrsize	end      end    end  until true  return tend-------------------------------------------------------------------------------- x86 Template String Description-- ===============================---- Each template string is a list of [match:]pattern pairs,-- separated by "|". The first match wins. No match means a-- bad or unsupported combination of operand modes or sizes.---- The match part and the ":" is omitted if the operation has-- no operands. Otherwise the first N characters are matched-- against the mode strings of each of the N operands.---- The mode string for each operand type is (see parseoperand()):--   Integer register: "rm", +"R" for eax, ax, al, +"C" for cl--   FP register:      "f",  +"F" for st0--   Index operand:    "xm", +"O" for [disp] (pure offset)--   Immediate:        "i",  +"S" for signed 8 bit, +"1" for 1,--                     +"I" for arg, +"P" for pointer--   Any:              +"J" for valid jump targets---- So a match character "m" (mixed) matches both an integer register-- and an index operand (to be encoded with the ModRM/SIB scheme).-- But "r" matches only a register and "x" only an index operand-- (e.g. for FP memory access operations).---- The operand size match string starts right after the mode match-- characters and ends before the ":". "dwb" is assumed, if empty.-- The effective data size of the operation is matched against this list.---- If only the regular "b", "w", "d", "q", "t" operand sizes are-- present, then all operands must be the same size. Unspecified sizes-- are ignored, but at least one operand must have a size or the pattern-- won't match (use the "byte", "word", "dword", "qword", "tword"-- operand size overrides. E.g.: mov dword [eax], 1).---- If the list has a "1" or "2" prefix, the operand size is taken-- from the respective operand and any other operand sizes are ignored.-- If the list contains only ".", all operand sizes are ignored.-- If the list has a "/" prefix, the concatenated (mixed) operand sizes-- are compared to the match.---- E.g. "rrdw" matches for either two dword registers or two word-- registers. "Fx2dq" matches an st0 operand plus an index operand-- pointing to a dword (float) or qword (double).---- Every character after the ":" is part of the pattern string:--   Hex chars are accumulated to form the opcode (left to right).--   "n"       disables the standard opcode mods--             (otherwise: -1 for "b", o16 prefix for "w")--   "r"/"R"   adds the reg. number from the 1st/2nd operand to the opcode.--   "m"/"M"   generates ModRM/SIB from the 1st/2nd operand.--             The spare 3 bits are either filled with the last hex digit or--             the result from a previous "r"/"R". The opcode is restored.---- All of the following characters force a flush of the opcode:--   "o"/"O"   stores a pure 32 bit disp (offset) from the 1st/2nd operand.--   "S"       stores a signed 8 bit immediate from the last operand.--   "U"       stores an unsigned 8 bit immediate from the last operand.--   "W"       stores an unsigned 16 bit immediate from the last operand.--   "i"       stores an operand sized immediate from the last operand.--   "I"       dito, but generates an action code to optionally modify--             the opcode (+2) for a signed 8 bit immediate.--   "J"       generates one of the REL action codes from the last operand.---------------------------------------------------------------------------------- Template strings for x86 instructions. Ordered by first opcode byte.-- Unimplemented opcodes (deliberate omissions) are marked with *.local map_op = {  -- 00-05: add...  -- 06: *push es  -- 07: *pop es  -- 08-0D: or...  -- 0E: *push cs  -- 0F: two byte opcode prefix  -- 10-15: adc...  -- 16: *push ss  -- 17: *pop ss  -- 18-1D: sbb...  -- 1E: *push ds  -- 1F: *pop ds  -- 20-25: and...  es_0 =	"26",  -- 27: *daa  -- 28-2D: sub...  cs_0 =	"2E",  -- 2F: *das  -- 30-35: xor...  ss_0 =	"36",  -- 37: *aaa  -- 38-3D: cmp...  ds_0 =	"3E",  -- 3F: *aas  inc_1 =	"rdw:40r|m:FF0m",  dec_1 =	"rdw:48r|m:FF1m",  push_1 =	"rdw:50r|mdw:FF6m|S.:6AS|ib:n6Ai|i.:68i",  pop_1 =	"rdw:58r|mdw:8F0m",  -- 60: *pusha, *pushad, *pushaw  -- 61: *popa, *popad, *popaw  -- 62: *bound rdw,x  -- 63: *arpl mw,rw  fs_0 =	"64",  gs_0 =	"65",  o16_0 =	"66",  a16_0 =	"67",  -- 68: push idw  -- 69: imul rdw,mdw,idw  -- 6A: push ib  -- 6B: imul rdw,mdw,S  -- 6C: *insb  -- 6D: *insd, *insw  -- 6E: *outsb  -- 6F: *outsd, *outsw  -- 70-7F: jcc lb  -- 80: add... mb,i  -- 81: add... mdw,i  -- 82: *undefined  -- 83: add... mdw,S  test_2 =	"mr:85Rm|rm:85rM|Ri:A9i|mi:F70mi",  -- 86: xchg rb,mb  -- 87: xchg rdw,mdw  -- 88: mov mb,r  -- 89: mov mdw,r  -- 8A: mov r,mb  -- 8B: mov r,mdw  -- 8C: *mov mdw,seg  lea_2 =	"rxd:8DrM",  -- 8E: *mov seg,mdw  -- 8F: pop mdw  nop_0 =	"90",  xchg_2 =	"Rrdw:90R|rRdw:90r|rm:87rM|mr:87Rm",  cbw_0 =	"6698",  cwde_0 =	"98",  cwd_0 =	"6699",  cdq_0 =	"99",  -- 9A: *call iw:idw  wait_0 =	"9B",  fwait_0 =	"9B",

⌨️ 快捷键说明

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