Class: Wilson::MachineCodeX86
- Inherits:
-
MachineCode
- Object
- MachineCode
- Wilson::MachineCodeX86
- 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
-
#ah ⇒ Object
registers-general-8bit.
-
#al ⇒ Object
registers-general-8bit.
-
#ax ⇒ Object
registers-general-16bit.
-
#bh ⇒ Object
registers-general-8bit.
-
#bl ⇒ Object
registers-general-8bit.
-
#bp ⇒ Object
registers-general-16bit.
-
#bx ⇒ Object
registers-general-16bit.
-
#ch ⇒ Object
registers-general-8bit.
-
#cl ⇒ Object
registers-general-8bit.
-
#cr0 ⇒ Object
registers-control.
-
#cr2 ⇒ Object
registers-control.
-
#cr3 ⇒ Object
registers-control.
-
#cr4 ⇒ Object
registers-control.
-
#cs ⇒ Object
registers-segment.
-
#cx ⇒ Object
registers-general-16bit.
-
#dh ⇒ Object
registers-general-8bit.
-
#di ⇒ Object
registers-general-16bit.
-
#dl ⇒ Object
registers-general-8bit.
-
#dr0 ⇒ Object
registers-debug.
-
#dr1 ⇒ Object
registers-debug.
-
#dr2 ⇒ Object
registers-debug.
-
#dr3 ⇒ Object
registers-debug.
-
#dr6 ⇒ Object
registers-debug.
-
#dr7 ⇒ Object
registers-debug.
-
#ds ⇒ Object
registers-segment.
-
#dx ⇒ Object
registers-general-16bit.
-
#eax ⇒ Object
registers-general-32bit.
-
#ebp ⇒ Object
registers-general-32bit.
-
#ebx ⇒ Object
registers-general-32bit.
-
#ecx ⇒ Object
registers-general-32bit.
-
#edi ⇒ Object
registers-general-32bit.
-
#edx ⇒ Object
registers-general-32bit.
-
#es ⇒ Object
registers-segment.
-
#esi ⇒ Object
registers-general-32bit.
-
#esp ⇒ Object
registers-general-32bit.
-
#fs ⇒ Object
registers-segment.
-
#gs ⇒ Object
registers-segment.
-
#mm0 ⇒ Object
registers-mmx.
-
#mm1 ⇒ Object
registers-mmx.
-
#mm2 ⇒ Object
registers-mmx.
-
#mm3 ⇒ Object
registers-mmx.
-
#mm4 ⇒ Object
registers-mmx.
-
#mm5 ⇒ Object
registers-mmx.
-
#mm6 ⇒ Object
registers-mmx.
-
#mm7 ⇒ Object
registers-mmx.
-
#si ⇒ Object
registers-general-16bit.
-
#sp ⇒ Object
registers-general-16bit.
-
#ss ⇒ Object
registers-segment.
-
#st0 ⇒ Object
registers-fpu.
-
#st1 ⇒ Object
registers-fpu.
-
#st2 ⇒ Object
registers-fpu.
-
#st3 ⇒ Object
registers-fpu.
-
#st4 ⇒ Object
registers-fpu.
-
#st5 ⇒ Object
registers-fpu.
-
#st6 ⇒ Object
registers-fpu.
-
#st7 ⇒ Object
registers-fpu.
-
#tr3 ⇒ Object
registers-test.
-
#tr4 ⇒ Object
registers-test.
-
#tr5 ⇒ Object
registers-test.
-
#tr6 ⇒ Object
registers-test.
-
#tr7 ⇒ Object
registers-test.
Attributes inherited from MachineCode
#bits, #cachedInstructions, #instructions, #procedure, #processors, #stream
Instance Method Summary collapse
- #arg(n) ⇒ Object
- #defaultBits ⇒ Object
- #defaultProcessors ⇒ Object
- #from_ruby(reg) ⇒ Object
- #platform ⇒ Object
- #setup16BitRegisters ⇒ Object
- #setup32BitRegisters ⇒ Object
- #setup8BitRegisters ⇒ Object
- #setupControlRegisters ⇒ Object
- #setupDebugRegisters ⇒ Object
- #setupFPURegisters ⇒ Object
- #setupMachine ⇒ Object
- #setupMMXRegisters ⇒ Object
- #setupSegmentRegisters ⇒ Object
- #setupTestRegisters ⇒ Object
- #to_ruby(reg) ⇒ Object
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
Instance Method Details
#arg(n) ⇒ Object
782 783 784 |
# File 'lib/wilson.rb', line 782 def arg n ebp + (n+3) * 4 end |
#defaultBits ⇒ Object
699 700 701 |
# File 'lib/wilson.rb', line 699 def defaultBits 32 end |
#defaultProcessors ⇒ Object
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 |
#platform ⇒ Object
686 687 688 |
# File 'lib/wilson.rb', line 686 def platform 'i386' end |
#setup16BitRegisters ⇒ Object
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 |
#setup32BitRegisters ⇒ Object
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 |
#setup8BitRegisters ⇒ Object
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 |
#setupControlRegisters ⇒ Object
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 |
#setupDebugRegisters ⇒ Object
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 |
#setupFPURegisters ⇒ Object
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 |
#setupMachine ⇒ Object
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 |
#setupMMXRegisters ⇒ Object
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 |
#setupSegmentRegisters ⇒ Object
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 |
#setupTestRegisters ⇒ Object
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 |