Class: Wilson::MachineCodeX86

Inherits:
MachineCode show all
Defined in:
lib/wilson.rb

Overview

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.

Instance Attribute Summary collapse

Attributes inherited from MachineCode

#bits, #cachedInstructions, #instructions, #procedure, #processors, #stream

Instance Method Summary collapse

Methods inherited from MachineCode

#assemble, #future_label, #initialize, #inspect, #instructionFromMessage, #label, #method_missing, #supportsProcessor

Constructor Details

This class inherits a constructor from Wilson::MachineCode

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Wilson::MachineCode

Instance Attribute Details

#ahObject

registers-general-8bit



657
658
659
# File 'lib/wilson.rb', line 657

def ah
  @ah
end

#alObject

registers-general-8bit



657
658
659
# File 'lib/wilson.rb', line 657

def al
  @al
end

#axObject

registers-general-16bit



660
661
662
# File 'lib/wilson.rb', line 660

def ax
  @ax
end

#bhObject

registers-general-8bit



657
658
659
# File 'lib/wilson.rb', line 657

def bh
  @bh
end

#blObject

registers-general-8bit



657
658
659
# File 'lib/wilson.rb', line 657

def bl
  @bl
end

#bpObject

registers-general-16bit



660
661
662
# File 'lib/wilson.rb', line 660

def bp
  @bp
end

#bxObject

registers-general-16bit



660
661
662
# File 'lib/wilson.rb', line 660

def bx
  @bx
end

#chObject

registers-general-8bit



657
658
659
# File 'lib/wilson.rb', line 657

def ch
  @ch
end

#clObject

registers-general-8bit



657
658
659
# File 'lib/wilson.rb', line 657

def cl
  @cl
end

#cr0Object

registers-control



663
664
665
# File 'lib/wilson.rb', line 663

def cr0
  @cr0
end

#cr2Object

registers-control



663
664
665
# File 'lib/wilson.rb', line 663

def cr2
  @cr2
end

#cr3Object

registers-control



663
664
665
# File 'lib/wilson.rb', line 663

def cr3
  @cr3
end

#cr4Object

registers-control



663
664
665
# File 'lib/wilson.rb', line 663

def cr4
  @cr4
end

#csObject

registers-segment



651
652
653
# File 'lib/wilson.rb', line 651

def cs
  @cs
end

#cxObject

registers-general-16bit



660
661
662
# File 'lib/wilson.rb', line 660

def cx
  @cx
end

#dhObject

registers-general-8bit



657
658
659
# File 'lib/wilson.rb', line 657

def dh
  @dh
end

#diObject

registers-general-16bit



660
661
662
# File 'lib/wilson.rb', line 660

def di
  @di
end

#dlObject

registers-general-8bit



657
658
659
# File 'lib/wilson.rb', line 657

def dl
  @dl
end

#dr0Object

registers-debug



648
649
650
# File 'lib/wilson.rb', line 648

def dr0
  @dr0
end

#dr1Object

registers-debug



648
649
650
# File 'lib/wilson.rb', line 648

def dr1
  @dr1
end

#dr2Object

registers-debug



648
649
650
# File 'lib/wilson.rb', line 648

def dr2
  @dr2
end

#dr3Object

registers-debug



648
649
650
# File 'lib/wilson.rb', line 648

def dr3
  @dr3
end

#dr6Object

registers-debug



648
649
650
# File 'lib/wilson.rb', line 648

def dr6
  @dr6
end

#dr7Object

registers-debug



648
649
650
# File 'lib/wilson.rb', line 648

def dr7
  @dr7
end

#dsObject

registers-segment



651
652
653
# File 'lib/wilson.rb', line 651

def ds
  @ds
end

#dxObject

registers-general-16bit



660
661
662
# File 'lib/wilson.rb', line 660

def dx
  @dx
end

#eaxObject

registers-general-32bit



642
643
644
# File 'lib/wilson.rb', line 642

def eax
  @eax
end

#ebpObject

registers-general-32bit



642
643
644
# File 'lib/wilson.rb', line 642

def ebp
  @ebp
end

#ebxObject

registers-general-32bit



642
643
644
# File 'lib/wilson.rb', line 642

def ebx
  @ebx
end

#ecxObject

registers-general-32bit



642
643
644
# File 'lib/wilson.rb', line 642

def ecx
  @ecx
end

#ediObject

registers-general-32bit



642
643
644
# File 'lib/wilson.rb', line 642

def edi
  @edi
end

#edxObject

registers-general-32bit



642
643
644
# File 'lib/wilson.rb', line 642

def edx
  @edx
end

#esObject

registers-segment



651
652
653
# File 'lib/wilson.rb', line 651

def es
  @es
end

#esiObject

registers-general-32bit



642
643
644
# File 'lib/wilson.rb', line 642

def esi
  @esi
end

#espObject

registers-general-32bit



642
643
644
# File 'lib/wilson.rb', line 642

def esp
  @esp
end

#fsObject

registers-segment



651
652
653
# File 'lib/wilson.rb', line 651

def fs
  @fs
end

#gsObject

registers-segment



651
652
653
# File 'lib/wilson.rb', line 651

def gs
  @gs
