metasm/cpu/ia32/decode.rb in metasm-1.0.2 vs metasm/cpu/ia32/decode.rb in metasm-1.0.3

- old
+ new

@@ -401,11 +401,16 @@ sz = [a1, :%, operandsize] isz = [[operandsize, :-, a1], :%, operandsize] # ror a, b => (a >> b) | (a << (32-b)) { a0 => Expression[[[[a0, :&, operandmask], e_op, sz], :|, [[a0, :&, operandmask], inv_op, isz]], :&, operandmask] } } - when 'sar', 'shl', 'sal'; lambda { |di, a0, a1| { a0 => Expression[a0, (op[-1] == ?r ? :>> : :<<), [a1, :%, [opsz(di), 32].max]] } } + when 'shl', 'sal'; lambda { |di, a0, a1| { a0 => Expression[a0, (op[-1] == ?r ? :>> : :<<), [a1, :%, [opsz(di), 32].max]] } } + when 'sar'; lambda { |di, a0, a1| + sz = [opsz(di), 32].max + a1 = [a1, :%, sz] + { a0 => Expression[[a0, :>>, a1], :|, + [[[mask[di], :*, sign[a0, di]], :<<, [sz, :-, a1]], :&, mask[di]]] } } when 'shr'; lambda { |di, a0, a1| { a0 => Expression[[a0, :&, mask[di]], :>>, [a1, :%, opsz(di)]] } } when 'shrd' lambda { |di, a0, a1, a2| { a0 => Expression[[a0, :>>, [a2, :%, opsz(di)]], :|, [a1, :<<, [[opsz(di), :-, a2], :%, opsz(di)]]] } } @@ -421,22 +426,22 @@ lambda { |di, a0| { esp => Expression[esp, :-, opsz(di)/8], Indirection[esp, opsz(di)/8, di.address] => Expression[a0] } } when 'pop' lambda { |di, a0| { esp => Expression[esp, :+, opsz(di)/8], a0 => Indirection[esp, opsz(di)/8, di.address] } } - when 'pushfd', 'pushf' + when 'pushfd', 'pushf', 'pushfq' # TODO Unknown per bit lambda { |di| efl = Expression[0x202] bts = lambda { |pos, v| efl = Expression[efl, :|, [[v, :&, 1], :<<, pos]] } bts[0, :eflag_c] bts[6, :eflag_z] bts[7, :eflag_s] bts[11, :eflag_o] { esp => Expression[esp, :-, opsz(di)/8], Indirection[esp, opsz(di)/8, di.address] => efl } } - when 'popfd', 'popf' + when 'popfd', 'popf', 'popfq' lambda { |di| bt = lambda { |pos| Expression[[Indirection[esp, opsz(di)/8, di.address], :>>, pos], :&, 1] } { esp => Expression[esp, :+, opsz(di)/8], :eflag_c => bt[0], :eflag_z => bt[6], :eflag_s => bt[7], :eflag_o => bt[11] } } when 'sahf' lambda { |di| bt = lambda { |pos| Expression[[eax, :>>, pos], :&, 1] } { :eflag_c => bt[0], :eflag_z => bt[6], :eflag_s => bt[7] } } @@ -549,10 +554,10 @@ lambda { |di, *a| next {:incomplete_binding => 1} if di.opcode.args.include?(:regxmm) # XXX movsd xmm0, xmm1... op =~ /^(stos|movs|lods|scas|cmps)([bwdq])$/ e_op = $1 sz = { 'b' => 1, 'w' => 2, 'd' => 4, 'q' => 8 }[$2] - eax_ = Reg.new(0, 8*sz).symbolic + eax_ = self.class::Reg.new(0, 8*sz).symbolic dir = :+ if di.block and (di.block.list.find { |ddi| ddi.opcode.name == 'std' } rescue nil) dir = :- end pesi = Indirection[esi, sz, di.address]