about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorserpilliere <fabrice.desclaux@cea.fr>2015-07-20 21:59:11 +0200
committerserpilliere <fabrice.desclaux@cea.fr>2015-07-20 21:59:11 +0200
commitbe4fdd14245bfb4a1f69a29dc6f1605679446b78 (patch)
treeb5af11dbaeca4d7ffc10851f179049ec164ca303
parentb6c18b0a1d5246789e39b64688deeddbf80a0b99 (diff)
downloadmiasm-be4fdd14245bfb4a1f69a29dc6f1605679446b78.tar.gz
miasm-be4fdd14245bfb4a1f69a29dc6f1605679446b78.zip
X86/sem: update semantic
-rw-r--r--miasm2/arch/x86/sem.py68
1 files changed, 36 insertions, 32 deletions
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index 4dafc809..6b5ae583 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -620,55 +620,57 @@ def dec(ir, instr, a):
     return e, []
 
 
-def push(ir, instr, a):
+def push_gen(ir, instr, a, size):
     e = []
-    s = instr.mode
-    size = instr.v_opmode()
-    opmode, admode = s, instr.v_admode()
-    # special case segment regs
-    if a in [ES, CS, SS, DS, FS, GS]:
-        off = admode
-    else:
-        off = a.size
-    if not s in [16, 32, 64]:
+    if not size in [16, 32, 64]:
         raise ValueError('bad size stacker!')
-    if isinstance(a, m2_expr.ExprInt):
-        a = m2_expr.ExprInt_fromsize(s, a.arg)
+    if a.size < size:
+        a = a.zeroExtend(size)
+    elif a.size == size:
+        pass
+    else:
+        raise ValueError('strange arg size')
 
-    c = mRSP[instr.mode][:s] - m2_expr.ExprInt_fromsize(s, off / 8)
-    e.append(m2_expr.ExprAff(mRSP[instr.mode][:s], c))
-    # we sub vopmode to stack, but mem access is arg size wide
+    sp = mRSP[instr.mode]
+    new_sp = sp - m2_expr.ExprInt_from(sp, size / 8)
+    e.append(m2_expr.ExprAff(sp, new_sp))
     if ir.do_stk_segm:
-        c = m2_expr.ExprOp('segm', SS, c)
-    e.append(m2_expr.ExprAff(m2_expr.ExprMem(c, a.size), a))
+        new_sp = m2_expr.ExprOp('segm', SS, new_sp)
+    e.append(m2_expr.ExprAff(m2_expr.ExprMem(new_sp, size), a))
     return e, []
 
+def push(ir, instr, a):
+    return push_gen(ir, instr, a, instr.mode)
 
-def pop(ir, instr, a):
+def pushw(ir, instr, a):
+    return push_gen(ir, instr, a, 16)
+
+
+def pop_gen(ir, instr, a, size):
     e = []
-    s = instr.mode
-    size = instr.v_opmode()
-    opmode, admode = s, instr.v_admode()
-    # special case segment regs
-    if a in [ES, CS, SS, DS, FS, GS]:
-        off = admode
-    else:
-        off = a.size
-    if not s in [16, 32, 64]:
+    if not size in [16, 32, 64]:
         raise ValueError('bad size stacker!')
-    new_esp = mRSP[instr.mode][:s] + m2_expr.ExprInt_fromsize(s, off / 8)
+
+    sp = mRSP[instr.mode]
+    new_sp = sp + m2_expr.ExprInt_from(sp, size / 8)
     # don't generate ESP incrementation on POP ESP
     if a != ir.sp:
-        e.append(m2_expr.ExprAff(mRSP[instr.mode][:s], new_esp))
+        e.append(m2_expr.ExprAff(sp, new_sp))
     # XXX FIX XXX for pop [esp]
     if isinstance(a, m2_expr.ExprMem):
-        a = a.replace_expr({mRSP[instr.mode]: new_esp})
-    c = mRSP[instr.mode][:s]
+        a = a.replace_expr({sp: new_sp})
+    c = sp
     if ir.do_stk_segm:
         c = m2_expr.ExprOp('segm', SS, c)
     e.append(m2_expr.ExprAff(a, m2_expr.ExprMem(c, a.size)))
     return e, []
 
+def pop(ir, instr, a):
+    return pop_gen(ir, instr, a, instr.mode)
+
+def popw(ir, instr, a):
+    return pop_gen(ir, instr, a, 16)
+
 
 def sete(ir, instr, a):
     e = []
@@ -944,7 +946,7 @@ def pushfd(ir, instr):
 
 
 def pushfw(ir, instr):
-    return push(ir, instr, compose_eflag(16))
+    return pushw(ir, instr, compose_eflag(16))
 
 
 def popfd(ir, instr):
@@ -3175,7 +3177,9 @@ mnemo_func = {'mov': mov,
               'inc': inc,
               'dec': dec,
               'push': push,
+              'pushw': pushw,
               'pop': pop,
+              'popw': popw,
               'sete': sete,
               'setnz': setnz,
               'setl': setl,