class MachineCodeX86

MachineCodeX86 is a concrete implementation of a machine to create X86 assembly code on.

You can use this class in two ways:

a) you can instantiate an instance and use its register variables

to build up machine code in the @stream variable and then use
those bytes in any way that you see fit, or

b) you can make a subclass of this class much like you do with

ExternalInterface and put methods on the class that will
compile in to assembler code that can be called from Smalltalk
code

Using MachineCodeX86 for scripting

This is the long hand way of writing assembly code, since you always include a receiver with every command.

asm = Assembler.MachineCodeX86.new

Once you have an assembler, you can access the registers and send commands to them, eg:

asm.eax.mov 1

As you send the commands, the @stream will build up containing the X86 assembler bytes you can use. You can use memory addresses in your assembler code with the m method, eg:

asm.eax.m.mov 1

Once you are finished, you simply send:

asm.stream

This will return you the stream of bytes.

Labels & Jumps

You can do labels and jump to them using two different label commands. The first is label, which places a label jump point immediately on call, eg:

label = asm.label
label.jmp

The other is a future label that can be placed at some future point in the program and jumped too

label = asm.future_label
asm.eax.xor asm.eax
label.jmp
asm.eax.inc
label.plant

You plant the future label where you want it to actually be and past references to it will be updated. Future labels will always use a dword jmp so that there's space to fill in the command if the jmp ends up being far.

Attributes

ah[RW]

registers-general-8bit

al[RW]

registers-general-8bit

ax[RW]

registers-general-16bit

bh[RW]

registers-general-8bit

bl[RW]

registers-general-8bit

bp[RW]

registers-general-16bit

bx[RW]

registers-general-16bit

ch[RW]

registers-general-8bit

cl[RW]

registers-general-8bit

cr0[RW]

registers-control

cr2[RW]

registers-control

cr3[RW]

registers-control

cr4[RW]

registers-control

cs[RW]

registers-segment

cx[RW]

registers-general-16bit

dh[RW]

registers-general-8bit

di[RW]

registers-general-16bit

dl[RW]

registers-general-8bit

dr0[RW]

registers-debug

dr1[RW]

registers-debug

dr2[RW]

registers-debug

dr3[RW]

registers-debug

dr6[RW]

registers-debug

dr7[RW]

registers-debug

ds[RW]

registers-segment

dx[RW]

registers-general-16bit

eax[RW]

registers-general-32bit

ebp[RW]

registers-general-32bit

ebx[RW]

registers-general-32bit

ecx[RW]

registers-general-32bit

edi[RW]

registers-general-32bit

edx[RW]

registers-general-32bit

es[RW]

registers-segment

esi[RW]

registers-general-32bit

esp[RW]

registers-general-32bit

fs[RW]

registers-segment

gs[RW]

registers-segment

mm0[RW]

registers-mmx

mm1[RW]

registers-mmx

mm2[RW]

registers-mmx

mm3[RW]

registers-mmx

mm4[RW]

registers-mmx

mm5[RW]

registers-mmx

mm6[RW]

registers-mmx

mm7[RW]

registers-mmx

si[RW]

registers-general-16bit

sp[RW]

registers-general-16bit

ss[RW]

registers-segment

st0[RW]

registers-fpu

st1[RW]

registers-fpu

st2[RW]

registers-fpu

st3[RW]

registers-fpu

st4[RW]

registers-fpu

st5[RW]

registers-fpu

st6[RW]

registers-fpu

st7[RW]

registers-fpu

tr3[RW]

registers-test

tr4[RW]

registers-test

tr5[RW]

registers-test

tr6[RW]

registers-test

tr7[RW]

registers-test

Public Instance Methods

arg(n) click to toggle source
# File lib/wilson.rb, line 781
def arg n
  ebp + (n+3) * 4
end
defaultBits() click to toggle source
# File lib/wilson.rb, line 698
def defaultBits
  32
end
defaultProcessors() click to toggle source
# File lib/wilson.rb, line 711
def defaultProcessors
  %w(8086 186 286 386 486 PENT P6 CYRIX FPU MMX PRIV UNDOC)
end
from_ruby(reg) click to toggle source
# File lib/wilson.rb, line 790
def from_ruby reg
  reg.shr 1
end
platform() click to toggle source
# File lib/wilson.rb, line 685
def platform
  'i386'
end
setup16BitRegisters() click to toggle source
# File lib/wilson.rb, line 740
def setup16BitRegisters
  self.ax = Register.on_id_bits self, 0, 16
  self.cx = Register.on_id_bits self, 1, 16
  self.dx = Register.on_id_bits self, 2, 16
  self.bx = Register.on_id_bits self, 3, 16
  self.sp = Register.on_id_bits self, 4, 16
  self.bp = Register.on_id_bits self, 5, 16
  self.si = Register.on_id_bits self, 6, 16
  self.di = Register.on_id_bits self, 7, 16
