about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xexample/disas_and_graph.py3
-rw-r--r--miasm/arch/ia32_arch.py107
-rw-r--r--miasm/arch/ia32_sem.py616
-rw-r--r--miasm/expression/expression.py26
-rwxr-xr-xmiasm/tools/emul_helper.py16
-rw-r--r--miasm/tools/emul_lib/libcodenat.c52
-rw-r--r--miasm/tools/emul_lib/libcodenat.h34
-rw-r--r--miasm/tools/emul_lib/libcodenat_interface.c178
-rw-r--r--miasm/tools/to_c_helper.py30
9 files changed, 695 insertions, 367 deletions
diff --git a/example/disas_and_graph.py b/example/disas_and_graph.py
index 8a41d979..07030ea4 100755
--- a/example/disas_and_graph.py
+++ b/example/disas_and_graph.py
@@ -169,7 +169,8 @@ def my_disasm_callback(ad):
             raise ValueError('bad machine options')
     all_bloc = asmbloc.dis_bloc_all(mnemo, in_str, ad, set(),
                                     symbol_pool=symbol_pool,
-                                    amode = admode,
+                                    opmode = admode,
+                                    admode = admode,
                                     dontdis_retcall = options.dontdiscallret,
                                     follow_call = options.followcall)
     g = asmbloc.bloc2graph(all_bloc)
diff --git a/miasm/arch/ia32_arch.py b/miasm/arch/ia32_arch.py
index a192efbd..80bf0f04 100644
--- a/miasm/arch/ia32_arch.py
+++ b/miasm/arch/ia32_arch.py
@@ -255,7 +255,7 @@ def dict_to_ad(d, modifs = {}, opmode = u32, admode = u32):
         n = [x for x in d if type(x) in [int, long]]
         if len(n)!=1:
             raise ValueError("bad reg! %s"%str(d))
-        n = n[0]        
+        n = n[0]
         if x86_afs.size in d and d[x86_afs.size] == x86_afs.size_seg :
             t = x86_afs.reg_sg
         elif x86_afs.size in d:
@@ -294,26 +294,21 @@ def dict_to_ad(d, modifs = {}, opmode = u32, admode = u32):
                 out+='-0x%.8X'%-imm_tmp
             else:
                 out+='0x%.8X'%imm_tmp
-                
         if x86_afs.symb in d:
             #XXX todo multiple ref
             if out!="": out+='+'
             for c in d[x86_afs.symb]:
-                
                 if d[x86_afs.symb][c]==1:
                     out += '%s'%str(c.name)
                 else:
                     out += '%d,%s'%(int(d[x86_afs.symb][c]), str(c))
-                
     elif is_address(d):
         if x86_afs.size in d:
             size = d[x86_afs.size]
-            
         out = [ad_size[size]]
         segment = " "
         if x86_afs.segm in d:
             segment += x86_afs.reg_sg[d[x86_afs.segm]]+':'
-            
         for k in d:
             if k in [x86_afs.ad, x86_afs.size, x86_afs.segm]:
                 continue
@@ -824,7 +819,7 @@ class x86allmncs:
         addop("dec",   [0xFE],             d1   , no_rm         , {w8:(0,0)}         ,{}                , {},                         )
         addop("div",   [0xF6],             d6   , no_rm         , {w8:(0,0)}         ,{}                , {},                         )
                                                                                                             
-        addop("enter", [0xC8],             noafs, [u08, u16]    , {}                 ,{}                , {},                         )
+        addop("enter", [0xC8],             noafs, [u16, u08]    , {}                 ,{}                , {},                         )
                                                                                                             
         addop("hlt",   [0xF4],             noafs, no_rm         , {}                 ,{}                , {bkf:True}                  )
                                                                                                             
@@ -1257,6 +1252,10 @@ class x86allmncs:
         self.movsw_m = mnemonic(pm.name, pm.opc, pm.afs, pm.rm, pm.modifs, pm.modifs_orig, None)#, pm.sem)
         self.movsw_m.name = "movsw"
 
+        pm = self.find_mnemo("cmpsd")[0]
+        self.cmpsw_m = mnemonic(pm.name, pm.opc, pm.afs, pm.rm, pm.modifs, pm.modifs_orig, None)#, pm.sem)
+        self.cmpsw_m.name = "cmpsw"
+
         pm = self.find_mnemo("scasd")[0]
         self.scasw_m = mnemonic(pm.name, pm.opc, pm.afs, pm.rm, pm.modifs, pm.modifs_orig, None)#, pm.sem)
         self.scasw_m.name = "scasw"
@@ -1614,20 +1613,17 @@ class x86_mn:
                             mnemo_args = mnemo_args+[r]
                         else:
                             mnemo_args = [r]+mnemo_args
-                        
                     else:
-                        dib_out.append(r)                    
-
+                        dib_out.append(r)
                 elif dib == mim:
                     l = struct.calcsize(x86_afs.dict_size[self.size_ad])
                     d = struct.unpack(x86_afs.dict_size[self.size_ad], bin.readbs(l))[0]
                     d = uint32(d)
 
-                    
                     size = [self.size_op, x86_afs.u08][m.modifs[w8]]
                     dib_out.append({x86_afs.ad:True, x86_afs.size:size, x86_afs.imm:d})
                 elif dib in [r_cl, r_dx]:
-                    dib_out.append(dib)                    
+                    dib_out.append(dib)
                     pass
 
                 elif dib in segm_regs:
@@ -1649,8 +1645,6 @@ class x86_mn:
                     if is_address(a) and p in prefix_seg.values():
                         a[x86_afs.segm]=prefix_seg_inv[p]
                         continue
-                        
-                    
 
             t_len = bin.offset-init_offset
             bin.offset = init_offset
@@ -1668,14 +1662,77 @@ class x86_mn:
                 self.m = x86mndb.pushfw_m
             if self.size_op == u16 and self.m.name == "popfd":
                 self.m = x86mndb.popfw_m
-            if self.size_op == u16 and self.m.name == "lodsd":
-                self.m = x86mndb.lodsw_m
-            if self.size_op == u16 and self.m.name == "stosd":
-                self.m = x86mndb.stosw_m
-            if self.size_op == u16 and self.m.name == "movsd":
-                self.m  = x86mndb.movsw_m
-            if self.size_op == u16 and self.m.name == "scasd":
-                self.m  = x86mndb.scasw_m
+            if self.m.name.startswith("lods"):
+                if self.m.name[-1] == "b":
+                    s = u08
+                elif self.size_op == u16:
+                    s = u16
+                    self.m = x86mndb.lodsw_m
+                else:
+                    s = u32
+                self.arg = [{x86_afs.reg_dict[x86_afs.r_esi]:1,
+                             x86_afs.ad:True,
+                             x86_afs.size:s,
+                             x86_afs.segm:x86_afs.reg_sg.index(x86_afs.r_ds)}]
+            if self.m.name.startswith("stos"):
+                if self.m.name[-1] == "b":
+                    s = u08
+                elif self.size_op == u16:
+                    s = u16
+                    self.m = x86mndb.stosw_m
+                else:
+                    s = u32
+                self.arg = [{x86_afs.reg_dict[x86_afs.r_edi]:1,
+                             x86_afs.ad:True,
+                             x86_afs.size:s,
+                             x86_afs.segm:x86_afs.reg_sg.index(x86_afs.r_es)}]
+            if self.m.name.startswith("movs"):
+                if self.m.name[-1] == "b":
+                    s = u08
+                elif self.size_op == u16:
+                    s = u16
+                    self.m  = x86mndb.movsw_m
+                else:
+                    s = u32
+                self.arg = [{x86_afs.reg_dict[x86_afs.r_edi]:1,
+                             x86_afs.ad:True,
+                             x86_afs.size:s,
+                             x86_afs.segm:x86_afs.reg_sg.index(x86_afs.r_es)},
+
+                            {x86_afs.reg_dict[x86_afs.r_esi]:1,
+                             x86_afs.ad:True,
+                             x86_afs.size:s,
+                             x86_afs.segm:x86_afs.reg_sg.index(x86_afs.r_ds)}]
+            if self.m.name.startswith("cmps"):
+                if self.m.name[-1] == "b":
+                    s = u08
+                elif self.size_op == u16:
+                    s = u16
+                    self.m  = x86mndb.cmpsw_m
+                else:
+                    s = u32
+                self.arg = [{x86_afs.reg_dict[x86_afs.r_edi]:1,
+                             x86_afs.ad:True,
+                             x86_afs.size:s,
+                             x86_afs.segm:x86_afs.reg_sg.index(x86_afs.r_es)},
+
+                            {x86_afs.reg_dict[x86_afs.r_esi]:1,
+                             x86_afs.ad:True,
+                             x86_afs.size:s,
+                             x86_afs.segm:x86_afs.reg_sg.index(x86_afs.r_ds)}]
+
+            if self.m.name.startswith("scas"):
+                if self.m.name[-1] == "b":
+                    s = u08
+                elif self.size_op == u16:
+                    s = u16
+                    self.m  = x86mndb.scasw_m
+                else:
+                    s = u32
+                self.arg = [{x86_afs.reg_dict[x86_afs.r_edi]:1,
+                             x86_afs.ad:True,
+                             x86_afs.size:s,
+                             x86_afs.segm:x86_afs.reg_sg.index(x86_afs.r_es)}]
             return True
 
         except IOError:
@@ -2215,6 +2272,12 @@ if __name__ == '__main__':
     test_out = []
     log.setLevel(logging.DEBUG)
 
+    instr = x86mnemo.dis('66af'.replace(' ', '').decode('hex'))
+    print instr
+    print instr.arg
+    print instr.l
+    fds
+
     instr = x86mnemo.dis('64a100000000'.replace(' ', '').decode('hex'))
     print instr
     print instr.arg
diff --git a/miasm/arch/ia32_sem.py b/miasm/arch/ia32_sem.py
index 4abcbe51..fe439b66 100644
--- a/miasm/arch/ia32_sem.py
+++ b/miasm/arch/ia32_sem.py
@@ -218,6 +218,15 @@ ds = ExprId(reg_ds, size = 16)
 fs = ExprId(reg_fs, size = 16)
 gs = ExprId(reg_gs, size = 16)
 
+segm_dict = {
+    reg_es:es,
+    reg_cs:cs,
+    reg_ss:ss,
+    reg_ds:ds,
+    reg_fs:fs,
+    reg_gs:gs,
+    }
+
 tsc1 = ExprId(reg_tsc1, size = 32)
 tsc2 = ExprId(reg_tsc2, size = 32)
 
@@ -446,19 +455,19 @@ def update_flag_sub(x, y, z):
     return e
 
 
-def mov(a, b):
+def mov(info, a, b):
     return [ExprAff(a, b)]
 
-def xchg(a, b):
+def xchg(info, a, b):
     e = []
     e.append(ExprAff(a, b))
     e.append(ExprAff(b, a))
     return e
 
-def movzx(a, b):
+def movzx(info, a, b):
     return [ExprAff(a, ExprCompose([ExprSliceTo(ExprInt(uint32(0)), b.get_size(), a.get_size()), ExprSliceTo(b, 0, b.get_size())]))]
 
