require 'intel/operand' module Intel ## # Address is a memory address in one of the following example forms: # # eax, ebx + ecx, eax + 5, 23545, edx + eax + 2312 class Address < Operand attr_accessor :id, :index attr_reader :offset attr_writer :isAssemblerOffset # FIX def initialize isAssemblerOffset = nil, bits = nil, id = nil super(nil,bits) self.isAssemblerOffset = isAssemblerOffset self.id = id self.index = self.offset = nil end def bits super || self.machine.bits end def offset= obj if obj.is_a?(Register) then @offset = 0 self.index = obj else @offset = obj end end def + o # TODO: this seems totally and completely wrong if o.is_a?(Register) then self.index = o else self.offset = o end self end def address? true end def offset? @isAssemblerOffset.nil? ? id.nil? : @isAssemblerOffset end def push_mod_rm_on spareRegister, stream if id.nil? then stream << (0b00000101 + (spareRegister.id << 3)) return stream.push_D(offset) end modrm = case offset when 0 then 0b00000000 when 1..255 then 0b01000000 else 0b10000000 end if index.nil? then modrm += (spareRegister.id << 3) else stream << (0b00000100 + (spareRegister.id << 3)) modrm += (index.id << 3) end stream << modrm + id return self if offset == 0 return stream.push_B(offset) if offset < 256 stream.push_D offset end def m self end end end