end
setup32BitRegisters() click to toggle source
# File lib/wilson.rb, line 770
def setup32BitRegisters
  self.eax = Register.on_id_bits self, 0, 32
  self.ecx = Register.on_id_bits self, 1, 32
  self.edx = Register.on_id_bits self, 2, 32
  self.ebx = Register.on_id_bits self, 3, 32
  self.esp = Register.on_id_bits self, 4, 32
  self.ebp = Register.on_id_bits self, 5, 32
  self.esi = Register.on_id_bits self, 6, 32
  self.edi = Register.on_id_bits self, 7, 32
end
setup8BitRegisters() click to toggle source
# File lib/wilson.rb, line 729
def setup8BitRegisters
  self.al = Register.on_id_bits self, 0, 8
  self.cl = Register.on_id_bits self, 1, 8
  self.dl = Register.on_id_bits self, 2, 8
  self.bl = Register.on_id_bits self, 3, 8
  self.ah = Register.on_id_bits self, 4, 8
  self.ch = Register.on_id_bits self, 5, 8
  self.dh = Register.on_id_bits self, 6, 8
  self.bh = Register.on_id_bits self, 7, 8
end
setupControlRegisters() click to toggle source
# File lib/wilson.rb, line 678
def setupControlRegisters
  self.cr0 = ControlRegister.on_id self, 0
  self.cr2 = ControlRegister.on_id self, 2
  self.cr3 = ControlRegister.on_id self, 3
  self.cr4 = ControlRegister.on_id self, 4
end
setupDebugRegisters() click to toggle source
# File lib/wilson.rb, line 689
def setupDebugRegisters
  self.dr0 = DebugRegister.on_id self, 0
  self.dr1 = DebugRegister.on_id self, 1
  self.dr2 = DebugRegister.on_id self, 2
  self.dr3 = DebugRegister.on_id self, 3
  self.dr6 = DebugRegister.on_id self, 6
  self.dr7 = DebugRegister.on_id self, 7
end
setupFPURegisters() click to toggle source
# File lib/wilson.rb, line 667
def setupFPURegisters
  self.st0 = FPURegister.on_id self, 0
  self.st1 = FPURegister.on_id self, 1
  self.st2 = FPURegister.on_id self, 2
  self.st3 = FPURegister.on_id self, 3
  self.st4 = FPURegister.on_id self, 4
  self.st5 = FPURegister.on_id self, 5
  self.st6 = FPURegister.on_id self, 6
  self.st7 = FPURegister.on_id self, 7
end
setupMMXRegisters() click to toggle source
# File lib/wilson.rb, line 751
def setupMMXRegisters
  self.mm0 = MMXRegister.on_id self, 0
  self.mm1 = MMXRegister.on_id self, 1
  self.mm2 = MMXRegister.on_id self, 2
  self.mm3 = MMXRegister.on_id self, 3
  self.mm4 = MMXRegister.on_id self, 4
  self.mm5 = MMXRegister.on_id self, 5
  self.mm6 = MMXRegister.on_id self, 6
  self.mm7 = MMXRegister.on_id self, 7
end
setupMachine() click to toggle source
# File lib/wilson.rb, line 715
def setupMachine
  self.instructions = Assembler.commands

  self.setup8BitRegisters
  self.setup16BitRegisters
  self.setup32BitRegisters
  self.setupSegmentRegisters
  self.setupControlRegisters
  self.setupTestRegisters
  self.setupDebugRegisters
  self.setupFPURegisters
  self.setupMMXRegisters
end
setupSegmentRegisters() click to toggle source
# File lib/wilson.rb, line 702
def setupSegmentRegisters
  self.es = SegmentRegister.on_id self, 0
  self.cs = SegmentRegister.on_id self, 1
  self.ss = SegmentRegister.on_id self, 2
  self.ds = SegmentRegister.on_id self, 3
  self.fs = SegmentRegister.on_id self, 4
  self.gs = SegmentRegister.on_id self, 5
end
setupTestRegisters() click to toggle source
# File lib/wilson.rb, line 762
def setupTestRegisters
  self.tr3 = TestRegister.on_id self, 3
  self.tr4 = TestRegister.on_id self, 4
  self.tr5 = TestRegister.on_id self, 5
  self.tr6 = TestRegister.on_id self, 6
  self.tr7 = TestRegister.on_id self, 7
end
to_ruby(reg) click to toggle source
# File lib/wilson.rb, line 785
def to_ruby reg
  reg.shl 1
  reg.inc
end