without warning include machine.e constant eax=#BEEF90, ecx = eax + 1, edx = eax + 2, ebx = eax + 3, esp = eax + 4, ebp = eax + 5, esi = eax + 6, edi = eax + 7 constant operands = { eax,eax*2,eax*4,eax*8, ecx,ecx*2,ecx*4,ecx*8, edx,edx*2,edx*4,edx*8, ebx,ebx*2,ebx*4,ebx*8, ebp,ebp*2,ebp*4,ebp*8, esi,esi*2,esi*4,esi*8, edi,edi*2,edi*4,edi*8, esp} with trace function modrm(integer mod, sequence rm) -- rm can be {eax}, {eax,ebx}, {eax,ebx*4,5}, {ebx*4}, {ebx*4,5}, or {5} integer reg1, reg2, scale, disp, e sequence regs, result reg1 = 0 reg2 = 0 scale = 0 disp = 0 for i = 1 to length(rm) do e = find(rm[i], operands) if rm[i] = esp then if reg1 = 0 and reg2 = 0 then reg1 = esp reg2 = esp else puts(2, "modrm: Warning! esp must be alone in effective address\n") end if elsif e then if and_bits(e, 3) = 1 and reg1 = 0 then reg1 = rm[i] elsif reg2 = 0 then scale = and_bits(e-1,3) reg2 = rm[i] / power(2,scale) else puts(2, "modrm: Warning! Too many registers in effective address\n") end if else disp += rm[i] end if end for if reg2 then result = {mod*8 + 4, scale*#40 + and_bits(reg1,7) + 8*and_bits(reg2,7)} else result = {mod*8 + and_bits(reg1,7)} end if if disp = 0 and reg1 != ebp then elsif reg1 = 0 then result[length(result)] += 5 result &= int_to_bytes(disp) elsif disp <= 127 and disp >= -128 then result[1] += #40 result &= disp else result[1] += #80 result &= int_to_bytes(disp) end if return result end function function add(object dst, object src) if atom(dst) then if dst >= eax and dst <= edi then dst = and_bits(dst, 7) if atom(src) then if src >= eax and src <= edi then -- mov reg, reg return {#89, #C0 + dst + 8*and_bits(src, 7)} else -- mov reg, immediate return (#B8 + dst) & int_to_bytes(src) end if else -- mov reg, memory expression return #8B & modrm(dst, src) end if else -- mov immediate, ... end if else if atom(src) then if src >= eax and src <= edi then -- mov memory expression, register return #89 & modrm(and_bits(src,7), dst) else -- mov memory expression, immediate return #C7 & modrm(0, dst) & int_to_bytes(src) end if else -- mov mem, mem end if end if puts(1, "mov: Not a valid combination of operands\n") end function function mov (object dst, object src) if atom(dst) then if dst >= eax and dst <= edi then dst = and_bits(dst, 7) if atom(src) then if src >= eax and src <= edi then -- mov reg, reg return {#89, #C0 + dst + 8*and_bits(src, 7)} else -- mov reg, immediate return (#B8 + dst) & int_to_bytes(src) end if elsif dst=0 and length(src) = 1 and not find(src[1], operands) then -- mov eax, mem return #A1 & int_to_bytes(src[1]) else -- mov reg, memory expression return #8B & modrm(dst, src) end if else -- mov immediate, ... end if else if atom(src) then if src=eax and length(dst) = 1 and not find(dst[1], operands) then -- mov mem, eax return #A3 & int_to_bytes(dst[1]) elsif src >= eax and src <= edi then -- mov memory expression, register return #89 & modrm(and_bits(src,7), dst) else -- mov memory expression, immediate return #C7 & modrm(0, dst) & int_to_bytes(src) end if else -- mov mem, mem end if end if puts(1, "mov: Not a valid combination of operands\n") end function function autosize(object word, object byte, integer i) if i < -128 or i > 127 then return word & int_to_bytes(i) else return byte & i end if end function function push_dword(atom i) return #68 & int_to_bytes(i) end function function push_mem(atom i) return {#FF,#35}&int_to_bytes(i) end function function push_stk(atom i) return #FF&autosize({#B4,#24},{#74,24},i) end function function add_esp(integer i) return autosize({#81,#C4},{#83,#C4},i) end function function mov_eax(atom i) return #B8 & int_to_bytes(i) end function function mov_eax_stk(atom i) return #8B&autosize({#84,#24},{#44,#24},i) end function function mov_stk_eax(atom i) return #89&autosize({#84,#24},{#44,#24},i) end function function mov_eax_mem(atom i) return #A3 & int_to_bytes(i) end function function mov_mem_eax(atom i) return #A1 & int_to_bytes(i) end function function push_at_ebp(integer p) return #FF & autosize(#B5,#75,p) end function function mov_at_ebp(integer p, atom i) return #C7 & autosize(#85,#45,p) & int_to_bytes(i) end function constant ASSIGN=1, POKE4=2, PEEK4=3, ADDTO=4, CALLPROC=5, ASSIGNFUNC=6, RETURN=7, WHILE=8, IF=9 function hex(object s) sequence result if sequence(s) then result = "" for i=1 to length(s) do if i > 1 then result &= "," end if result &= hex(s[i]) end for return "{"&result&"}" elsif s>=0 and s<=255 then return sprintf("#%02x",{s}) end if return sprintf("#%08x",{s}) end function include asm.e asm_output(1,1) --? get_asm("mov dword ptr [64], eax") ? get_asm("add eax, 500") puts(1, " "&hex(add(eax,{500})))