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]