end

#mm0Object

registers-mmx



666
667
668
# File 'lib/wilson.rb', line 666

def mm0
  @mm0
end

#mm1Object

registers-mmx



666
667
668
# File 'lib/wilson.rb', line 666

def mm1
  @mm1
end

#mm2Object

registers-mmx



666
667
668
# File 'lib/wilson.rb', line 666

def mm2
  @mm2
end

#mm3Object

registers-mmx



666
667
668
# File 'lib/wilson.rb', line 666

def mm3
  @mm3
end

#mm4Object

registers-mmx



666
667
668
# File 'lib/wilson.rb', line 666

def mm4
  @mm4
end

#mm5Object

registers-mmx



666
667
668
# File 'lib/wilson.rb', line 666

def mm5
  @mm5
end

#mm6Object

registers-mmx



666
667
668
# File 'lib/wilson.rb', line 666

def mm6
  @mm6
end

#mm7Object

registers-mmx



666
667
668
# File 'lib/wilson.rb', line 666

def mm7
  @mm7
end

#siObject

registers-general-16bit



660
661
662
# File 'lib/wilson.rb', line 660

def si
  @si
end

#spObject

registers-general-16bit



660
661
662
# File 'lib/wilson.rb', line 660

def sp
  @sp
end

#ssObject

registers-segment



651
652
653
# File 'lib/wilson.rb', line 651

def ss
  @ss
end

#st0Object

registers-fpu



645
646
647
# File 'lib/wilson.rb', line 645

def st0
  @st0
end

#st1Object

registers-fpu



645
646
647
# File 'lib/wilson.rb', line 645

def st1
  @st1
end

#st2Object

registers-fpu



645
646
647
# File 'lib/wilson.rb', line 645

def st2
  @st2
end

#st3Object

registers-fpu



645
646
647
# File 'lib/wilson.rb', line 645

def st3
  @st3
end

#st4Object

registers-fpu



645
646
647
# File 'lib/wilson.rb', line 645

def st4
  @st4
end

#st5Object

registers-fpu



645
646
647
# File 'lib/wilson.rb', line 645

def st5
  @st5
end

#st6Object

registers-fpu



645
646
647
# File 'lib/wilson.rb', line 645

def st6
  @st6
end

#st7Object

registers-fpu



645
646
647
# File 'lib/wilson.rb', line 645

def st7
  @st7
end

#tr3Object

registers-test



654
655
656
# File 'lib/wilson.rb', line 654

def tr3
  @tr3
end

#tr4Object

registers-test



654
655
656
# File 'lib/wilson.rb', line 654

def tr4
  @tr4
end

#tr5Object

registers-test



654
655
656
# File 'lib/wilson.rb', line 654

def tr5
  @tr5
end

#tr6Object

registers-test



654
655
656
# File 'lib/wilson.rb', line 654

def tr6
  @tr6
end

#tr7Object

registers-test



654
655
656
# File 'lib/wilson.rb', line 654

def tr7
  @tr7
end

Instance Method Details

#arg(n) ⇒ Object



782
783
784
# File 'lib/wilson.rb', line 782

def arg n
  ebp + (n+3) * 4
end

#defaultBitsObject



699
700
701
# File 'lib/wilson.rb', line 699

def defaultBits
  32
end

#defaultProcessorsObject



712
713
714
# File 'lib/wilson.rb', line 712

def defaultProcessors
  %w(8086 186 286 386 486 PENT P6 CYRIX FPU MMX PRIV UNDOC)
end

#from_ruby(reg) ⇒ Object



791
792
793
# File 'lib/wilson.rb', line 791

def from_ruby reg
  reg.shr 1
end

#platformObject



686
687
688
# File 'lib/wilson.rb', line 686

def platform
  'i386'
end

#setup16BitRegistersObject



741
742
743
744
745
746
747
748
749
750
# File 'lib/wilson.rb', line 741

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

#setup32BitRegistersObject



771
772
773
774
775
776
777
778
779
780
# File 'lib/wilson.rb', line 771

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

#setup8BitRegistersObject



730
731
732
733
734
735
736
737
738
739
# File 'lib/wilson.rb', line 730

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

#setupControlRegistersObject



679
680
681
682
683
684
# File 'lib/wilson.rb', line 679

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

#setupDebugRegistersObject



690
691
692
693
694
695
696
697
# File 'lib/wilson.rb', line 690

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

#setupFPURegistersObject



668
669
670
671
672
673
674
675
676
677
# File 'lib/wilson.rb', line 668

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

#setupMachineObject



716
717
718
719
720
721
722
723
724
725
726
727
728
# File 'lib/wilson.rb', line 716

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

#setupMMXRegistersObject



752
753
754
755
756
757
758
759
760
761
# File 'lib/wilson.rb', line 752

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

#setupSegmentRegistersObject



703
704
705
706
707
708
709
710
# File 'lib/wilson.rb', line 703

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

#setupTestRegistersObject



763
764
765
766
767
768
769
# File 'lib/wilson.rb', line 763

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) ⇒ Object



786
787
788
789
# File 'lib/wilson.rb', line 786

def to_ruby reg
  reg.shl 1
  reg.inc
end