node/lib/metasm/metasm/cpu/ia32/encode.rb
# returns the byte representing the register encoded as modrm
# works with Reg/SimdReg
returns the byte representing the register encoded as modrm
works with Reg/SimdReg
returns the byte representing the register encoded as modrm works with Reg / SimdReg
def encode32(reg, endianness)
			 b => 0  1  2  3  4  5+i|i 6  7
			 i => 0  1  2  3 nil   5   6  7
			ret = EncodedData.new << (reg << 3)
			 add bits in the first octet of ret.data (1.9 compatibility layer)
			or_bits = lambda { |v|	 rape me
				if ret.data[0].kind_of? Integer
					ret.data[0] |= v
				else
					ret.data[0] = (ret.data[0].unpack('C').first | v).chr
				end
			}
			if not self.b and not self.i
				or_bits[5]
				[ret << @imm.encode(:a32, endianness)]
			elsif not self.b and self.s != 1
				 sib with no b
				raise EncodeError, "Invalid ModRM {self}" if @i.val == 4
				or_bits[4]
				s = {8=>3, 4=>2, 2=>1}[@s]
				imm = self.imm || Expression[0]
				fu = (s << 6) | (@i.val << 3) | 5
				fu = fu.chr if s >= 2	 rb1.9 encoding fix
				[ret << fu << imm.encode(:a32, endianness)]
			else
				imm = @imm.reduce if self.imm
				imm = nil if imm == 0
				if not self.i or (not self.b and self.s == 1)
					 no sib byte (except for [esp])
					b = self.b || self.i
					or_bits[b.val]
					ret << 0x24 if b.val == 4
				else
					 sib
					or_bits[4]
					i, b = @i, @b
					b, i = i, b if @s == 1 and (i.val == 4 or b.val == 5)
					raise EncodeError, "Invalid ModRM {self}" if i.val == 4
					s = {8=>3, 4=>2, 2=>1, 1=>0}[@s]
					fu = (s << 6) | (i.val << 3) | b.val
					fu = fu.chr if s >= 2	 rb1.9 encoding fix
					ret << fu
				end
				imm ||= 0 if b.val == 5
				if imm
					case Expression.in_range?(imm, :i8)
					when true
						or_bits[1<<6]
						[ret << Expression.encode_imm(imm, :i8, endianness)]
					when false
						or_bits[2<<6]
						[ret << Expression.encode_imm(imm, :a32, endianness)]
					when nil
						rets = ret.dup
						or_bits[1<<6]
						ret << @imm.encode(:i8, endianness)
						rets, ret = ret, rets	 or_bits[] modifies ret directly
						or_bits[2<<6]
						ret << @imm.encode(:a32, endianness)
						[ret, rets]
					end
				else
					[ret]
				end
			end
		end
def encode32 ( reg , endianness ) ret = EncodedData . new << ( reg << 3 ) or_bits = lambda { | v | if ret . data [ 0 ] . kind_of? Integer ret . data [ 0 ] |= v else ret . data [ 0 ] = ( ret . data [ 0 ] . unpack ( 'C' ) . first | v ) . chr end } if not self . b and not self . i or_bits [ 5 ] [ ret << @imm . encode ( :a32 , endianness ) ] elsif not self . b and self . s != 1 raise EncodeError , "Invalid ModRM #{self}" if @i . val == 4 or_bits [ 4 ] s = { 8 => 3 , 4 => 2 , 2 => 1 } [ @s ] imm = self . imm || Expression [ 0 ] fu = ( s << 6 ) | ( @i . val << 3 ) | 5 fu = fu . chr if s >= 2 [ ret << fu << imm . encode ( :a32 , endianness ) ] else imm = @imm . reduce if self . imm imm = nil if imm == 0 if not self . i or ( not self . b and self . s == 1 ) b = self . b || self . i or_bits [ b . val ] ret << 0x24 if b . val == 4 else or_bits [ 4 ] i , b = @i , @b b , i = i , b if @s == 1 and ( i . val == 4 or b . val == 5 ) raise EncodeError , "Invalid ModRM #{self}" if i . val == 4 s = { 8 => 3 , 4 => 2 , 2 => 1 , 1 => 0 } [ @s ] fu = ( s << 6 ) | ( i . val << 3 ) | b . val fu = fu . chr if s >= 2 ret << fu end imm ||= 0 if b . val == 5 if imm case Expression . in_range? ( imm , :i8 ) when true or_bits [ 1 << 6 ] [ ret << Expression . encode_imm ( imm , :i8 , endianness ) ] when false or_bits [ 2 << 6 ] [ ret << Expression . encode_imm ( imm , :a32 , endianness ) ] when nil rets = ret . dup or_bits [ 1 << 6 ] ret << @imm . encode ( :i8 , endianness ) rets , ret = ret , rets or_bits [ 2 << 6 ] ret << @imm . encode ( :a32 , endianness ) [ ret , rets ] end else [ ret ] end end end
returns the byte representing the register encoded as modrm
works with Reg/SimdReg
returns the byte representing the register encoded as modrm works with Reg / SimdReg
# 0 => [ [0      ], [1      ], [2      ], [3      ], [:sib      ], [:i32   ], [6      ], [7      ] ], \ # 1 => [ [0, :i8 ], [1, :i8 ], [2, :i8 ], [3, :i8 ], [:sib, :i8 ], [5, :i8 ], [6, :i8 ], [7, :i8 ] ], \ # 2 => [ [0, :i32], [1, :i32], [2, :i32], [3, :i32], [:sib, :i32], [5, :i32], [6, :i32], [7, :i32] ] # # b => 0  1  2  3  4  5+i|i 6  7 # i => 0  1  2  3 nil   5   6  7 # add bits in the first octet of ret.data (1.9 compatibility layer) # rape me # sib with no b # rb1.9 encoding fix # no sib byte (except for [esp]) # sib # rb1.9 encoding fix # or_bits[] modifies ret directly
reg
endianness