89 lines
1.7 KiB
Ruby
89 lines
1.7 KiB
Ruby
|
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
|