about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorCamille Mougey <commial@gmail.com>2015-07-21 12:54:09 +0200
committerCamille Mougey <commial@gmail.com>2015-07-21 12:54:09 +0200
commit97463558ea31744a24e3330ab3227e2098878d03 (patch)
tree480e2af9a1f30c027b07c8feb2889eb8bed01a77
parente82d888243fc5f283e7a3d5b12e5cefaf950edc5 (diff)
parent2ff7161eaba5da7845c69be28e8092f030b94bed (diff)
downloadmiasm-97463558ea31744a24e3330ab3227e2098878d03.tar.gz
miasm-97463558ea31744a24e3330ab3227e2098878d03.zip
Merge pull request #196 from serpilliere/fix_pushw
Fix pushw
-rw-r--r--miasm2/arch/x86/arch.py73
-rw-r--r--miasm2/arch/x86/sem.py68
-rw-r--r--test/arch/x86/arch.py66
-rw-r--r--test/arch/x86/unit/mn_stack.py60
-rw-r--r--test/test_all.py1
5 files changed, 213 insertions, 55 deletions
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py
index 33fd428f..f966c860 100644
--- a/miasm2/arch/x86/arch.py
+++ b/miasm2/arch/x86/arch.py
@@ -3751,13 +3751,30 @@ addop("outsd", [bs8(0x6f), bs_opmode64])
 
 # addop("pause", [bs8(0xf3), bs8(0x90)])
 
-addop("pop", [bs8(0x8f), stk] + rmmod(d0))
-addop("pop", [bs("01011"), stk, reg])
-addop("pop", [bs8(0x1f), stk, d_ds])
-addop("pop", [bs8(0x07), stk, d_es])
-addop("pop", [bs8(0x17), stk, d_ss])
-addop("pop", [bs8(0x0f), stk, bs8(0xa1), d_fs])
-addop("pop", [bs8(0x0f), stk, bs8(0xa9), d_gs])
+addop("popw", [bs8(0x8f), stk, bs_opmode16] + rmmod(d0))
+addop("popw", [bs("01011"), stk, reg, bs_opmode16])
+addop("popw", [bs8(0x1f), stk, d_ds, bs_opmode16])
+addop("popw", [bs8(0x07), stk, d_es, bs_opmode16])
+addop("popw", [bs8(0x17), stk, d_ss, bs_opmode16])
+addop("popw", [bs8(0x0f), stk, bs8(0xa1), d_fs, bs_opmode16])
+addop("popw", [bs8(0x0f), stk, bs8(0xa9), d_gs, bs_opmode16])
+
+addop("pop", [bs8(0x8f), stk, bs_opmode32] + rmmod(d0))
+addop("pop", [bs("01011"), stk, reg, bs_opmode32])
+addop("pop", [bs8(0x1f), stk, d_ds, bs_opmode32])
+addop("pop", [bs8(0x07), stk, d_es, bs_opmode32])
+addop("pop", [bs8(0x17), stk, d_ss, bs_opmode32])
+addop("pop", [bs8(0x0f), stk, bs8(0xa1), d_fs, bs_opmode32])
+addop("pop", [bs8(0x0f), stk, bs8(0xa9), d_gs, bs_opmode32])
+
+addop("pop", [bs8(0x8f), stk, bs_opmode64] + rmmod(d0))
+addop("pop", [bs("01011"), stk, reg, bs_opmode64])
+addop("pop", [bs8(0x1f), stk, d_ds, bs_opmode64])
+addop("pop", [bs8(0x07), stk, d_es, bs_opmode64])
+addop("pop", [bs8(0x17), stk, d_ss, bs_opmode64])
+addop("pop", [bs8(0x0f), stk, bs8(0xa1), d_fs, bs_opmode64])
+addop("pop", [bs8(0x0f), stk, bs8(0xa9), d_gs, bs_opmode64])
+
 
 # popa_name = {16:'POPA', 32:'POPAD'}
 # bs_popa_name = bs_modname_size(l=0, name=popa_name)
@@ -3777,16 +3794,38 @@ addop("prefetch1", [bs8(0x0f), bs8(0x18)] + rmmod(d2, rm_arg_m08))
 addop("prefetch2", [bs8(0x0f), bs8(0x18)] + rmmod(d3, rm_arg_m08))
 addop("prefetchnta", [bs8(0x0f), bs8(0x18)] + rmmod(d0, rm_arg_m08))
 