-def movsx(a, b):
+def movsx(info, a, b):
     return [ExprAff(a, ExprCompose([ExprSliceTo(ExprCond(ExprOp('==', get_op_msb(b), ExprInt(uint32(1))),
                                                          ExprInt(uint32(0xffffffff)),
                                                          ExprInt(uint32(0))),
@@ -466,10 +475,10 @@ def movsx(a, b):
                                     ExprSliceTo(b,
                                                 0, b.get_size())]))]
 
-def lea(a, b):
+def lea(info, a, b):
     return [ExprAff(a, b.arg)]
 
-def add(a, b):
+def add(info, a, b):
     e= []
     c = ExprOp('+', a, b)
     e+=update_flag_arith(c)
@@ -478,7 +487,7 @@ def add(a, b):
     e.append(ExprAff(a, c))
     return e
 
-def xadd(a, b):
+def xadd(info, a, b):
     e= []
     c = ExprOp('+', b, a)
     e+=update_flag_arith(c)
@@ -488,7 +497,7 @@ def xadd(a, b):
     e.append(ExprAff(a, c))
     return e
 
-def adc(a, b):
+def adc(info, a, b):
     e= []
     c = ExprOp('+',
                a,
@@ -501,7 +510,7 @@ def adc(a, b):
     e.append(ExprAff(a, c))
     return e
 
-def sub(a, b):
+def sub(info, a, b):
     e= []
     c = ExprOp('-', a, b)
     e+=update_flag_arith(c)
@@ -511,7 +520,7 @@ def sub(a, b):
     return e
 
 #a-(b+cf)
-def sbb(a, b):
+def sbb(info, a, b):
     e= []
     c = ExprOp('-',
                a,
@@ -524,11 +533,11 @@ def sbb(a, b):
     e.append(ExprAff(a, c))
     return e
 
-def neg(b):
+def neg(info, b):
     e= []
     cast_int = tab_uintsize[b.get_size()]
     a = ExprInt(cast_int(0))
-    
+
     c = ExprOp('-', a, b)
     e+=update_flag_arith(c)
     e+=update_flag_sub(a, b, c)
@@ -536,7 +545,7 @@ def neg(b):
     e.append(ExprAff(b, c))
     return e
 
-def l_not(b):
+def l_not(info, b):
     e= []
     cast_int = tab_uintsize[b.get_size()]
     c = ExprOp('!', b)
@@ -544,7 +553,7 @@ def l_not(b):
     return e
 
 
-def l_cmp(a, b):
+def l_cmp(info, a, b):
     e= []
     c = ExprOp('-', a, b)
     e+=update_flag_arith(c)
@@ -552,38 +561,38 @@ def l_cmp(a, b):
     e+=update_flag_af(c)
     return e
 
-def xor(a, b):
+def xor(info, a, b):
     e= []
     c = ExprOp('^', a, b)
     e+=update_flag_logic(c)
     e.append(ExprAff(a, c))
     return e
 
-def l_or(a, b):
+def l_or(info, a, b):
     e= []
     c = ExprOp('|', a, b)
     e+=update_flag_logic(c)
     e.append(ExprAff(a, c))
     return e
 
-def l_and(a, b):
+def l_and(info, a, b):
     e= []
     c = ExprOp('&', a, b)
     e+=update_flag_logic(c)
     e.append(ExprAff(a, c))
     return e
 
-def l_test(a, b):
+def l_test(info, a, b):
     e= []
     c = ExprOp('&', a, b)
     e+=update_flag_logic(c)
     return e
 
-def l_rol(a, b):
+def l_rol(info, a, b):
     e= []
     cast_int = tab_uintsize[a.get_size()]
     c = ExprOp('<<<', a, b)
-    
+
     new_cf = ExprOp("&", c ,ExprInt(cast_int(1)))
     e.append(ExprAff(cf, new_cf))
     ### hack (only valid if b=1)
@@ -591,17 +600,17 @@ def l_rol(a, b):
     e.append(ExprAff(a, c))
     return e
 
-def l_ror(a, b):
+def l_ror(info, a, b):
     e= []
     c = ExprOp('>>>', a, b)
-    
+
     e.append(ExprAff(cf, get_op_msb(c)))
     ### hack (only valid if b=1): when count == 1: a = msb-1(dest)
     e.append(ExprAff(of, ExprOp("^", get_op_msb(c), get_op_msb(a))))
     e.append(ExprAff(a, c))
     return e
 
-def rcl(a, b):
+def rcl(info, a, b):
     e= []
     c = ExprOp('<<<c_rez', a, b, cf)
     new_cf = ExprOp('<<<c_cf', a, b, cf)
@@ -612,7 +621,7 @@ def rcl(a, b):
     e.append(ExprAff(a, c))
     return e
 
-def rcr(a, b):
+def rcr(info, a, b):
     e= []
     c = ExprOp('>>>c_rez', a, b, cf)
     new_cf = ExprOp('>>>c_cf', a, b, cf)
@@ -624,7 +633,7 @@ def rcr(a, b):
     
     return e
 
-def sar(a, b):
+def sar(info, a, b):
     e= []
     cast_int = tab_uintsize[a.get_size()]
     cast_intb = tab_uintsize[b.get_size()]
@@ -640,10 +649,8 @@ def sar(a, b):
                                   shifter,
                                   ExprInt(cast_intb(1))
                                   )
-                           
                            )
                     )
-    
     e.append(ExprAff(cf, ExprCond(shifter,
                                   new_cf,
                                   cf)
@@ -654,7 +661,7 @@ def sar(a, b):
     e.append(ExprAff(a, c))
     return e
 
-def shr(a, b):
+def shr(info, a, b):
     e= []
     cast_int = tab_uintsize[a.get_size()]
     cast_intb = tab_uintsize[b.get_size()]
@@ -669,28 +676,24 @@ def shr(a, b):
                                   shifter,
                                   ExprInt(cast_intb(1))
                                   )
-                           
                            )
                     )
-    
     e.append(ExprAff(cf, ExprCond(shifter,
                                   new_cf,
                                   cf)
                      )
              )
-    
     e.append(ExprAff(of, get_op_msb(a)))
     e+=update_flag_znp(c)
     e.append(ExprAff(a, c))
     return e
 
-def shrd_cl(a, b):
+def shrd_cl(info, a, b):
     e= []
     cast_int = tab_uintsize[a.get_size()]
     cast_intb = tab_uintsize[b.get_size()]
 
     shifter = ExprOp('&',ecx, ExprInt(cast_intb(0x1f)))
-    
     c = ExprOp('|',
                 ExprOp('>>', a, shifter),
                 ExprOp('<<', b, ExprOp('-',
@@ -707,7 +710,6 @@ def shrd_cl(a, b):
                                   shifter,
                                   ExprInt(cast_intb(1))
                                   )
-                           
                            )
                     )
     e.append(ExprAff(cf, ExprCond(shifter,
@@ -720,7 +722,7 @@ def shrd_cl(a, b):
     e.append(ExprAff(a, c))
     return e
 
-def shrd(a, b, c):
+def shrd(info, a, b, c):
     e= []
     cast_int = tab_uintsize[a.get_size()]
     cast_intb = tab_uintsize[b.get_size()]
@@ -756,12 +758,12 @@ def shrd(a, b, c):
     e.append(ExprAff(a, d))
     return e
 
-def sal(a, b):
+def sal(info, a, b):
     e= []
     cast_int = tab_uintsize[a.get_size()]
     cast_intb = tab_uintsize[b.get_size()]
     shifter = ExprOp('&',b, ExprInt(cast_intb(0x1f)))
-    
+
     c = ExprOp('a<<', a, shifter)
     new_cf = ExprOp('&',
                     ExprInt(cast_int(1)),
@@ -771,10 +773,8 @@ def sal(a, b):
                                   ExprInt(cast_intb(a.get_size())),
                                   shifter
                                   )
-                           
                            )
                     )
-    
     e.append(ExprAff(cf, ExprCond(shifter,
                                   new_cf,
                                   cf)
@@ -785,12 +785,12 @@ def sal(a, b):
     e.append(ExprAff(a, c))
     return e
 
-def shl(a, b):
+def shl(info, a, b):
     e= []
     cast_int = tab_uintsize[a.get_size()]
     cast_intb = tab_uintsize[b.get_size()]
     shifter = ExprOp('&',b, ExprInt(cast_intb(0x1f)))
-    
+
     c = ExprOp('<<', a, shifter)
     new_cf = ExprOp('&',
                     ExprInt(cast_int(1)),
@@ -800,7 +800,6 @@ def shl(a, b):
                                   ExprInt(cast_intb(a.get_size())),
                                   shifter
                                   )
-                           
                            )
                     )
     e.append(ExprAff(cf, ExprCond(shifter,
@@ -813,12 +812,11 @@ def shl(a, b):
     e.append(ExprAff(a, c))
     return e
 
-def shld_cl(a, b):
+def shld_cl(info, a, b):
     e= []
     cast_int = tab_uintsize[a.get_size()]
     cast_intb = tab_uintsize[b.get_size()]
     shifter = ExprOp('&',ecx, ExprInt(cast_int(0x1f)))
-    
     c = ExprOp('|',
             ExprOp('<<', a, shifter),
             ExprOp('>>', b, ExprOp('-',
@@ -835,7 +833,6 @@ def shld_cl(a, b):
                                   ExprInt(cast_intb(a.get_size())),
                                   shifter
                                   )
-                           
                            )
                     )
     e.append(ExprAff(cf, ExprCond(shifter,
@@ -850,28 +847,28 @@ def shld_cl(a, b):
 
 
 #XXX todo ###
-def cmc():
+def cmc(info):
     return     [ExprAff(cf, ExprOp('==', cf, ExprInt(uint32(0))))]
 
-def clc():
+def clc(info):
     return     [ExprAff(cf, ExprInt(uint32(0)))]
 
-def stc():
+def stc(info):
     return     [ExprAff(cf, ExprInt(uint32(1)))]
 
-def cld():
+def cld(info):
     return     [ExprAff(df, ExprInt(uint32(0)))]
 
-def std():
+def std(info):
     return     [ExprAff(df, ExprInt(uint32(1)))]
 
-def cli():
+def cli(info):
     return     [ExprAff(i_f, ExprInt(uint32(0)))]
 
-def sti():
+def sti(info):
     return     [ExprAff(ExprId('vmcpu.vm_exception_flags'), ExprInt(uint32(1<<7)))]
 
-def inc(a):
+def inc(info, a):
     e= []
     b = ExprInt(tab_uintsize[a.get_size()](1))
     c = ExprOp('+', a, b)
@@ -879,12 +876,12 @@ def inc(a):
     e+=update_flag_af(c)
 
     cast_int = tab_uintsize[c.get_size()]
-    e.append(update_flag_add_of(cast_int, a, b, c))    
+    e.append(update_flag_add_of(cast_int, a, b, c))
     e.append(ExprAff(a, c))
     return e
 
 
-def dec(a):
+def dec(info, a):
     e= []
     b = ExprInt(tab_uintsize[a.get_size()](-1))
     c = ExprOp('+', a, b)
@@ -892,11 +889,11 @@ def dec(a):
     e+=update_flag_af(c)
 
     cast_int = tab_uintsize[c.get_size()]
-    e.append(update_flag_add_of(cast_int, a, b, c))    
+    e.append(update_flag_add_of(cast_int, a, b, c))
     e.append(ExprAff(a, c))
     return e
 
-def push(a):
+def push(info, a):
     e= []
     s = a.get_size()
     if not s in [16,32]:
@@ -905,8 +902,8 @@ def push(a):
     e.append(ExprAff(esp, c))
     e.append(ExprAff(ExprMem(c, s), a))
     return e
-    
-def pop(a):
+
+def pop(info, a):
     e= []
     s = a.get_size()
     if not s in [16,32]:
@@ -919,60 +916,60 @@ def pop(a):
     e.append(ExprAff(a, ExprMem(esp, s)))
     return e
 
-def sete(a):
+def sete(info, a):
     e = []
     e.append(ExprAff(a, ExprCond(ExprOp('==', zf, ExprInt(uint32(1))), ExprInt(tab_uintsize[a.get_size()](1)), ExprInt(tab_uintsize[a.get_size()](0)))))
     return e
 
-def setnz(a):
+def setnz(info, a):
     e = []
     e.append(ExprAff(a, ExprCond(ExprOp('==', zf, ExprInt(uint32(0))), ExprInt(tab_uintsize[a.get_size()](1)), ExprInt(tab_uintsize[a.get_size()](0)))))
     return e
 
-def setl(a):
+def setl(info, a):
     e = []
     e.append(ExprAff(a, ExprCond(ExprOp('==', ExprOp('==', nf, of), ExprInt(uint32(0))), ExprInt(tab_uintsize[a.get_size()](1)), ExprInt(tab_uintsize[a.get_size()](0)))))
     return e
 
-def setg(a):
+def setg(info, a):
     e = []
     e.append(ExprAff(a, ExprCond(ExprOp("&", ExprOp('==', zf, ExprInt(uint32(0))), ExprOp('==', nf, of)), ExprInt(tab_uintsize[a.get_size()](1)), ExprInt(tab_uintsize[a.get_size()](0)))))
     return e
 
-def setge(a):
+def setge(info, a):
     e = []
     e.append(ExprAff(a, ExprCond(ExprOp('==', nf, of), ExprInt(tab_uintsize[a.get_size()](1)), ExprInt(tab_uintsize[a.get_size()](0)))))
     return e
 
 
-def seta(a):
+def seta(info, a):
     e = []
     e.append(ExprAff(a, ExprCond(ExprOp('&', ExprOp('==', cf, ExprInt(uint32(0))), ExprOp('==', zf, ExprInt(uint32(0)))), ExprInt(tab_uintsize[a.get_size()](1)), ExprInt(tab_uintsize[a.get_size()](0)))))
     return e
 
-def setb(a):
+def setb(info, a):
     e = []
     e.append(ExprAff(a, ExprCond(ExprOp('==', cf, ExprInt(uint32(1))), ExprInt(tab_uintsize[a.get_size()](1)), ExprInt(tab_uintsize[a.get_size()](0)))))
     return e
 
-def setns(a):
+def setns(info, a):
     e = []
     e.append(ExprAff(a, ExprCond(ExprOp('==', nf, ExprInt(uint32(0))), ExprInt(tab_uintsize[a.get_size()](1)), ExprInt(tab_uintsize[a.get_size()](0)))))
     return e
 
-def sets(a):
+def sets(info, a):
     e = []
     e.append(ExprAff(a, ExprCond(ExprOp('==', nf, ExprInt(uint32(1))), ExprInt(tab_uintsize[a.get_size()](1)), ExprInt(tab_uintsize[a.get_size()](0)))))
     return e
 
 
-def seto(a): 
+def seto(info, a):
     e= []
     e.append(ExprAff(a, ExprCond(ExprOp('==', of, ExprInt(uint32(1))), ExprInt(tab_uintsize[a.get_size()](1)), ExprInt(tab_uintsize[a.get_size()](0)))))
     return e
 
 
-def bswap(a):
+def bswap(info, a):
     e = []
     c = ExprCompose([ExprSliceTo(ExprOp('&', ExprInt(tab_uintsize[a.get_size()](0xFF)), a),                                 24, 32),
                      ExprSliceTo(ExprOp('>>', ExprOp('&', ExprInt(tab_uintsize[a.get_size()](0xFF00)), a), ExprInt(uint32(8))),     16, 24),
@@ -982,43 +979,25 @@ def bswap(a):
     e.append(ExprAff(a, c))
     return e
 
-def cmpsb():
+def cmps(info, a, b):
     e= []
-    e+=l_cmp(ExprMem(esi, 8), ExprMem(edi, 8))
-    e.append(ExprAff(edi, ExprCond(df, ExprOp('-', edi, ExprInt(uint32(1))), ExprOp('+', edi, ExprInt(uint32(1))))))
-    e.append(ExprAff(esi, ExprCond(df, ExprOp('-', esi, ExprInt(uint32(1))), ExprOp('+', esi, ExprInt(uint32(1))))))
+    int_cast = tab_uintsize[a.get_size()]
+    e+=l_cmp(info, a, b)
+    e.append(ExprAff(a.arg, ExprCond(df,
+                                     ExprOp('-', a.arg, ExprInt(int_cast(a.get_size()/8))),
+                                     ExprOp('+', a.arg, ExprInt(int_cast(a.get_size()/8))))))
+    e.append(ExprAff(b.arg, ExprCond(df,
+                                     ExprOp('-', b.arg, ExprInt(int_cast(a.get_size()/8))),
+                                     ExprOp('+', b.arg, ExprInt(int_cast(a.get_size()/8))))))
     return e
 
-def cmpsw():
+def scas(info, a):
     e= []
-    e+=l_cmp(ExprMem(esi, 16), ExprMem(edi, 16))
-    e.append(ExprAff(edi, ExprCond(df, ExprOp('-', edi, ExprInt(uint32(2))), ExprOp('+', edi, ExprInt(uint32(2))))))
-    e.append(ExprAff(esi, ExprCond(df, ExprOp('-', esi, ExprInt(uint32(2))), ExprOp('+', esi, ExprInt(uint32(2))))))
-    return e
-
-def cmpsd():
-    e= []
-    e+=l_cmp(ExprMem(esi), ExprMem(edi))
-    e.append(ExprAff(edi, ExprCond(df, ExprOp('-', edi, ExprInt(uint32(4))), ExprOp('+', edi, ExprInt(uint32(4))))))
-    e.append(ExprAff(esi, ExprCond(df, ExprOp('-', esi, ExprInt(uint32(4))), ExprOp('+', esi, ExprInt(uint32(4))))))
-    return e
-
-def scasb():
-    e= []
-    e+=l_cmp(eax[0:8], ExprMem(edi, 8))
-    e.append(ExprAff(edi, ExprCond(df, ExprOp('-', edi, ExprInt(uint32(1))), ExprOp('+', edi, ExprInt(uint32(1))))))
-    return e
-
-def scasw():
-    e= []
-    e+=l_cmp(eax[0:16], ExprMem(edi, 16))
-    e.append(ExprAff(edi, ExprCond(df, ExprOp('-', edi, ExprInt(uint32(2))), ExprOp('+', edi, ExprInt(uint32(2))))))
-    return e
-
-def scasd():
-    e= []
-    e+=l_cmp(eax, ExprMem(edi))
-    e.append(ExprAff(edi, ExprCond(df, ExprOp('-', edi, ExprInt(uint32(4))), ExprOp('+', edi, ExprInt(uint32(4))))))
+    int_cast = tab_uintsize[a.get_size()]
+    e+=l_cmp(info, eax[0:a.get_size()], a)
+    e.append(ExprAff(a.arg, ExprCond(df,
+                                     ExprOp('-', a.arg, ExprInt(int_cast(a.get_size()/8))),
+                                     ExprOp('+', a.arg, ExprInt(int_cast(a.get_size()/8))))))
     return e
 
 
@@ -1043,13 +1022,13 @@ def compose_eflag(s = 32):
         args.append(ExprSliceTo(ExprInt(uint32(0)),22, 32))
     return ExprCompose(args)
 
-def pushfd():
-    return push(compose_eflag())
+def pushfd(info):
+    return push(info, compose_eflag())
 
-def pushfw():
-    return push(compose_eflag(16))
+def pushfw(info):
+    return push(info, compose_eflag(16))
 
-def popfd():
+def popfd(info):
     tmp = ExprMem(esp)
     e = []
     e.append(ExprAff(cf, ExprSlice(tmp, 0, 1)))
@@ -1072,7 +1051,7 @@ def popfd():
     e.append(ExprAff(esp, ExprOp('+', esp, ExprInt(uint32(4)))))
     return e
 
-def popfw():
+def popfw(info):
     tmp = ExprMem(esp)
     e = []
     e.append(ExprAff(cf, ExprSlice(tmp, 0, 1)))
@@ -1089,7 +1068,7 @@ def popfw():
     e.append(ExprAff(esp, ExprOp('+', esp, ExprInt(uint32(2)))))
     return e
 
-def pushad():
+def pushad(info):
     e = []
     s = 32
     if not s in [16,32]:
@@ -1101,7 +1080,7 @@ def pushad():
     e.append(ExprAff(esp, c))
     return e
 
-def popad():
+def popad(info):
     e = []
     s = 32
     if not s in [16,32]:
@@ -1113,146 +1092,185 @@ def popad():
             continue
         c = ExprOp('+', esp, ExprInt(uint32((s/8)*i)))
         e.append(ExprAff(regs[i], ExprMem(c, s)))
-        
+
     c = ExprOp('+', esp, ExprInt(uint32((s/8)*(i+1))))
     e.append(ExprAff(esp, c))
-    
+
     return e
 
 
-def call(a, b): 
+def call(info, a, b):
     e= []
-    c = ExprOp('+', esp, ExprInt(uint32(-4)))    
-    e.append(ExprAff(esp, c))
-    e.append(ExprAff(ExprMem(c), a))
+    opmode, admode = info
+    if opmode == u16:
+        s = 16
+        myesp = esp[:16]
+    else:
+        s = 32
+        myesp = esp
+    int_cast = tab_uintsize[s]
+
+    c = ExprOp('+', myesp, ExprInt(int_cast(-s/8)))
+    e.append(ExprAff(myesp, c))
+    e.append(ExprAff(ExprMem(c, size=s), a))
     e.append(ExprAff(eip, b))
     return e
 
-def ret(a = ExprInt(uint32(0))):
+def ret(info, a = ExprInt(uint32(0))):
     e = []
-    e.append(ExprAff(esp, ExprOp('+', esp, ExprOp('+', ExprInt(uint32(4)), a))))
-    e.append(ExprAff(eip, ExprMem(esp)))
-
-    
-    return e
+    opmode, admode = info
+    if opmode == u16:
+        s = 16
+        myesp = esp[:16]
+    else:
+        s = 32
+        myesp = esp
+    int_cast = tab_uintsize[s]
+    e.append(ExprAff(myesp, ExprOp('+', myesp, ExprOp('+', ExprInt(int_cast(s/8)), a))))
+    e.append(ExprAff(eip, ExprMem(myesp, size = s)))
+    return e
+
+def leave(info):
+    opmode, admode = info
+    if opmode == u16:
+        s = 16
+        myesp = esp[:16]
+        myebp = ebp[:16]
+    else:
+        s = 32
+        myesp = esp
+        myebp = ebp
+    int_cast = tab_uintsize[s]
 
-def leave():
     e = []
-    e.append(ExprAff(ebp, ExprMem(ebp)))
-    e.append(ExprAff(esp, ExprOp('+', ExprInt(uint32(4)), ebp)))
+    e.append(ExprAff(myebp, ExprMem(myebp, size = s)))
+    e.append(ExprAff(myesp, ExprOp('+', ExprInt(int_cast(s/8)), myebp)))
     return e
 
-def enter(a,b):
-    #XXX 32 bit...
+def enter(info, a,b):
+    opmode, admode = info
+    if opmode == u16:
+        s = 16
+        myesp = esp[:16]
+        myebp = ebp[:16]
+    else:
+        s = 32
+        myesp = esp
+        myebp = ebp
+    int_cast = tab_uintsize[s]
+
     e = []
-    e.append(ExprAff(ExprMem(esp), ebp))
-    e.append(ExprAff(ebp, ExprOp("-", esp, ExprInt(uint32(4)))))
-    e.append(ExprAff(esp, ExprOp('-', esp, 
-                                      ExprOp("+", a, ExprInt(uint32(4)))
+    esp_tmp = ExprOp("-", myesp, ExprInt(int_cast(s/8)))
+    e.append(ExprAff(ExprMem(esp_tmp,
+                             size = s),
+                     myebp))
+    e.append(ExprAff(myebp, esp_tmp))
+    e.append(ExprAff(myesp, ExprOp('-', myesp,
+                                      ExprOp("+", a, ExprInt(int_cast(s/8)))
                                 )
                     )
             )
     return e
 
-def jmp(a): 
+def jmp(info, a):
     e= []
     e.append(ExprAff(eip, a))
     return e
 
-def jz(a, b): 
+def jz(info, a, b):
     e= []
     e.append(ExprAff(eip, ExprCond(ExprOp('==', zf, ExprInt(uint32(1))), b, a)))
     return e
 
-def jnz(a, b): 
+def jnz(info, a, b):
     e= []
     e.append(ExprAff(eip, ExprCond(ExprOp('==', zf, ExprInt(uint32(0))), b, a)))
     return e
 
-def jp(a, b): 
+def jp(info, a, b):
     e= []
     e.append(ExprAff(eip, ExprCond(ExprOp('==', pf, ExprInt(uint32(1))), b, a)))
     return e
 
-def jnp(a, b): 
+def jnp(info, a, b):
     e= []
     e.append(ExprAff(eip, ExprCond(ExprOp('==', pf, ExprInt(uint32(0))), b, a)))
     return e
 
-def ja(a, b): 
+def ja(info, a, b):
     e= []
     e.append(ExprAff(eip, ExprCond(ExprOp('&', ExprOp('==', cf, ExprInt(uint32(0))), ExprOp('==', zf, ExprInt(uint32(0)))), b, a)))
     return e
 
-def jae(a, b): 
+def jae(info, a, b):
     e= []
     e.append(ExprAff(eip, ExprCond(ExprOp('==', cf, ExprInt(uint32(0))), b, a)))
     return e
 
-def jb(a, b): 
+def jb(info, a, b):
     e= []
     e.append(ExprAff(eip, ExprCond(ExprOp('==', cf, ExprInt(uint32(1))), b, a)))
     return e
 
-def jbe(a, b): 
+def jbe(info, a, b):
     e= []
     e.append(ExprAff(eip, ExprCond(ExprOp('|', ExprOp('==', cf, ExprInt(uint32(1))), ExprOp('==', zf, ExprInt(uint32(1)))), b, a)))
     return e
 
-def jge(a, b): 
+def jge(info, a, b):
     e= []
     e.append(ExprAff(eip, ExprCond(ExprOp('==', nf, of), b, a)))
     return e
 
-def jg(a, b): 
+def jg(info, a, b):
     e= []
     e.append(ExprAff(eip, ExprCond(ExprOp('&', ExprOp('==', zf, ExprInt(uint32(0))), ExprOp('==', nf, of)), b, a)))
     return e
 
-def jl(a, b): 
+def jl(info, a, b):
     e= []
     e.append(ExprAff(eip, ExprCond(ExprOp('==', ExprOp('==', nf, of), ExprInt(uint32(0))), b, a)))
     return e
 
-def jle(a, b): 
+def jle(info, a, b):
     e= []
     e.append(ExprAff(eip, ExprCond(ExprOp('|', zf, ExprOp('==', ExprOp('==', nf, of), ExprInt(uint32(0)))), b, a)))
     return e
 
-def js(a, b): 
+def js(info, a, b):
     e= []
     e.append(ExprAff(eip, ExprCond(ExprOp('==', nf, ExprInt(uint32(1))), b, a)))
     return e
 
-def jns(a, b): 
+def jns(info, a, b):
     e= []
     e.append(ExprAff(eip, ExprCond(ExprOp('==', nf, ExprInt(uint32(0))), b, a)))
     return e
 
-def jo(a, b):
+def jo(info, a, b):
     e= []
     e.append(ExprAff(eip, ExprCond(of, b, a)))
     return e
 
-def jno(a, b): 
+def jno(info, a, b):
     e= []
     e.append(ExprAff(eip, ExprCond(ExprOp('==', of, ExprInt(uint32(0))), b, a)))
     return e
 
-def jecxz(a, b): 
+def jecxz(info, a, b):
     e= []
     e.append(ExprAff(eip, ExprCond(ExprOp('==', ecx, ExprInt(uint32(0))), b, a)))
     return e
 
 
-def loop(a, b): 
+def loop(info, a, b):
     e= []
     c = ExprOp('-', ecx, ExprInt(uint32(1)))
     e.append(ExprAff(ecx, c))
     e.append(ExprAff(eip, ExprCond(ExprOp('==', ExprInt(uint32(0)), ExprOp('==', c, ExprInt(uint32(0)))), b, a)))
     return e
 
-def loopne(a, b): 
+def loopne(info, a, b):
     e= []
     c = ExprOp('-', ecx, ExprInt(uint32(1)))
     e.append(ExprAff(ecx, c))
@@ -1264,7 +1282,7 @@ def loopne(a, b):
     return e
 
 #XXX size to do; eflag
-def div(a):
+def div(info, a):
     e= []
 
     s = a.get_size()
@@ -1289,7 +1307,7 @@ def div(a):
     return e
 
 #XXX size to do; eflag
-def idiv(a):
+def idiv(info, a):
     e= []
 
     s = a.get_size()
@@ -1312,7 +1330,7 @@ def idiv(a):
     return e
 
 #XXX size to do; eflag
-def mul(a):
+def mul(info, a):
     e= []
     if a.get_size() == 32:
         c_hi = ExprOp('umul32_hi', eax, a)
@@ -1327,8 +1345,6 @@ def mul(a):
                                       ExprInt(uint32(0)),
                                       ExprInt(uint32(1)))))
 
-        
-        
     elif a.get_size() == 16:
         c_hi = ExprOp('umul16_hi', r_ax, a)
         c_lo = ExprOp('umul16_lo', r_ax, a)
@@ -1354,11 +1370,10 @@ def mul(a):
 
 
 
-    
     return e
 
 #XXX size to do; eflag
-def imul(a, b = None, c = None):
+def imul(info, a, b = None, c = None):
     e= []
     if b == None:
         if a.get_size() == 32:
@@ -1374,7 +1389,6 @@ def imul(a, b = None, c = None):
         elif a.get_size() == 8:
             c = ExprOp('imul08', eax, a)
             e.append(ExprAff(eax[:16], c))
-            
     else:
         if c == None:
             c = b
@@ -1385,7 +1399,7 @@ def imul(a, b = None, c = None):
 
 
 #XXX 16 bit bug
-def cdq():
+def cdq(info):
     e = []
     e.append(ExprAff(edx,
                      ExprCond(ExprOp('==', ExprOp('&', eax, ExprInt(uint32(0x80000000))), ExprInt(uint32(0))),
@@ -1395,61 +1409,36 @@ def cdq():
              )
     return e
 
-def stosb():
-    e = []
-    e.append(ExprAff(ExprMem(edi, 8), eax[0:8]))
-    e.append(ExprAff(edi, ExprCond(df, ExprOp('-', edi, ExprInt(uint32(1))), ExprOp('+', edi, ExprInt(uint32(1))))))
-    return e
-
-def stosw():
-    e = []
-    e.append(ExprAff(ExprMem(edi, 16), eax[0:16]))
-    e.append(ExprAff(edi, ExprCond(df, ExprOp('-', edi, ExprInt(uint32(2))), ExprOp('+', edi, ExprInt(uint32(2))))))
-    return e
-
-def stosd():
-    e = []
-    e.append(ExprAff(ExprMem(edi), eax))
-    e.append(ExprAff(edi, ExprCond(df, ExprOp('-', edi, ExprInt(uint32(4))), ExprOp('+', edi, ExprInt(uint32(4))))))
-    return e
-
-def lodsb():
+def stos(info, a):
     e = []
-    e.append(ExprAff(eax[0:8], ExprMem(esi, 8)))
-    e.append(ExprAff(esi, ExprCond(df, ExprOp('-', esi, ExprInt(uint32(1))), ExprOp('+', esi, ExprInt(uint32(1))))))
+    int_cast = tab_uintsize[a.get_size()]
+    e.append(ExprAff(a, eax[0:a.get_size()]))
+    e.append(ExprAff(a.arg, ExprCond(df,
+                                     ExprOp('-', a.arg, ExprInt(int_cast(a.get_size()/8))),
+                                     ExprOp('+', a.arg, ExprInt(int_cast(a.get_size()/8))))))
     return e
 
-def lodsw():
+def lods(info, a):
     e = []
-    e.append(ExprAff(eax[0:16], ExprMem(esi, 16)))
-    e.append(ExprAff(esi, ExprCond(df, ExprOp('-', esi, ExprInt(uint32(2))), ExprOp('+', esi, ExprInt(uint32(2))))))
+    int_cast = tab_uintsize[a.get_size()]
+    e.append(ExprAff(eax[0:a.get_size()], a))
+    e.append(ExprAff(a.arg, ExprCond(df,
+                                     ExprOp('-', a.arg, ExprInt(int_cast(a.get_size()/8))),
+                                     ExprOp('+', a.arg, ExprInt(int_cast(a.get_size()/8))))))
     return e
 
-def lodsd():
+def movs(info, a, b):
     e = []
-    e.append(ExprAff(eax, ExprMem(esi)))
-    e.append(ExprAff(esi, ExprCond(df, ExprOp('-', esi, ExprInt(uint32(4))), ExprOp('+', esi, ExprInt(uint32(4))))))
-    return e
+    int_cast = tab_uintsize[a.get_size()]
 
-def movsb():
-    e = []
-    e.append(ExprAff(ExprMem(edi, 8), ExprMem(esi, 8)))
-    e.append(ExprAff(edi, ExprCond(df, ExprOp('-', edi, ExprInt(uint32(1))), ExprOp('+', edi, ExprInt(uint32(1))))))
-    e.append(ExprAff(esi, ExprCond(df, ExprOp('-', esi, ExprInt(uint32(1))), ExprOp('+', esi, ExprInt(uint32(1))))))
-    return e
-
-def movsw():
-    e = []
-    e.append(ExprAff(ExprMem(edi, 16), ExprMem(esi, 16)))
-    e.append(ExprAff(edi, ExprCond(df, ExprOp('-', edi, ExprInt(uint32(2))), ExprOp('+', edi, ExprInt(uint32(2))))))
-    e.append(ExprAff(esi, ExprCond(df, ExprOp('-', esi, ExprInt(uint32(2))), ExprOp('+', esi, ExprInt(uint32(2))))))
-    return e
+    e.append(ExprAff(a, b))
+    e.append(ExprAff(a.arg, ExprCond(df,
+                                     ExprOp('-', a.arg, ExprInt(int_cast(a.get_size()/8))),
+                                     ExprOp('+', a.arg, ExprInt(int_cast(a.get_size()/8))))))
+    e.append(ExprAff(b.arg, ExprCond(df,
+                                     ExprOp('-', b.arg, ExprInt(int_cast(a.get_size()/8))),
+                                     ExprOp('+', b.arg, ExprInt(int_cast(a.get_size()/8))))))
 
-def movsd():
-    e = []
-    e.append(ExprAff(ExprMem(edi), ExprMem(esi)))
-    e.append(ExprAff(edi, ExprCond(df, ExprOp('-', edi, ExprInt(uint32(4))), ExprOp('+', edi, ExprInt(uint32(4))))))
-    e.append(ExprAff(esi, ExprCond(df, ExprOp('-', esi, ExprInt(uint32(4))), ExprOp('+', esi, ExprInt(uint32(4))))))
     return e
 
 
@@ -1475,7 +1464,7 @@ def float_pop(avoid_flt = None):
     return e
 
 # XXX TODO
-def fcom(a):
+def fcom(info, a):
     e = []
     """
     if isinstance(a, ExprMem):
@@ -1490,15 +1479,15 @@ def fcom(a):
     e.append(ExprAff(float_c3, ExprOp('fcom_c3', float_st0, src)))
     return e
 
-def ficom(a):
+def ficom(info, a):
     return []
 
-def fcomp(a):
+def fcomp(info, a):
     e= fcom(a)
     e+=float_pop()
     return e
 
-def fld(a):
+def fld(info, a):
     if isinstance(a, ExprMem):
         src = ExprOp('mem_%.2d_to_double'%a.get_size(), a)
     else:
@@ -1516,7 +1505,7 @@ def fld(a):
     e.append(ExprAff(float_stack_ptr, ExprOp('+', float_stack_ptr, ExprInt(uint32(1)))))
     return e
 
-def fst(a):
+def fst(info, a):
     e = []
     if isinstance(a, ExprMem):
         src = ExprOp('double_to_mem_%2d'%a.get_size(), float_st0)
@@ -1525,38 +1514,38 @@ def fst(a):
     e.append(ExprAff(a, src))
     return e
 
-def fstp(a):
+def fstp(info, a):
     e = fst(a)
     e+=float_pop(a)
     return e
 
-def fist(a):
+def fist(info, a):
     e = []
     e.append(ExprAff(a, ExprOp('double_to_int_32', float_st0)))
     return e
 
-def fistp(a):
+def fistp(info, a):
     e = fist(a)
     e+=float_pop(a)
     return e
 
-def fild(a):
+def fild(info, a):
     #XXXXX
     src = ExprOp('int_%.2d_to_double'%a.get_size(), a)
     return fld(src)
 
-def fldz():
+def fldz(info):
     return fld(ExprOp('int_32_to_double', ExprInt(uint32(0))))
 
-def fld1():
+def fld1(info):
     return fld(ExprOp('int_32_to_double', ExprInt(uint32(1))))
 
-def fldl2e():
+def fldl2e(info):
     x = struct.pack('d', 1/math.log(2))
     x = struct.unpack('Q', x)[0]
     return fld(ExprOp('mem_64_to_double', ExprInt(uint64(x))))
 
-def fadd(a, b = None):
+def fadd(info, a, b = None):
     if b == None:
         b = a
         a = float_st0
@@ -1568,7 +1557,7 @@ def fadd(a, b = None):
     e.append(ExprAff(a, ExprOp('fadd', a, src)))
     return e
 
-def faddp(a, b = None):
+def faddp(info, a, b = None):
     e = fadd(a, b)
     if b == None:
         e+=float_pop(float_st0)
@@ -1576,11 +1565,11 @@ def faddp(a, b = None):
         e+=float_pop(a)
     return e
 
-def fninit():
+def fninit(info):
     return []
 
 
-def fsub(a, b = None):
+def fsub(info, a, b = None):
     if b == None:
         b = a
         a = float_st0
@@ -1592,7 +1581,7 @@ def fsub(a, b = None):
     e.append(ExprAff(a, ExprOp('fsub', a, src)))
     return e
 
-def fmul(a, b = None):
+def fmul(info, a, b = None):
     if b == None:
         b = a
         a = float_st0
@@ -1604,7 +1593,7 @@ def fmul(a, b = None):
     e.append(ExprAff(a, ExprOp('fmul', a, src)))
     return e
 
-def fdiv(a, b = None):
+def fdiv(info, a, b = None):
     if b == None:
         b = a
         a = float_st0
@@ -1616,7 +1605,7 @@ def fdiv(a, b = None):
     e.append(ExprAff(a, ExprOp('fdiv', a, src)))
     return e
 
-def ftan(a):
+def ftan(info, a):
     e = []
     if isinstance(a, ExprMem):
         src = ExprOp('mem_%.2d_to_double'%a.get_size(), a)
@@ -1625,7 +1614,7 @@ def ftan(a):
     e.append(ExprAff(float_st0, ExprOp('ftan', src)))
     return e
 
-def fxch(a):
+def fxch(info, a):
     e = []
     if isinstance(a, ExprMem):
         src = ExprOp('mem_%.2d_to_double'%a.get_size(), a)
@@ -1635,7 +1624,7 @@ def fxch(a):
     e.append(ExprAff(src, float_st0))
     return e
 
-def fptan():
+def fptan(info):
     e= []
     e.append(ExprAff(float_st7, float_st6))
     e.append(ExprAff(float_st6, float_st5))
@@ -1655,43 +1644,43 @@ def fptan():
     return e
 
 
-def frndint():
+def frndint(info):
     e = []
     e.append(ExprAff(float_st0, ExprOp('frndint', float_st0)))
     return e
 
-def fsin():
+def fsin(info):
     e = []
     e.append(ExprAff(float_st0, ExprOp('fsin', float_st0)))
     return e
 
-def fcos():
+def fcos(info):
     e = []
     e.append(ExprAff(float_st0, ExprOp('fcos', float_st0)))
     return e
 
-def fscale():
+def fscale(info):
     e = []
     e.append(ExprAff(float_st0, ExprOp('fscale', float_st0, float_st1)))
     return e
 
-def f2xm1():
+def f2xm1(info):
     e = []
     e.append(ExprAff(float_st0, ExprOp('f2xm1', float_st0)))
     return e
 
-def fsqrt():
+def fsqrt(info):
     e = []
     e.append(ExprAff(float_st0, ExprOp('fsqrt', float_st0)))
     return e
 
-def fabs():
+def fabs(info):
     e = []
     e.append(ExprAff(float_st0, ExprOp('fabs', float_st0)))
     return e
 
 
-def fnstsw():
+def fnstsw(info):
     dst = eax
     return [ExprAff(dst, ExprCompose([ExprSliceTo(ExprInt(uint32(0)), 0, 8),
                                       ExprSliceTo(float_c0, 8, 9),
@@ -1703,39 +1692,39 @@ def fnstsw():
                                       ExprSliceTo(ExprSlice(dst, 16, dst.get_size()), 16, dst.get_size())
                                       ]))]
 
-def fnstcw(a):
+def fnstcw(info, a):
     e = []
     e.append(ExprAff(a, float_control))
     return e
 
-def fldcw(a):
+def fldcw(info, a):
     e = []
     e.append(ExprAff(float_control, a))
     return e
 
-def fwait():
+def fwait(info):
     return []
 
-def nop():
+def nop(info):
     return []
 
-def hlt():
+def hlt(info):
     return []
 
-def rdtsc():
+def rdtsc(info):
     e = []
     e.append(ExprAff(tsc1, ExprOp('+', tsc1, ExprInt(uint32(1)))))
     e.append(ExprAff(eax, tsc1))
     e.append(ExprAff(edx, tsc2))
     return e
 
-def cbw(a):
+def cbw(info, a):
     e = []
     cast_int = tab_uintsize[a.get_size()]
     b = ExprOp('<<', ExprInt(cast_int(-1)),
                      ExprInt(cast_int(a.get_size()/2)))
 
-    e.append(ExprAff(a, ExprCond( 
+    e.append(ExprAff(a, ExprCond(
                          ExprOp('==', ExprInt(cast_int(0)),
                                      ExprOp('&', a, ExprOp('<<',ExprInt(cast_int(1)), 
                                                                 ExprOp('-', ExprInt(cast_int(a.get_size()/2)), 
@@ -1743,52 +1732,51 @@ def cbw(a):
                                                                       )
                                                     )
                                            )
-                               ), 
+                               ),
                          a,
                          ExprOp('|', a, b),
                          )
             ))
-                   
     return e
-    
+
 # XXX TODO
-def daa():
-	return []
+def daa(info):
+    return []
 
-def aam(a):
-	return []
+def aam(info, a):
+    return []
 
-def aad(a):
-	return []
+def aad(info, a):
+    return []
 
-def aaa():
-	return []
+def aaa(info, ):
+    return []
 
-def bsf(a, b):
+def bsf(info, a, b):
     e = []
     cast_int = tab_uintsize[b.get_size()]
     e.append(ExprAff(a, ExprOp('bsf', a, b)))
     e.append(ExprAff(zf, ExprOp('==', ExprInt(cast_int(0)), b)))
     return e
-    
-def bsr(a, b):
+
+def bsr(info, a, b):
     e = []
     cast_int = tab_uintsize[b.get_size()]
     e.append(ExprAff(a, ExprOp('bsr', a, b)))
     e.append(ExprAff(zf, ExprOp('==', ExprInt(cast_int(0)), b)))
     return e
 
-def arpl(a, b):
+def arpl(info, a, b):
     e= []
     e.append(ExprAff(ExprId('vmcpu.vm_exception_flags'), ExprInt(uint32(1<<7))))
     return e
 
-def ins():
+def ins(info):
     e= []
     e.append(ExprAff(ExprId('vmcpu.vm_exception_flags'), ExprInt(uint32(1<<7))))
     return e
 
-def sidt(a):
+def sidt(info, a):
     e = []
     if not isinstance(a, ExprMem) or a.size!=32:
       raise 'not exprmem 32bit instance!!'
@@ -1800,47 +1788,47 @@ def sidt(a):
     return e
 
 
-def cmovz(a, b):
+def cmovz(info, a, b):
     e= []
     e.append(ExprAff(a, ExprCond(ExprOp('==', zf, ExprInt(uint32(1))), b, a)))
     return e
-def cmovnz(a, b):
+def cmovnz(info, a, b):
     e= []
     e.append(ExprAff(a, ExprCond(ExprOp('==', zf, ExprInt(uint32(0))), b, a)))
     return e
 
 #XXX
-def l_int(a):
+def l_int(info, a):
     e= []
     e.append(ExprAff(ExprId('vmcpu.vm_exception_flags'), ExprInt(uint32(1<<1)))) #SOFT BP
     return e
 
-def l_sysenter():
+def l_sysenter(info):
     e= []
     e.append(ExprAff(ExprId('vmcpu.vm_exception_flags'), ExprInt(uint32(EXCEPT_PRIV_INSN))))
     return e
 
 #XXX
-def l_out(a, b):
+def l_out(info, a, b):
     e= []
     e.append(ExprAff(ExprId('vmcpu.vm_exception_flags'), ExprInt(uint32(EXCEPT_PRIV_INSN))))
     return e
 
 #XXX
-def l_outs():
+def l_outs(info):
     e= []
     e.append(ExprAff(ExprId('vmcpu.vm_exception_flags'), ExprInt(uint32(EXCEPT_PRIV_INSN)))) #SOFT BP
     return e
 
 # XXX actually, xlat performs al = (ds:[e]bx + ZeroExtend(al))
-def xlat():
+def xlat(info):
     e= []
     a = ExprCompose([ExprSliceTo(ExprInt(uint32(0)), 8, 32), ExprSliceTo(eax[0:8], 0, 8)])
     b = ExprMem(ExprOp('+', ebx, a), 8)
     e.append(ExprAff(eax[0:8], b))
     return e
 
-def cpuid():
+def cpuid(info):
     e = []
     e.append(ExprAff(eax, ExprOp('cpuid', eax, ExprInt(uint32(0)))))
     e.append(ExprAff(ebx, ExprOp('cpuid', eax, ExprInt(uint32(1)))))
@@ -1848,7 +1836,7 @@ def cpuid():
     e.append(ExprAff(edx, ExprOp('cpuid', eax, ExprInt(uint32(3)))))
     return e
 
-def bt(a, b):
+def bt(info, a, b):
     cast_int = tab_uintsize[a.get_size()]
     e= []
     c= ExprOp('&', b, ExprInt(cast_int(b.get_size() - 1)))
@@ -1856,7 +1844,7 @@ def bt(a, b):
     e.append(ExprAff(cf, ExprOp('&', d, ExprInt(cast_int(1)))))
     return e
 
-def btc(a, b):
+def btc(info, a, b):
     cast_int = tab_uintsize[a.get_size()]
     e= []
     c= ExprOp('&', b, ExprInt(cast_int(b.get_size() - 1)))
@@ -1866,7 +1854,7 @@ def btc(a, b):
     e.append(ExprAff(a, ExprOp('^', a, m)))
     return e
 
-def bts(a, b):
+def bts(info, a, b):
     cast_int = tab_uintsize[a.get_size()]
     e= []
     c= ExprOp('&', b, ExprInt(cast_int(b.get_size() - 1)))
@@ -1876,7 +1864,7 @@ def bts(a, b):
     e.append(ExprAff(a, ExprOp('|', a, m)))
     return e
 
-def btr(a, b):
+def btr(info, a, b):
     cast_int = tab_uintsize[a.get_size()]
     e= []
     c= ExprOp('&', b, ExprInt(cast_int(b.get_size() - 1)))
@@ -1887,13 +1875,13 @@ def btr(a, b):
     return e
 
 
-def into():
+def into(info):
     return []
 
-def l_in(a, b):
+def l_in(info, a, b):
     return []
 
-def cmpxchg(a, b, c):
+def cmpxchg(info, a, b, c):
     e = []
     cast_int = tab_uintsize[a.get_size()]
 
@@ -1908,9 +1896,7 @@ def cmpxchg(a, b, c):
                                  c)
                      ))
     return e
-    
-    
-    
+
 mnemo_func = {'mov': mov,
               'xchg': xchg,
               'movzx': movzx,
@@ -1934,7 +1920,7 @@ mnemo_func = {'mov': mov,
               'rcr':rcr,
               'sar':sar,
               'shr':shr,
-              'shrd_cl':shrd_cl,              
+              'shrd_cl':shrd_cl,
               'sal':sal,
               'shl':shl,
               'shld_cl':shld_cl,
@@ -1962,12 +1948,12 @@ mnemo_func = {'mov': mov,
               'sets':sets,
               'seto':seto,
               'bswap':bswap,
-              'cmpsb':cmpsb,
-              'cmpsw':cmpsw,
-              'cmpsd':cmpsd,
-              'scasb':scasb,
-              'scasw':scasw,
-              'scasd':scasd,
+              'cmpsb':cmps,
+              'cmpsw':cmps,
+              'cmpsd':cmps,
+              'scasb':scas,
+              'scasw':scas,
+              'scasd':scas,
               'pushfd':pushfd,
               'pushfw':pushfw,
               'popfd':popfd,
@@ -2010,15 +1996,15 @@ mnemo_func = {'mov': mov,
               'aad':aad,
               'aaa':aaa,
               'shrd':shrd,
-              'stosb':stosb,
-              'stosw':stosw,
-              'stosd':stosd,
-              'lodsb':lodsb,
-              'lodsw':lodsw,
-              'lodsd':lodsd,
-              'movsb':movsb,
-              'movsw':movsw,
-              'movsd':movsd,
+              'stosb':stos,
+              'stosw':stos,
+              'stosd':stos,
+              'lodsb':lods,
+              'lodsw':lods,
+              'lodsd':lods,
+              'movsb':movs,
+              'movsw':movs,
+              'movsd':movs,
               'fcomp':fcomp,
               'nop':nop,
               'fnop':nop, #XXX
@@ -2199,15 +2185,14 @@ class ia32_rexpr:
 
 
 
-def dict_to_Expr(d, modifs = {}, mnemo_mode = x86_afs.u32):
+def dict_to_Expr(d, modifs = {}, opmode = u32, admode = u32, segm_to_do = {}):
     size = [x86_afs.u32, x86_afs.u08][modifs[w8]==True]
     #overwrite w8
     if modifs[sd]!=None:
         size = [x86_afs.f32, x86_afs.f64][modifs[sd]==True]
-    if modifs[wd]:
+    elif modifs[wd]:
         size = x86_afs.u16
 
-                
     tab32 = {ia32_rexpr.u08:ia32_rexpr.reg_list8, ia32_rexpr.u16:ia32_rexpr.reg_list16, ia32_rexpr.u32:ia32_rexpr.reg_list32,ia32_rexpr.f32:ia32_rexpr.reg_flt}
     tab16 = {ia32_rexpr.u08:ia32_rexpr.reg_list8, ia32_rexpr.u16:ia32_rexpr.reg_list32, ia32_rexpr.u32:ia32_rexpr.reg_list16}
     ad_size = {ia32_rexpr.u08:ia32_rexpr.u08, ia32_rexpr.u16:ia32_rexpr.u16, ia32_rexpr.u32:ia32_rexpr.u32, ia32_rexpr.f32:ia32_rexpr.u32, ia32_rexpr.f64:ia32_rexpr.u32}
@@ -2215,7 +2200,7 @@ def dict_to_Expr(d, modifs = {}, mnemo_mode = x86_afs.u32):
     if is_reg(d):
         n = [x for x in d if type(x) in [int, long]]
         if len(n)!=1:
-            raise "bad reg! %s"%str(d)
+            raise ValueError("bad reg! %s"%str(d))
         n = n[0]
         if x86_afs.size in d and d[x86_afs.size] == x86_afs.size_seg :
             t = ia32_rexpr.reg_listsg
@@ -2225,7 +2210,7 @@ def dict_to_Expr(d, modifs = {}, mnemo_mode = x86_afs.u32):
                 my_s = x86_afs.u32
             t = tab32[my_s]
         else:
-            if mnemo_mode == u32:
+            if opmode == u32:
                 t = tab32[size]
             else:
                 t = tab16[size]
@@ -2241,18 +2226,17 @@ def dict_to_Expr(d, modifs = {}, mnemo_mode = x86_afs.u32):
         if modifs[sd] is not None:
             t = tab32[size]
             n&=7
-        
+
         out = t[n]
     elif is_imm(d):
         if ia32_rexpr.imm in d:
             #test bug imm 16b
-            if mnemo_mode == x86_afs.u16:
+            if opmode == x86_afs.u16:
                 if size == x86_afs.u16:
                     size = x86_afs.u32
                 else:
                     size = x86_afs.u16
-        
-            
+
             #print d
             out = ExprInt(tab_afs_int[size](d[ia32_rexpr.imm]))
         if ia32_rexpr.symb in d:
@@ -2270,9 +2254,10 @@ def dict_to_Expr(d, modifs = {}, mnemo_mode = x86_afs.u32):
                 return ExprId(myname.name)
             return ExprInt(uint32(myval))
     elif is_address(d):
-        
+        int_cast = tab_afs_int[admode]
+        segm = None
+
         size = {ia32_rexpr.u08:8, ia32_rexpr.u16:16, ia32_rexpr.u32:32, ia32_rexpr.f32:32, ia32_rexpr.f64:64}[size]
-        
         if ia32_rexpr.size in d:
             size = d[ia32_rexpr.size]
         msize = {ia32_rexpr.u08:8, ia32_rexpr.u16:16, ia32_rexpr.u32:32, ia32_rexpr.f32:32, ia32_rexpr.f64:64}
@@ -2285,15 +2270,23 @@ def dict_to_Expr(d, modifs = {}, mnemo_mode = x86_afs.u32):
             if k in [ia32_rexpr.ad, ia32_rexpr.size]:
                 continue
             elif k in [ia32_rexpr.segm]:
-                if d[k] == 4:
-                    out.append(ExprInt(uint32(0x7FF70000)))
+                if d[k] in segm_to_do:
+                    segm = x86_afs.reg_sg[d[k]]
+                    segm =  segm_dict[segm]
             elif k == ia32_rexpr.imm:
                 out.append(ExprInt(d[k]))
             elif type(k) in [int, long]:
                 if d[k] ==1:
-                    out.append(ia32_rexpr.reg_list32[k])
+                    if admode == u16:
+                        out.append(ia32_rexpr.reg_list16[k])
+                    else:
+                        out.append(ia32_rexpr.reg_list32[k])
                 else:
-                    out.append(ExprOp('*', ExprInt(uint32(d[k])), ia32_rexpr.reg_list32[k]))
+                    if admode == u16:
+                        out.append(ExprOp('*', ExprInt(int_cast(d[k])), ia32_rexpr.reg_list16[k]))
+                    else:
+                        out.append(ExprOp('*', ExprInt(int_cast(d[k])), ia32_rexpr.reg_list32[k]))
+
             elif k == ia32_rexpr.symb:
                 print 'warning: symbol.. in mem look', d[k]
                 out.append(ExprId(str(d[k].items()[0][0].name)))
@@ -2304,8 +2297,7 @@ def dict_to_Expr(d, modifs = {}, mnemo_mode = x86_afs.u32):
         e = out[0]
         for o in out[1:]:
             e = ExprOp('+', e, o)
-        out = ExprMem(e, size)
-        
+        out = ExprMem(e, size, segm)
     else:
         raise 'unknown arg %s'%str(d)
     return out
diff --git a/miasm/expression/expression.py b/miasm/expression/expression.py
index 5108deab..55e7e265 100644
--- a/miasm/expression/expression.py
+++ b/miasm/expression/expression.py
@@ -334,11 +334,14 @@ class ExprCond(Expr):
         return "(%s?%s:%s)"%(self.cond.toC(), self.src1.toC(), self.src2.toC())
 
 class ExprMem(Expr):
-    def __init__(self, arg, size = 32):
+    def __init__(self, arg, size = 32, segm = None):
         if not isinstance(arg, Expr): raise 'arg must be expr'
-        self.arg, self.size = arg, size
+        self.arg, self.size, self.segm = arg, size, segm
     def __str__(self):
-        return "@%d[%s]"%(self.size, str(self.arg))
+        if self.segm:
+            return "%s:@%d[%s]"%(self.segm, self.size, str(self.arg))
+        else:
+            return "@%d[%s]"%(self.size, str(self.arg))
     def get_r(self, mem_read=False):
         if mem_read:
             return set(self.arg.get_r(mem_read).union(set([self])))
@@ -352,10 +355,13 @@ class ExprMem(Expr):
         if self in g:
             return g[self]
         arg = self.arg
+        segm = self.segm
         if isinstance(arg, Expr):
             arg = self.arg.reload_expr(g)
+        if isinstance(segm, Expr):
+            segm = self.segm.reload_expr(g)
 
-        return ExprMem(arg, self.size )
+        return ExprMem(arg, self.size, segm)
     def __contains__(self, e):
         return self == e or self.arg.__contains__(e)
 
@@ -363,18 +369,20 @@ class ExprMem(Expr):
         if self in g:
             return g[self]
         arg = self.arg.replace_expr(g)
-        return ExprMem(arg, self.size )
+        return ExprMem(arg, self.size, self.segm)
 
     def __eq__(self, a):
         if not isinstance(a, ExprMem):
             return False
-        return self.arg == a.arg and self.size == a.size
+        return self.arg == a.arg and self.size == a.size and self.segm == a.segm
     def __hash__(self):
-        return hash(self.arg)^hash(self.size)
+        return hash(self.arg)^hash(self.size)^hash(self.segm)
 
     def toC(self):
-        return "MEM_LOOKUP_%.2d(%s)"%(self.size, self.arg.toC())
-
+        if self.segm:
+            return "MEM_LOOKUP_%.2d_SEGM(%s, %s)"%(self.size, self.segm.toC(), self.arg.toC())
+        else:
+            return "MEM_LOOKUP_%.2d(%s)"%(self.size, self.arg.toC())
 
 class ExprOp(Expr):
     def __init__(self, op, *args):
diff --git a/miasm/tools/emul_helper.py b/miasm/tools/emul_helper.py
index 3b3f58c5..f89d3bf5 100755
--- a/miasm/tools/emul_helper.py
+++ b/miasm/tools/emul_helper.py
@@ -164,13 +164,6 @@ def get_instr_expr_args(name, modifs, mnemo_mode, args, my_eip):
         e = mnemo_func[name](*args)
     return e
 """
-###XXX for eval int 
-def get_instr_expr(l, my_eip, args = None):
-    if args==None:args = []
-    for x in l.arg:
-        args.append(dict_to_Expr(x, l.m.modifs, l.mnemo_mode))
-    l.arg_expr = args
-    return get_instr_expr_args(l.m.name, l.m.modifs, l.mnemo_mode, args, my_eip)
 
 
 #"""
@@ -194,11 +187,12 @@ def get_instr_expr_args(name, modifs, mnemo_mode, args, my_eip):
         e = mnemo_func[name](*args)
     return e
 #"""
+
 ###XXX for eval abs
-def get_instr_expr(l, my_eip, args = None):
+def get_instr_expr(l, my_eip, args = None, segm_to_do = {}):
     if args==None:args = []
     for x in l.arg:
-        args.append(dict_to_Expr(x, l.m.modifs, l.mnemo_mode))
+        args.append(dict_to_Expr(x, l.m.modifs, l.opmode, l.admode, segm_to_do))
     l.arg_expr = args
     return get_instr_expr_args(l.m.name, l.m.modifs, l.mnemo_mode, args, my_eip)
 
@@ -625,7 +619,7 @@ def guess_func_destack(all_bloc):
     return False, a[x86_afs.imm]
 
 
-def digest_allbloc_instr(all_bloc):
+def digest_allbloc_instr(all_bloc, segm_to_do = {}):
     instrs = {}
     g = asmbloc.bloc2graph(all_bloc)
     open("graph_b.txt" , "w").write(g)
@@ -657,7 +651,7 @@ def digest_allbloc_instr(all_bloc):
                 if str(instrs[l.offset][0]) != str(l):
                     raise ValueError('dup instr@ with different instr', (str(l), str(instrs[l.offset][0])))
             args = []
-            ex = get_instr_expr(l, ExprInt(uint32(l.offset+l.l)), args)
+            ex = get_instr_expr(l, ExprInt(uint32(l.offset+l.l)), args, segm_to_do = segm_to_do)
 
                 
             instrs[l.offset] = (l, ex)
diff --git a/miasm/tools/emul_lib/libcodenat.c b/miasm/tools/emul_lib/libcodenat.c
index ca9415a0..aca3a41d 100644
--- a/miasm/tools/emul_lib/libcodenat.c
+++ b/miasm/tools/emul_lib/libcodenat.c
@@ -323,24 +323,48 @@ void MEM_WRITE_08(uint64_t addr, unsigned char src)
 	memory_page_write(8, addr, src);
 }
 
+void MEM_WRITE_08_SEGM(uint16_t segm, uint64_t addr, unsigned char src)
+{
+	check_write_code_bloc(8, addr + vmcpu.segm_base[segm]);
+	memory_page_write(8, addr + vmcpu.segm_base[segm], src);
+}
+
 void MEM_WRITE_16(uint64_t addr, unsigned short src)
 {
 	check_write_code_bloc(16, addr);
 	memory_page_write(16, addr, src);
 }
 
+void MEM_WRITE_16_SEGM(uint16_t segm, uint64_t addr, unsigned short src)
+{
+	check_write_code_bloc(16, addr + vmcpu.segm_base[segm]);
+	memory_page_write(16, addr + vmcpu.segm_base[segm], src);
+}
+
 void MEM_WRITE_32(uint64_t addr, unsigned int src)
 {
 	check_write_code_bloc(32, addr);
 	memory_page_write(32, addr, src);
 }
 
+void MEM_WRITE_32_SEGM(uint16_t segm, uint64_t addr, unsigned int src)
+{
+	check_write_code_bloc(32, addr + vmcpu.segm_base[segm]);
+	memory_page_write(32, addr + vmcpu.segm_base[segm], src);
+}
+
 void MEM_WRITE_64(uint64_t addr, uint64_t src)
 {
 	check_write_code_bloc(64, addr);
 	memory_page_write(64, addr, src);
 }
 
+void MEM_WRITE_64_SEGM(uint16_t segm, uint64_t addr, uint64_t src)
+{
+	check_write_code_bloc(64, addr + vmcpu.segm_base[segm]);
+	memory_page_write(64, addr + vmcpu.segm_base[segm], src);
+}
+
 
 unsigned int MEM_LOOKUP(unsigned int my_size, uint64_t addr)
 {
@@ -356,6 +380,13 @@ unsigned char MEM_LOOKUP_08(uint64_t addr)
     return ret;
 }
 
+unsigned char MEM_LOOKUP_08_SEGM(uint16_t segm, uint64_t addr)
+{
+    unsigned char ret;
+    ret = memory_page_read(8, addr + vmcpu.segm_base[segm]);
+    return ret;
+}
+
 unsigned short MEM_LOOKUP_16(uint64_t addr)
 {
     unsigned short ret;
@@ -363,6 +394,13 @@ unsigned short MEM_LOOKUP_16(uint64_t addr)
     return ret;
 }
 
+unsigned short MEM_LOOKUP_16_SEGM(uint16_t segm, uint64_t addr)
+{
+    unsigned short ret;
+    ret = memory_page_read(16, addr + vmcpu.segm_base[segm]);
+    return ret;
+}
+
 unsigned int MEM_LOOKUP_32(uint64_t addr)
 {
     unsigned int ret;
@@ -370,6 +408,13 @@ unsigned int MEM_LOOKUP_32(uint64_t addr)
     return ret;
 }
 
+unsigned int MEM_LOOKUP_32_SEGM(uint16_t segm, uint64_t addr)
+{
+    unsigned int ret;
+    ret = memory_page_read(32, addr + vmcpu.segm_base[segm]);
+    return ret;
+}
+
 uint64_t MEM_LOOKUP_64(uint64_t addr)
 {
     uint64_t ret;
@@ -377,6 +422,13 @@ uint64_t MEM_LOOKUP_64(uint64_t addr)
     return ret;
 }
 
+uint64_t MEM_LOOKUP_64_SEGM(uint16_t segm, uint64_t addr)
+{
+    uint64_t ret;
+    ret = memory_page_read(64, addr + vmcpu.segm_base[segm]);
+    return ret;
+}
+
 void vm_throw(unsigned long flags)
 {
 	vmcpu.vm_exception_flags |= flags;
diff --git a/miasm/tools/emul_lib/libcodenat.h b/miasm/tools/emul_lib/libcodenat.h
index 26d6b850..bb123096 100644
--- a/miasm/tools/emul_lib/libcodenat.h
+++ b/miasm/tools/emul_lib/libcodenat.h
@@ -116,7 +116,6 @@ typedef struct {
 
 	unsigned int cond;
 
-	unsigned int ds;
 	unsigned int vm_exception_flags;
 	unsigned int vm_exception_flags_new;
 	unsigned int vm_last_write_ad;
@@ -165,6 +164,21 @@ typedef struct {
 	unsigned int tsc1_new;
 	unsigned int tsc2_new;
 
+
+	uint16_t es;
+	uint16_t cs;
+	uint16_t ss;
+	uint16_t ds;
+	uint16_t fs;
+	uint16_t gs;
+
+	uint16_t es_new;
+	uint16_t cs_new;
+	uint16_t ss_new;
+	uint16_t ds_new;
+	uint16_t fs_new;
+	uint16_t gs_new;
+
 	unsigned int cr0;
 	unsigned int cr0_new;
 
@@ -207,7 +221,7 @@ typedef struct {
 	uint64_t pfmem64_6;
 	uint64_t pfmem64_7;
 
-
+	uint32_t segm_base[0x10000];
 
 }vm_cpu_t;
 
@@ -270,6 +284,11 @@ void MEM_WRITE_16(uint64_t addr, unsigned short src);
 void MEM_WRITE_32(uint64_t addr, unsigned int src);
 void MEM_WRITE_64(uint64_t addr, uint64_t src);
 
+void MEM_WRITE_08_SEGM(uint16_t segm, uint64_t addr, unsigned char src);
+void MEM_WRITE_16_SEGM(uint16_t segm, uint64_t addr, unsigned short src);
+void MEM_WRITE_32_SEGM(uint16_t segm, uint64_t addr, unsigned int src);
+void MEM_WRITE_64_SEGM(uint16_t segm, uint64_t addr, uint64_t src);
+
 
 unsigned char MEM_LOOKUP_08(uint64_t addr);
 unsigned short MEM_LOOKUP_16(uint64_t addr);
@@ -277,6 +296,12 @@ unsigned int MEM_LOOKUP_32(uint64_t addr);
 uint64_t MEM_LOOKUP_64(uint64_t addr);
 
 
+unsigned char MEM_LOOKUP_08_SEGM(uint16_t segm, uint64_t addr);
+unsigned short MEM_LOOKUP_16_SEGM(uint16_t segm, uint64_t addr);
+unsigned int MEM_LOOKUP_32_SEGM(uint16_t segm, uint64_t addr);
+uint64_t MEM_LOOKUP_64_SEGM(uint16_t segm, uint64_t addr);
+
+
 
 
 void MEM_WRITE_08_PASSTHROUGH(uint64_t addr, unsigned char src);
@@ -340,6 +365,11 @@ typedef struct _reg_dict{
     unsigned int* ptr;
 } reg_dict;
 
+typedef struct _reg_segm_dict{
+    char* name;
+    uint16_t* ptr;
+} reg_segm_dict;
+
 typedef struct _reg_float_dict{
     char* name;
     void* ptr;
diff --git a/miasm/tools/emul_lib/libcodenat_interface.c b/miasm/tools/emul_lib/libcodenat_interface.c
index ce402e07..d43401dd 100644
--- a/miasm/tools/emul_lib/libcodenat_interface.c
+++ b/miasm/tools/emul_lib/libcodenat_interface.c
@@ -208,6 +208,105 @@ PyObject* _vm_set_gpreg(PyObject *dict)
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+PyObject* _vm_get_segm(void)
+{
+    PyObject *dict = PyDict_New();
+    PyObject *o;
+
+    o = PyInt_FromLong((long)vmcpu.es);
+    PyDict_SetItemString(dict, "es", o);
+    Py_DECREF(o);
+    o = PyInt_FromLong((long)vmcpu.cs);
+    PyDict_SetItemString(dict, "cs", o);
+    Py_DECREF(o);
+    o = PyInt_FromLong((long)vmcpu.ss);
+    PyDict_SetItemString(dict, "ss", o);
+    Py_DECREF(o);
+    o = PyInt_FromLong((long)vmcpu.ds);
+    PyDict_SetItemString(dict, "ds", o);
+    Py_DECREF(o);
+    o = PyInt_FromLong((long)vmcpu.fs);
+    PyDict_SetItemString(dict, "fs", o);
+    Py_DECREF(o);
+    o = PyInt_FromLong((long)vmcpu.gs);
+    PyDict_SetItemString(dict, "gs", o);
+    Py_DECREF(o);
+
+
+
+    return dict;
+}
+
+
+reg_segm_dict segm_dict[] = { {.name = "es", .ptr = &(vmcpu.es)},
+			      {.name = "cs", .ptr = &(vmcpu.cs)},
+			      {.name = "ss", .ptr = &(vmcpu.ss)},
+			      {.name = "ds", .ptr = &(vmcpu.ds)},
+			      {.name = "fs", .ptr = &(vmcpu.fs)},
+			      {.name = "gs", .ptr = &(vmcpu.gs)},
+
+
+};
+
+
+
+
+PyObject* _vm_set_segm(PyObject *dict)
+{
+    PyObject *d_key, *d_value = NULL;
+    Py_ssize_t pos = 0;
+    unsigned int val;
+    unsigned int i, found;
+
+    if(!PyDict_Check(dict))
+	    RAISE(PyExc_TypeError, "arg must be dict");
+    while(PyDict_Next(dict, &pos, &d_key, &d_value)){
+	    if(!PyString_Check(d_key))
+		    RAISE(PyExc_TypeError, "key must be str");
+
+	    if (PyInt_Check(d_value)){
+		    val = (unsigned int)PyInt_AsLong(d_value);
+	    }
+	    else if (PyLong_Check(d_value)){
+		    val = (unsigned int)PyInt_AsUnsignedLongLongMask(d_value);
+	    }
+	    else{
+		    RAISE(PyExc_TypeError,"value must be int");
+	    }
+
+	    found = 0;
+	    for (i=0; i < sizeof(segm_dict)/sizeof(reg_dict); i++){
+		    if (strcmp(PyString_AsString(d_key), segm_dict[i].name))
+			    continue;
+		    *(segm_dict[i].ptr) = val;
+		    found = 1;
+		    break;
+	    }
+
+	    if (found)
+		    continue;
+	    fprintf(stderr, "unkown key: %s\n", PyString_AsString(d_key));
+	    RAISE(PyExc_ValueError, "unkown reg");
+    }
+    return NULL;
+}
+
+
+
+
+
+
 PyObject* _vm_get_float(void)
 {
     PyObject *dict = PyDict_New();
@@ -724,7 +823,24 @@ PyObject* vm_set_gpreg(PyObject *self, PyObject *args)
 	_vm_set_gpreg(dict);
 	Py_INCREF(Py_None);
 	return Py_None;
+}
 
+
+PyObject* vm_get_segm(PyObject* self, PyObject* args)
+{
+    PyObject* p;
+    p = _vm_get_segm();
+    return p;
+}
+
+PyObject* vm_set_segm(PyObject *self, PyObject *args)
+{
+	PyObject* dict;
+	if (!PyArg_ParseTuple(args, "O", &dict))
+		return NULL;
+	_vm_set_segm(dict);
+	Py_INCREF(Py_None);
+	return Py_None;
 }
 
 PyObject* vm_get_float(PyObject* self, PyObject* args)
@@ -933,6 +1049,60 @@ unsigned int get_memory_page_from_min_ad_py(unsigned int size)
 }
 
 
+PyObject* vm_get_segm_base(PyObject* self, PyObject* args)
+{
+	PyObject *item1;
+	unsigned int segm_num;
+	PyObject* v;
+
+	if (!PyArg_ParseTuple(args, "O", &item1))
+		return NULL;
+	if (PyInt_Check(item1)){
+		segm_num = (unsigned int)PyInt_AsLong(item1);
+	}
+	else if (PyLong_Check(item1)){
+		segm_num = (unsigned int)PyInt_AsUnsignedLongLongMask(item1);
+	}
+	else{
+		RAISE(PyExc_TypeError,"arg1 must be int");
+	}
+	v = PyInt_FromLong((long)vmcpu.segm_base[segm_num]);
+	return v;
+}
+
+PyObject* vm_set_segm_base(PyObject* self, PyObject* args)
+{
+	PyObject *item1, *item2;
+	unsigned int segm_num, segm_base;
+
+	if (!PyArg_ParseTuple(args, "OO", &item1, &item2))
+		return NULL;
+	if (PyInt_Check(item1)){
+		segm_num = (unsigned int)PyInt_AsLong(item1);
+	}
+	else if (PyLong_Check(item1)){
+		segm_num = (unsigned int)PyInt_AsUnsignedLongLongMask(item1);
+	}
+	else{
+		RAISE(PyExc_TypeError,"arg1 must be int");
+	}
+	if (PyInt_Check(item2)){
+		segm_base = (unsigned int)PyInt_AsLong(item2);
+	}
+	else if (PyLong_Check(item2)){
+		segm_base = (unsigned int)PyInt_AsUnsignedLongLongMask(item2);
+	}
+	else{
+		RAISE(PyExc_TypeError,"arg2 must be int");
+	}
+	vmcpu.segm_base[segm_num] = segm_base;
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+
 PyObject* _vm_exec_blocs(PyObject* self, PyObject* args)
 {
 	PyObject* b;
@@ -1082,6 +1252,10 @@ static PyMethodDef CodenatMethods[] = {
      "X"},
     {"vm_set_gpreg",vm_set_gpreg, METH_VARARGS,
      "X"},
+    {"vm_get_segm", vm_get_segm, METH_VARARGS,
+     "X"},
+    {"vm_set_segm",vm_set_segm, METH_VARARGS,
+     "X"},
     {"vm_get_float", vm_get_float, METH_VARARGS,
      "X"},
     {"vm_set_float",vm_set_float, METH_VARARGS,
@@ -1136,6 +1310,10 @@ static PyMethodDef CodenatMethods[] = {
      "X"},
     {"vm_set_cpu_state",vm_set_cpu_state, METH_VARARGS,
      "X"},
+    {"vm_get_segm_base",vm_get_segm_base, METH_VARARGS,
+     "X"},
+    {"vm_set_segm_base",vm_set_segm_base, METH_VARARGS,
+     "X"},
 
     {NULL, NULL, 0, NULL}        /* Sentinel */
 
diff --git a/miasm/tools/to_c_helper.py b/miasm/tools/to_c_helper.py
index 601d7feb..f82b83ca 100644
--- a/miasm/tools/to_c_helper.py
+++ b/miasm/tools/to_c_helper.py
@@ -138,6 +138,15 @@ my_C_id = [
     #vm_last_write_size,
     tsc1,
     tsc2,
+
+
+    es ,
+    cs ,
+    ss ,
+    ds ,
+    fs ,
+    gs ,
+
     float_st0,
     float_st1,
     float_st2,
@@ -390,8 +399,8 @@ def Exp2C(exprs, l = None, addr2label = None, gen_exception_code = False):
     return out+out_eip, post_instr
 
 
-def bloc2C(all_bloc, addr2label = None, gen_exception_code = False, dbg_instr = False, dbg_reg = False, dbg_lbl = False, filtered_ad = None, tick_dbg = None):
-    all_instrs = digest_allbloc_instr(all_bloc)
+def bloc2C(all_bloc, addr2label = None, gen_exception_code = False, dbg_instr = False, dbg_reg = False, dbg_lbl = False, filtered_ad = None, tick_dbg = None, segm_to_do = {}):
+    all_instrs = digest_allbloc_instr(all_bloc, segm_to_do)
 
     if not addr2label:
         addr2label = lambda x:"loc_%.16X"%(x&mask_int)
@@ -487,19 +496,20 @@ def bloc2C(all_bloc, addr2label = None, gen_exception_code = False, dbg_instr =
 
 
 
-def bloc_gen_C_func(all_bloc, funcname, addr2label = None, gen_exception_code = False, dbg_instr = False, dbg_reg = False, dbg_lbl = False, filtered_ad = None, tick_dbg = None):
+def bloc_gen_C_func(all_bloc, funcname, addr2label = None, gen_exception_code = False, dbg_instr = False, dbg_reg = False, dbg_lbl = False, filtered_ad = None, tick_dbg = None, segm_to_do = {}):
     f_dec = 'uint64_t %s(void)'%funcname
     out = []
     out+=[f_dec,
           '{',
           ]
-    out += bloc2C(all_bloc, addr2label, gen_exception_code, dbg_instr, dbg_reg, dbg_lbl, filtered_ad, tick_dbg)
+    out += bloc2C(all_bloc, addr2label, gen_exception_code,
+                  dbg_instr, dbg_reg, dbg_lbl,
+                  filtered_ad, tick_dbg,
+                  segm_to_do)
     out+=['}',
           ]
     return f_dec, out
 
-    
-
 
 def gen_x86_core():
     import os
@@ -707,7 +717,7 @@ def asm2C(f_name, known_mems, dyn_func, in_str, x86_mn, symbol_pool, func_to_dis
     return funcs_code, dyn_dispatcher
 
 
-def gen_C_from_asmbloc(in_str, offset, symbol_pool, dont_dis = [], job_done = None, log_mn = False, log_reg = False, log_lbl = False, filtered_ad = [], tick_dbg = None, code_addr = [], all_bloc_funcs = [], **kargs):
+def gen_C_from_asmbloc(in_str, offset, symbol_pool, dont_dis = [], job_done = None, log_mn = False, log_reg = False, log_lbl = False, filtered_ad = [], tick_dbg = None, code_addr = [], all_bloc_funcs = [], segm_to_do = {}, **kargs):
     if job_done == None:
         job_done = set()
 
@@ -720,7 +730,7 @@ def gen_C_from_asmbloc(in_str, offset, symbol_pool, dont_dis = [], job_done = No
                      **kargs)
     f_dec, out = bloc_gen_C_func([cur_bloc], f_name, None, True,
                                  log_mn, log_reg, log_lbl,
-                                 filtered_ad, tick_dbg)
+                                 filtered_ad, tick_dbg, segm_to_do)
     #print "\n".join(out)
     return f_name, f_dec, out, cur_bloc
 
@@ -997,10 +1007,10 @@ def updt_bloc_emul(known_blocs, in_str, my_eip, symbol_pool, code_blocs_mem_rang
 '''    
 
 ttt = 0
-def updt_bloc_emul(known_blocs, in_str, my_eip, symbol_pool, code_blocs_mem_range, dont_dis = [], job_done = None, log_mn = False, log_regs = False, **kargs):
+def updt_bloc_emul(known_blocs, in_str, my_eip, symbol_pool, code_blocs_mem_range, dont_dis = [], job_done = None, log_mn = False, log_regs = False, segm_to_do = {}, **kargs):
     if job_done == None:
         job_done = set()
-    fname, f_dec, funcs_code, cur_bloc = gen_C_from_asmbloc(in_str, my_eip, symbol_pool, dont_dis, job_done, log_mn, log_regs, **kargs)
+    fname, f_dec, funcs_code, cur_bloc = gen_C_from_asmbloc(in_str, my_eip, symbol_pool, dont_dis, job_done, log_mn, log_regs, segm_to_do = segm_to_do, **kargs)
 
     dyn_dispatcher = """
     #define GOTO_DYNAMIC do {return %s;} while(0)