-addop("push", [bs8(0xff), stk] + rmmod(d6))
-addop("push", [bs("01010"), stk, reg])
-addop("push", [bs8(0x6a), s08, stk])
-addop("push", [bs8(0x68), d_imm, stk])
-addop("push", [bs8(0x0e), stk, d_cs])
-addop("push", [bs8(0x16), stk, d_ss])
-addop("push", [bs8(0x1e), stk, d_ds])
-addop("push", [bs8(0x06), stk, d_es])
-addop("push", [bs8(0x0f), stk, bs8(0xa0), d_fs])
-addop("push", [bs8(0x0f), stk, bs8(0xa8), d_gs])
+addop("pushw", [bs8(0xff), stk, bs_opmode16] + rmmod(d6))
+addop("pushw", [bs("01010"), stk, reg, bs_opmode16])
+addop("pushw", [bs8(0x6a), s08, stk, bs_opmode16])
+addop("pushw", [bs8(0x68), d_imm, stk, bs_opmode16])
+addop("pushw", [bs8(0x0e), stk, d_cs, bs_opmode16])
+addop("pushw", [bs8(0x16), stk, d_ss, bs_opmode16])
+addop("pushw", [bs8(0x1e), stk, d_ds, bs_opmode16])
+addop("pushw", [bs8(0x06), stk, d_es, bs_opmode16])
+addop("pushw", [bs8(0x0f), stk, bs8(0xa0), d_fs, bs_opmode16])
+addop("pushw", [bs8(0x0f), stk, bs8(0xa8), d_gs, bs_opmode16])
+
+addop("push", [bs8(0xff), stk, bs_opmode32] + rmmod(d6))
+addop("push", [bs("01010"), stk, reg, bs_opmode32])
+addop("push", [bs8(0x6a), s08, stk, bs_opmode32])
+addop("push", [bs8(0x68), d_imm, stk, bs_opmode32])
+addop("push", [bs8(0x0e), stk, d_cs, bs_opmode32])
+addop("push", [bs8(0x16), stk, d_ss, bs_opmode32])
+addop("push", [bs8(0x1e), stk, d_ds, bs_opmode32])
+addop("push", [bs8(0x06), stk, d_es, bs_opmode32])
+addop("push", [bs8(0x0f), stk, bs8(0xa0), d_fs, bs_opmode32])
+addop("push", [bs8(0x0f), stk, bs8(0xa8), d_gs, bs_opmode32])
+
+addop("push", [bs8(0xff), stk, bs_opmode64] + rmmod(d6))
+addop("push", [bs("01010"), stk, reg, bs_opmode64])
+addop("push", [bs8(0x6a), s08, stk, bs_opmode64])
+addop("push", [bs8(0x68), d_imm, stk, bs_opmode64])
+addop("push", [bs8(0x0e), stk, d_cs, bs_opmode64])
+addop("push", [bs8(0x16), stk, d_ss, bs_opmode64])
+addop("push", [bs8(0x1e), stk, d_ds, bs_opmode64])
+addop("push", [bs8(0x06), stk, d_es, bs_opmode64])
+addop("push", [bs8(0x0f), stk, bs8(0xa0), d_fs, bs_opmode64])
+addop("push", [bs8(0x0f), stk, bs8(0xa8), d_gs, bs_opmode64])
 
 # pusha_name = {16:'PUSHA', 32:'PUSHAD'}
 # bs_pusha_name = bs_modname_size(l=0, name=pusha_name)
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,
diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py
index 9d4e464d..93b651c0 100644
--- a/test/arch/x86/arch.py
+++ b/test/arch/x86/arch.py
@@ -1075,14 +1075,20 @@ reg_tests = [
     # "f390"),
 
 
-    (m16, "00000000    POP        WORD PTR [BX+SI]",
+    (m16, "00000000    POPW       WORD PTR [BX+SI]",
      "8f00"),
+    (m32, "00000000    POPW       WORD PTR [BX+SI]",
+     "66678f00"),
     (m32, "00000000    POP        DWORD PTR [EAX]",
      "8f00"),
     (m64, "00000000    POP        QWORD PTR [RAX]",
      "8f00"),
 
 
+    (m16, "00000000    POPW       AX",
+     "8fC0"),
+    (m32, "00000000    POPW       AX",
+     "668fC0"),
     (m32, "00000000    POP        EAX",
      "8fC0"),
     (m64, "00000000    POP        RAX",
@@ -1106,6 +1112,28 @@ reg_tests = [
     (m32, "00000000    POP        GS",
      "0fa9"),
 
+    (m16, "00000000    POPW       DS",
+     "1f"),
+    (m16, "00000000    POPW       ES",
+     "07"),
+    (m16, "00000000    POPW       SS",
+     "17"),
+    (m16, "00000000    POPW       FS",
+     "0fa1"),
+    (m16, "00000000    POPW       GS",
+     "0fa9"),
+
+    (m32, "00000000    POPW       DS",
+     "661f"),
+    (m32, "00000000    POPW       ES",
+     "6607"),
+    (m32, "00000000    POPW       SS",
+     "6617"),
+    (m32, "00000000    POPW       FS",
+     "660fa1"),
+    (m32, "00000000    POPW       GS",
+     "660fa9"),
+
     (m16, "00000000    POPA",
      "61"),
     (m32, "00000000    POPAD",
@@ -1130,7 +1158,7 @@ reg_tests = [
      "0f1800"),
 
 
-    (m16, "00000000    PUSH       AX",
+    (m16, "00000000    PUSHW      AX",
      "50"),
     (m32, "00000000    PUSH       EAX",
      "50"),
@@ -1138,9 +1166,9 @@ reg_tests = [
      "50"),
     (m64, "00000000    PUSH       R10",
      "4152"),
-    (m16, "00000000    PUSH       WORD PTR [BX+SI]",
+    (m16, "00000000    PUSHW      WORD PTR [BX+SI]",
      "FF30"),
-    (m16, "00000000    PUSH       WORD PTR [EAX]",
+    (m16, "00000000    PUSHW      WORD PTR [EAX]",
      "67FF30"),
     (m16, "00000000    PUSH       DWORD PTR [EAX]",
      "6667FF30"),
@@ -1149,11 +1177,11 @@ reg_tests = [
     (m64, "00000000    PUSH       QWORD PTR [RAX]",
      "FF30"),
 
-    (m16, "00000000    PUSH       0x11",
+    (m16, "00000000    PUSHW      0x11",
      "6a11"),
     (m32, "00000000    PUSH       0x11223344",
      "6844332211"),
-    (m32, "00000000    PUSH       0x1122",
+    (m32, "00000000    PUSHW      0x1122",
      "66682211"),
     (m32, "00000000    PUSH       0x80",
      "6880000000"),
@@ -1177,6 +1205,32 @@ reg_tests = [
     (m32, "00000000    PUSH       GS",
      "0fa8"),
 
+    (m32, "00000000    PUSHW      CS",
+     "660e"),
+    (m32, "00000000    PUSHW      SS",
+     "6616"),
+    (m32, "00000000    PUSHW      DS",
+     "661E"),
+    (m32, "00000000    PUSHW      ES",
+     "6606"),
+    (m32, "00000000    PUSHW      FS",
+     "660fa0"),
+    (m32, "00000000    PUSHW      GS",
+     "660fa8"),
+
+    (m16, "00000000    PUSHW      CS",
+     "0e"),
+    (m16, "00000000    PUSHW      SS",
+     "16"),
+    (m16, "00000000    PUSHW      DS",
+     "1E"),
+    (m16, "00000000    PUSHW      ES",
+     "06"),
+    (m16, "00000000    PUSHW      FS",
+     "0fa0"),
+    (m16, "00000000    PUSHW      GS",
+     "0fa8"),
+
     (m16, "00000000    PUSHA",
      "60"),
     (m32, "00000000    PUSHAD",
diff --git a/test/arch/x86/unit/mn_stack.py b/test/arch/x86/unit/mn_stack.py
new file mode 100644
index 00000000..dd349d54
--- /dev/null
+++ b/test/arch/x86/unit/mn_stack.py
@@ -0,0 +1,60 @@
+#! /usr/bin/env python
+from asm_test import Asm_Test
+
+
+class Test_PUSHPOP(Asm_Test):
+    TXT = '''
+    main:
+       MOV     EBP, ESP
+       PUSH    0x11223344
+       POP     EAX
+       CMP     EBP, ESP
+       JNZ     BAD
+
+       PUSHW   0x1122
+       POPW    AX
+       CMP     EBP, ESP
+       JNZ     BAD
+
+       PUSH    SS
+       POP     EAX
+       CMP     EBP, ESP
+       JNZ     BAD
+
+       PUSHW   SS
+       POPW    AX
+       CMP     EBP, ESP
+       JNZ     BAD
+
+       PUSHFD
+       POP     EAX
+       CMP     EBP, ESP
+       JNZ     BAD
+
+       PUSHFW
+       POPW    AX
+       CMP     EBP, ESP
+       JNZ     BAD
+
+       PUSH    EAX
+       POPFD
+       CMP     EBP, ESP
+       JNZ     BAD
+
+       PUSHW   AX
+       POPFW
+       CMP     EBP, ESP
+       JNZ     BAD
+
+       RET
+
+BAD:
+       INT     0x3
+       RET
+    '''
+    def check(self):
+        assert(self.myjit.cpu.ESP-4 == self.myjit.cpu.EBP)
+
+
+if __name__ == "__main__":
+    [test()() for test in [Test_PUSHPOP]]
diff --git a/test/test_all.py b/test/test_all.py
index 895dbdac..f59e3781 100644
--- a/test/test_all.py
+++ b/test/test_all.py
@@ -35,6 +35,7 @@ testset += RegressionTest(["x86/arch.py"], base_dir="arch",
 for script in ["x86/sem.py",
                "x86/unit/mn_strings.py",
                "x86/unit/mn_float.py",
+               "x86/unit/mn_stack.py",
                "arm/arch.py",
                "arm/sem.py",
                "msp430/arch.py",