CSES - Datatähti 2018 alku - Results
Submission details
Task:Fraktaali
Sender:ollpu
Submission time:2018-09-26 20:39:27 +0300
Language:Ruby
Status:READY
Result:100
Feedback
groupverdictscore
#1ACCEPTED10
#2ACCEPTED10
#3ACCEPTED10
#4ACCEPTED10
#5ACCEPTED10
#6ACCEPTED10
#7ACCEPTED10
#8ACCEPTED10
#9ACCEPTED10
#10ACCEPTED10
Test results
testverdicttimegroup
#1ACCEPTED0.11 s1details
#2ACCEPTED0.12 s2details
#3ACCEPTED0.12 s3details
#4ACCEPTED0.11 s4details
#5ACCEPTED0.12 s5details
#6ACCEPTED0.12 s6details
#7ACCEPTED0.11 s7details
#8ACCEPTED0.11 s8details
#9ACCEPTED0.11 s9details
#10ACCEPTED0.12 s10details

Code

def main
n = gets.to_i-1
bs = (1<<2*n) + (1<<n)
mem = Fiddle.malloc bs
asm do
rbp.mov mem
rcx.xor rcx
rdi.xor rdi
l1 = label
rsi.xor rsi
l2 = label
rax.mov rdi
rax.and rsi
rax.popcnt rax
al.test 1
jz even = flabel
eax.mov ".".ord
jmp over = flabel
even.plant
eax.mov "#".ord
over.plant
mov rbp+rcx, al
rcx.inc
rsi.inc
rdx.mov 1<<n
rsi.cmp rdx
jl l2
eax.mov "\n".ord
mov rbp+rcx, al
rcx.inc
rdi.inc
rdx.mov 1<<n
rdi.cmp rdx
jl l1
rax.mov 1
rdi.mov 1
rsi.mov mem
rdx.mov rcx
syscall
end
end
##
# Wilson is a pure ruby x86 assembler. No, really. Worst Idea Evar.
# Source: https://github.com/seattlerb/wilson/
# Modded by ollpu to run in modern Ruby (Linux x86_64)
##
#
# Why "wilson"? I wanted to name it "metal", but there is an existing
# project with that name... So I'm naming it after Wilson Bilkovich, who
# is about as metal as you can get (and it is easier to spell than
# "bilkovich", even tho that sounds more metal).
#
# Wilson is a port (and extension) of the smalltalk x86 assembler by
# Michael Lucas-Smith. I came across it when he presented it at
# Smalltalk SuperPowers at OOPSLA 2008.
require 'fiddle'
require 'fiddle/import'
module LibC
extend Fiddle::Importer
dlload "libc.so.6"
extern "void* mmap(void*, size_t, int, int, int, ptrdiff_t)"
extern "void* memcpy(void*, const void*, size_t)"
def self.mmap_rwx length
LibC.mmap(0, length, 0x7, 0x22, -1, 0)
end
end
class Object
def subclass_responsibility; raise "subclass responsibility" end
def no!; false end
alias :address? :no!
alias :future_label? :no!
alias :immediate? :no!
alias :immediate_value? :no!
alias :label? :no!
alias :offset? :no!
alias :operand? :no!
alias :register? :no!
alias :special_register? :no!
end
module Wilson
VERSION = '1.1.2'
##
# Assembler parses the NASM documentation and creates Command
# objects for it
class Assembler
attr_accessor :commands
attr_accessor :commands_by_mnemonic
def self.nasm_fixes
# TODO: extend parser to split /[,:]/ and remove some of these
'
CALL imm,imm16 ; o16 9A iw iw [8086]
CALL imm,imm32 ; o32 9A id iw [386]
CALLFAR mem16 ; o16 FF /3 [8086]
CALLFAR mem32 ; o32 FF /3 [386]
Jcc imm16 ; 0F 80+cc rw/rd [386]
Jcc imm32 ; 0F 80+cc rw/rd [386]
JMP imm,imm16 ; o16 EA iw iw [8086]
JMP imm,imm32 ; o32 EA id iw [386]
JMP imm16 ; E9 rw/rd [8086]
JMP imm32 ; E9 rw/rd [8086]
JMP imm8 ; EB rb [8086]
JMPFAR mem16 ; o16 FF /5 [8086]
JMPFAR mem32 ; o32 FF /5 [386]
FADDTO fpureg ; DC C0+r [8086,FPU]
FDIVTO fpureg ; DC F8+r [8086,FPU]
FDIVRTO fpureg ; DC F0+r [8086,FPU]
FMULTO fpureg ; DC C8+r [8086,FPU]
FSUBTO fpureg ; DC E8+r [8086,FPU]
FSUBRTO fpureg ; DC E0+r [8086,FPU]
CMP r/m16,imm8 ; o16 83 /7 ib [8086]
CMP r/m32,imm8 ; o32 83 /7 ib [386]
SAR r/m16,1 ; o16 D1 /7 [8086]
SAR r/m32,1 ; o32 D1 /7 [386]
MOV reg64,imm64 ; o32 B8+r id [x64]
SYSCALL ; 0F 05 [x64]
POPCNT reg16,r/m16 ; f3 o16 0f b8 /r [NEHALEM]
POPCNT reg32,r/m32 ; f3 o32 0f b8 /r [NEHALEM]
'
end
def self.nasm
File.read(__FILE__).split(/__END__/).last
end
@@default = nil
def self.default
@@default ||= self.new.parse
end
def self.default= o
@@default = o
end
def self.commands
self.default.commands
end
def self.commands_by_mnemonic
self.default.commands_by_mnemonic
end
def self.parse
self.default
end
def initialize
self.commands = []
self.commands_by_mnemonic = {}
end
def expand_parameters command
command.parameters.each_with_index do |parameter, index|
if String === parameter && parameter =~ /^r\/m(\d+)/ then
bits = $1.to_i
newCommand = command.dup
commands << newCommand
case bits
when 8, 16, 32 then
command.parameters[index] = MemoryRegister.new bits
newCommand.parameters[index] = Address.new false, bits
when 64 then
command.parameters[index] = MMXRegister.new bits
newCommand.parameters[index] = Address.new false, bits
end
end
end
end
def add_conditional_commands prototype
prototype.opcode = prototype.opcode[0..-3]
self.conditionals.each do |conditional, value|
command = prototype.dup
command.opcode += conditional
command.opcodes.each_with_index do |op, index|
command.opcodes[index] = ($1.hex+value).to_s(16) if op =~ /(.*)\+cc$/
end
self.add_command command
end
end
def process_line line # TODO: remove
return if line.empty?
return unless line =~ /^[A-Z].+;.*\[/
self.parse_command line
end
def add_command command
return self.add_conditional_commands(command) if command.opcode =~ /cc$/i
self.commands << command
self.expand_parameters command
end
def conditionals
@conditionals ||= {
'O' => 0, 'NO' => 1, 'B' => 2, 'C' => 2, 'NAE' => 2,
'AE' => 3, 'NB' => 3, 'NC' => 3, 'E' => 4, 'Z' => 4,
'NE' => 5, 'NZ' => 5, 'BE' => 6, 'NA' => 6, 'A' => 7,
'NBE' => 7, 'S' => 8, 'NS' => 9, 'P' => 10, 'PE' => 10,
'NP' => 11, 'PO' => 11, 'L' => 12, 'NGE' => 12, 'GE' => 13,
'NL' => 13, 'LE' => 14, 'NG' => 14, 'G' => 15, 'NLE' => 15,
}
end
def parse_command line
if line =~ /^(\w+)\s+([^;]*)\s*;\s*([^\[]+)\s+/ then
name, params, ops = $1, $2, $3
command = Command.new
command.opcode = name
command.opcodes = ops.split
command.initialize_parameters params.strip
self.add_command command
else
raise "unparsed: #{line}"
end
end
def parse
(self.class.nasm + self.class.nasm_fixes).each_line do |line|
self.process_line line.strip
end
self.commands.each do |cmd|
self.commands_by_mnemonic[cmd.opcode] ||= []
self.commands_by_mnemonic[cmd.opcode] << cmd
end
self
end
end
##
# Command is a potential command you can call. It has an
# opcode (eg: MOV) and the memory format that it outputs as
# (opcodes) as well as the kinds of parameters it takes and the
# processor types that support the command.
class Command
attr_accessor :opcode, :parameters, :opcodes
def dup
x = super
x.parameters = x.parameters.dup
x.opcodes = x.opcodes.dup
x
end
# TODO: learn this better, and figure out why not polymorphic ==
def parameter_matches a, b
return false if String === b
if a.register? && b.register? then
return (a.bits == b.bits || [a.bits, b.bits] == [64, 32] ) && (b.id.nil? || a.id == b.id)
end
if a.address? && b.address? then
return ! b.offset? || a.offset?
end
if a.special_register? && b.special_register? then
return a.class == b.class && (b.id.nil? || a.id == b.id)
end
return false unless b.immediate?
if a.immediate_value? then
return (b.value && b.value == a) || b.bits.nil? || a < (2 ** b.bits)
end
if a.label? then
return a.future_label? ? b.bits == a.machine.bits :
a.bits <= (b.bits || a.machine.bits)
end
false
end
def instruction_applies? instruction
return false if instruction.opcode != self.opcode
return false if instruction.parameters.size != self.parameters.size
instruction.parameters.zip(self.parameters).all? { |a, b|
self.parameter_matches a, b
}
end
def to_parameter parameter
case parameter
when 'r/m8' then return parameter # "Expanded by the parser"
when 'r/m16' then return parameter # "Expanded by the parser"
when 'r/m32' then return parameter # "Expanded by the parser"
when 'r/m64' then return parameter # "Expanded by the parser"
when 'TO fpureg' then return parameter # "Fixed in nasm_fixes"
when 'SHORT imm' then return parameter # "Fixed in nasm_fixes"
when 'FAR mem' then return parameter # "Fixed in nasm_fixes"
when 'FAR mem16' then return parameter # "Fixed in nasm_fixes"
when 'FAR mem32' then return parameter # "Fixed in nasm_fixes"
when 'NEAR imm' then return parameter # "Fixed in nasm_fixes"
when 'imm:imm16' then return parameter # "Fixed in nasm_fixes"
when 'imm:imm32' then return parameter # "Fixed in nasm_fixes"
when '1' then return Immediate.new(1)
when 'AL' then return Register.on_id_bits(nil, 0, 8)
when 'AX' then return Register.on_id_bits(nil, 0, 16)
when 'EAX' then return Register.on_id_bits(nil, 0, 32)
when 'CL' then return Register.on_id_bits(nil, 1, 8)
when 'CX' then return Register.on_id_bits(nil, 1, 16)
when 'ECX' then return Register.on_id_bits(nil, 1, 32)
when 'DL' then return Register.on_id_bits(nil, 2, 8)
when 'DX' then return Register.on_id_bits(nil, 2, 16)
when 'EDX' then return Register.on_id_bits(nil, 2, 32)
when 'BL' then return Register.on_id_bits(nil, 3, 8)
when 'BX' then return Register.on_id_bits(nil, 3, 16)
when 'EBX' then return Register.on_id_bits(nil, 3, 32)
when 'ES' then return SegmentRegister.on_id(nil, 0)
when 'CS' then return SegmentRegister.on_id(nil, 1)
when 'SS' then return SegmentRegister.on_id(nil, 2)
when 'DS' then return SegmentRegister.on_id(nil, 3)
when 'FS' then return SegmentRegister.on_id(nil, 4)
when 'GS' then return SegmentRegister.on_id(nil, 5)
when 'imm' then return Immediate.new
when 'imm8' then return Immediate.new(8)
when 'imm16' then return Immediate.new(16)
when 'imm32' then return Immediate.new(32)
when 'imm64' then return Immediate.new(64)
when 'segreg' then return SegmentRegister.new
when 'reg' then return Register.new
when 'reg8' then return Register.new(8)
when 'reg16' then return Register.new(16)
when 'reg32' then return Register.new(32)
when 'reg64' then return Register.new(64)
when 'mem' then return Address.new(false, 4)
when 'mem8' then return Address.new(false, 8)
when 'mem16' then return Address.new(false, 16)
when 'mem32' then return Address.new(false, 32)
when 'mem64' then return Address.new(false, 64)
when 'mem80' then return Address.new(false, 80)
when 'memoffs8' then return Address.new(true, 8)
when 'memoffs16' then return Address.new(true, 16)
when 'memoffs32' then return Address.new(true, 32)
when 'fpureg' then return FPURegister.new
when /ST(.*)/ then return FPURegister.new($1.to_i)
when 'mmxreg' then return MMXRegister.new
when /MM(.*)/ then return MMXRegister.new($1.to_i)
when 'CR0/2/3/4' then return ControlRegister.new
when 'DR0/1/2/3/6/7' then return DebugRegister.new
when 'TR3/4/5/6/7' then return TestRegister.new
else
warn "unknown parameter: #{parameter.inspect}"
return parameter
end
end
def initialize_parameters params
self.parameters = params.split(/,/).map { |s| self.to_parameter s }
end
def assemble instruction
stream = []
opcodes.each_with_index do |each, index|
self.execute_instruction_position_on(each, instruction,
(index + 1) / opcodes.size, stream)
end
stream
end
def execute_instruction_position_on(byte, instruction, position, stream)
case byte
when 'a16', 'a32' then
raise "not done yet"
when 'o16' then
return self.align16_on(instruction, stream)
when 'o32' then
return self.align32_on(instruction, stream)
when 'ib' then
return stream.push_B(instruction.theImmediate)
when 'iw' then
return stream.push_W(instruction.theSecondImmediate) if position == 1
return stream.push_W(instruction.theImmediate)
when 'id' then
if instruction.x64_mode
return stream.push_Q(instruction.theSecondImmediate) if position == 1
return stream.push_Q(instruction.theImmediate)
else
return stream.push_D(instruction.theSecondImmediate) if position == 1
return stream.push_D(instruction.theImmediate)
end
when 'rb' then
return self.relative_b_on(instruction, stream)
when 'rw' then
return self.relative_w_on(instruction, stream)
when 'rw/rd' then
return self.relative_w_on(instruction, stream) if
instruction.machine.bits == 16
return self.relative_d_on(instruction, stream)
when 'rd' then
return self.relative_d_on(instruction, stream)
when 'ow' then
raise byte
# [^stream push_W: instruction theAddress offset].
when 'od' then
raise byte
# [^stream push_D: instruction theAddress offset].
when 'ow/od' then
if instruction.machine.bits == 16 then
stream.push_W instruction.theAddress.offset
end
return stream.push_D(instruction.theAddress.offset)
when /^\/(.*)/ then
return self.modrm_instruction_on($1, instruction, stream)
end
number = byte.hex
number += instruction.parameters[parameters.first.id ? 1 : 0].id if
byte =~ /r$/
stream << number
end
##
# If we get here, there will be at least two parameters to combine
# a memory address with a register or a register with a register"
def modrm_r_on instruction, stream
address, register = instruction.first, instruction.second
swap = false # TODO: this can be 1 call at the bottom
if instruction.first.register? && instruction.second.register? then
if parameters.first.memory_register? then
return instruction.first.push_mod_rm_on(instruction.second, stream)
else
return instruction.second.push_mod_rm_on(instruction.first, stream)
end
end
if instruction.first.special_register? then
return instruction.second.push_mod_rm_on(instruction.first, stream)
end
if instruction.second.special_register? then
return instruction.first.push_mod_rm_on(instruction.second, stream)
end
address, register = if instruction.first.register? && instruction.second.respond_to?(:push_mod_rm_on) then
[instruction.second, instruction.first]
else
[instruction.first, instruction.second]
end
address.push_mod_rm_on register, stream
end
def align16_on instruction, stream
stream << 0x66 if instruction.machine.bits != 16
end
def relative_x_on instruction, stream, msg, dist
offset = instruction.first
offset = offset.offset if offset.offset?
if offset.label? then
if offset.future_label? then
offset.add instruction.machine.stream.size + stream.size
return stream.send(msg, dist)
end
offset = offset.position
end
stream.send(msg, -(instruction.machine.stream.size - offset + dist))
end
def relative_b_on instruction, stream
relative_x_on instruction, stream, :push_B, 1
end
def relative_w_on instruction, stream
relative_x_on instruction, stream, :push_W, 2
end
def relative_d_on instruction, stream
relative_x_on instruction, stream, :push_D, 4
end
def modrm_n_instruction_on id, instruction, stream
instruction.first.push_mod_rm_on Register.on_id_bits(instruction.machine, id, instruction.first.bits), stream
end
def align32_on instruction, stream
if instruction.parameters.any? { |par| par.register? && par.bits == 32 }
stream << 0x67 if instruction.machine.bits != 32
else
stream << 0x48
instruction.x64_mode = true
end
end
def modrm_instruction_on byte, instruction, stream
if byte == "r" then
self.modrm_r_on instruction, stream
else
self.modrm_n_instruction_on byte.to_i, instruction, stream
end
end
end
##
# Instruction is an instruction shape that we're going to match to
# Commands to find out what we should write in to memory.
class Instruction
attr_accessor :opcode, :machine, :parameters, :x64_mode
def self.on_message machine, message # TODO: remove
self.new message, machine
end
def initialize message, machine
self.machine = machine
self.opcode, *self.parameters = message
self.opcode = opcode.to_s.upcase
self.machine = parameters[1].machine unless machine
self.parameters.map! { |each| Proc === each ? each.call.m : each }
self.parameters.each do |each|
each.machine = self.machine if each.operand?
end
self.x64_mode = false
end
def first
parameters.first
end
def second
parameters.second
end
def theAddress
parameters.detect { |e| e.address? }
end
def assemble
instructions = machine.instructions_by_mnemonic[self.opcode].select { |command|
command.instruction_applies? self
}
return false if instructions.empty?
# Heuristically select "smallest" instruction
instruction = instructions.each.with_index.min_by { |inst, i| [inst.opcodes.size, i] }.first
machine.stream.concat(instruction.assemble self)
true
end
def theSecondImmediate
parameters.detect { |e| e.immediate_value? }
end
def theImmediate
parameters.reverse.detect { |e| e.immediate_value? }
end
end
##
# MachineCode is an abstract machine that has subclasses for each
# concrete machine type that you can write assembly language for.
# Right now this library only supports X86, so look at
# MachineCodeX86 for more details on how to use it.
class MachineCode
attr_accessor :stream, :procedure, :bits
attr_accessor :instructions_by_mnemonic
def initialize
self.procedure = nil
self.bits = self.defaultBits
self.stream = []
self.setupMachine
end
def inspect
"#{self.class}#{stream.inspect}"
end
def method_missing msg, *args
super unless self.instructionFromMessage(msg, *args).assemble
end
def instructionFromMessage msg, *args
Instruction.on_message self, [msg, *args]
end
def label
Label.on_at(self, stream.size)
end
def flabel
FutureLabel.on self
end
def assemble instruction
raise "no"
# aBlock on: MessageNotUnderstood do: [:ex |
# ex originator class = BlockClosure ifFalse: [ex pass].
# ex resume: (ex originator value m perform: ex parameter selector withArguments: ex parameter arguments)]</body>
end
alias :setupMachine :subclass_responsibility
alias :platform :subclass_responsibility
alias :defaultBits :subclass_responsibility
end
##
# 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.
class MachineCodeX86 < MachineCode
# registers-general-64bit
attr_accessor :rax, :rbx, :rbp, :rsp, :rdi, :rsi, :rcx, :rdx
# Not supported yet
# attr_accessor :r8, :r9, :r10, :r11, :r12, :r13, :r14, :r15
# registers-general-32bit
attr_accessor :eax, :ebx, :ebp, :esp, :edi, :esi, :ecx, :edx
# registers-fpu
attr_accessor :st0, :st1, :st2, :st3, :st4, :st5, :st6, :st7
# registers-debug
attr_accessor :dr0, :dr1, :dr2, :dr3, :dr6, :dr7
# registers-segment
attr_accessor :es, :ss, :cs, :gs, :fs, :ds
# registers-test
attr_accessor :tr3, :tr4, :tr5, :tr6, :tr7
# registers-general-8bit
attr_accessor :al, :ah, :bl, :bh, :cl, :ch, :dl, :dh
# registers-general-16bit
attr_accessor :ax, :bx, :cx, :dx, :sp, :bp, :si, :di
# registers-control
attr_accessor :cr0, :cr2, :cr3, :cr4
# registers-mmx
attr_accessor :mm0, :mm1, :mm2, :mm3, :mm4, :mm5, :mm6, :mm7
def setupMachine
self.instructions_by_mnemonic = Assembler.commands_by_mnemonic
self.setup8BitRegisters
self.setup16BitRegisters
self.setup32BitRegisters
self.setup64BitRegisters
self.setupSegmentRegisters
self.setupControlRegisters
self.setupTestRegisters
self.setupDebugRegisters
self.setupFPURegisters
self.setupMMXRegisters
end
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
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
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
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
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
def setup64BitRegisters
self.rax = Register.on_id_bits self, 0, 64
self.rcx = Register.on_id_bits self, 1, 64
self.rdx = Register.on_id_bits self, 2, 64
self.rbx = Register.on_id_bits self, 3, 64
self.rsp = Register.on_id_bits self, 4, 64
self.rbp = Register.on_id_bits self, 5, 64
self.rsi = Register.on_id_bits self, 6, 64
self.rdi = Register.on_id_bits self, 7, 64
end
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
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
def platform
'x86_64'
end
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
def defaultBits
32
end
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
def syscall
# Override Ruby's syscall
method_missing :syscall
end
end
##
# Operand is any kind of operand used in a command or instruction,
# eg: registers, memory addresses, labels, immediates, etc.
class Operand
attr_accessor :machine, :bits
def self.on machine
x = self.new
x.machine = machine
x
end
# TODO: fix _all_ initialize methods from here down to have cleaner args
def initialize bits = nil, machine = nil
@bits = bits
@machine = machine
end
def method_missing msg, *args, &b
super unless self.instructionFromMessage(msg, *args, &b).assemble
end
def instructionFromMessage msg, *args, &b
Instruction.on_message machine, [msg, self, *args] + (b ? [b] : [])
end
def operand?
true
end
end
##
# Immediate is an Integer wrapper so that we know the machine we're
# dealing with when we apply commands
class Immediate < Operand
attr_accessor :value
def immediate?
true
end
end
##
# 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 self.on_id_offset machine, id, offset
address = self.new
address.machine = machine
address.id = id
address.offset = offset
address
end
def initialize isAssemblerOffset = nil, bits = nil, id = nil
super(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.register? then
@offset = 0
self.index = obj
else
@offset = obj
end
end
def + o # TODO: this seems totally and completely wrong
if o.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
# TODO: scale support
mod = case offset
when 0 then
0b00
when -128..127 then
0b01
when -(1<<15)..(1<<15)-1
0b10
else
0b11
end
modrm = (mod << 6) | id
sib = nil
if index.nil? then
modrm += (spareRegister.id << 3)
else
# use SIB
modrm = mod << 6 | spareRegister.id << 3 | 0b100
sib = index.id << 3 | id
if id == 0b101 and mod == 0b00 # -bp special case
mod = 0b01
modrm |= mod << 6
end
end
stream << modrm
stream << sib if sib
case mod
when 0b00
return self
when 0b01
return stream.push_B(offset)
when 0b10
return stream.push_W(offset)
when 0b11
return stream.push_D(offset)
end
end
def m
self
end
end
##
# Register is a general X86 register, such as eax, ebx, ecx, edx,
# etc...
class Register < Operand
attr_accessor :id
def self.on_id_bits machine, id, bits
self.new bits, machine, id
end
def initialize bits = nil, machine = nil, id = nil
super(bits, machine)
self.id = id
end
def memory_register?
false
end
def register?
true
end
def get address # TODO: test
self.mov address
self.mov {self}
end
def push_mod_rm_on spareRegister, stream
stream << (0b11000000 + id + (spareRegister.id << 3))
end
def m
self + 0
end
def - offset
self + -offset
end
def + offset
Address.on_id_offset machine, id, offset
end
end
##
# MemoryRegister is a regular Register, but the parser needs to know
# if it is a primary or secondary register. This form is a private
# secondary register. Use Register instead of this guy.
class MemoryRegister < Register
def memory_register?
true
end
end
##
# Label is a known point in the byte stream that we can jmp/loop back to.
class Label < Operand
attr_accessor :position
def self.on_at machine, position
label = self.new
label.machine = machine
label.position = position
label
end
def bits
distance = machine.stream.size - position
if distance < (1<<7)
8
elsif distance < (1<<15)
16
elsif distance < (1<<31)
32
else
64
end
end
def label?
true
end
end
##
# FutureLabel is a label in memory that hasn't been defined yet and
# will go back and fill in the appropriate memory bytes later
class FutureLabel < Label
attr_accessor :positions
def initialize
super
self.positions = []
end
def plant
self.position = machine.stream.size
positions.each do |pos|
size = machine.stream[pos]
address = []
case size
when 1 then
address.push_B(position - pos - 1)
when 2 then
address.push_W(position - pos - 2)
when 4 then
address.push_D(position - pos - 4)
else
raise "unhandled size #{size}"
end
machine.stream[pos...pos+size] = address
end
end
def future_label?
position.nil?
end
def add aPosition
positions << aPosition
end
end
##
# SpecialRegister is the abstract implementation of any kind of
# register that isn't a general register, eg: segment registers, mmx
# registers, fpu registers, etc...
class SpecialRegister < Operand
attr_accessor :id
def self.on_id machine, id
register = self.new
register.machine = machine
register.id = id
register
end
def special_register?
true
end
end
##
# DebugRegister is an X86 DRx register
class DebugRegister < SpecialRegister
end
##
# TestRegister is an X86 Test Register, TRx
class TestRegister < SpecialRegister
end
##
# FPURegister is an X86 fpureg, STx
class FPURegister < SpecialRegister
def initialize id = nil
super()
self.id = id
end
end
##
# ControlRegister is an X86 CRx register
class ControlRegister < SpecialRegister
end
##
# MMXRegister is an X86 MMX register
class MMXRegister < SpecialRegister
def push_mod_rm_on spareRegister, stream
stream << (0b11000000 + id + (spareRegister.id << 3))
end
end
##
# SegmentRegister is an X86 segment register, eg: ss, cs, ds, es...
class SegmentRegister < SpecialRegister
end
end # module Wilson
require 'rbconfig'
class Integer
def m
address = Wilson::Address.new
address.offset = self
address
end
def immediate_value?
true
end
def inspect
"0x#{to_s 16}"
end if $DEBUG
end
class Array
def second
self[1]
end
def push_B integer
self << (integer & 255)
end
def push_W integer
self.push((integer & 255), (integer >> 8 & 255))
end
def push_D integer
self.push(*[integer].pack("V").unpack("C4"))
end
def push_Q integer
self.push_D(integer & (1<<32)-1)
self.push_D(integer >> 32)
end
end
class Module
def defasm name, *args, &block
fn = assemble(*args, &block)
define_method(name, &fn)
end
end
class Object
def assemble *args, &block
asm = Wilson::MachineCodeX86.new
# TODO: enter?
asm.rbp.push
asm.rbp.mov asm.rsp
size = asm.stream.size
asm.instance_eval(&block)
if asm.stream.size == size # return nil
warn "returning nil for #{self}"
asm.rax.mov 0
end
asm.rbp.pop
asm.ret
code = asm.stream.pack("C*")
if $DEBUG then
path = "#{$$}.obj"
File.open path, "wb" do |f|
f.write code
end
puts code.unpack("C*").map { |n| "%02X" % n }.join(' ')
system "ndisasm -b 64 #{path}"
File.unlink path
end
ptr = LibC.mmap_rwx code.size
LibC.memcpy(ptr, code, code.size)
Fiddle::Function.new(ptr, [Fiddle::TYPE_LONG]*args.size, Fiddle::TYPE_LONG)
end
def asm(*args, &block)
assemble(*args, &block).call(*args)
end
end
main
__END__
AAA ; 37 [8086]
AAS ; 3F [8086]
AAD ; D5 0A [8086]
AAD imm ; D5 ib [8086]
AAM ; D4 0A [8086]
AAM imm ; D4 ib [8086]
ADC r/m8,reg8 ; 10 /r [8086]
ADC r/m16,reg16 ; o16 11 /r [8086]
ADC r/m32,reg32 ; o32 11 /r [386]
ADC reg8,r/m8 ; 12 /r [8086]
ADC reg16,r/m16 ; o16 13 /r [8086]
ADC reg32,r/m32 ; o32 13 /r [386]
ADC r/m8,imm8 ; 80 /2 ib [8086]
ADC r/m16,imm16 ; o16 81 /2 iw [8086]
ADC r/m32,imm32 ; o32 81 /2 id [386]
ADC r/m16,imm8 ; o16 83 /2 ib [8086]
ADC r/m32,imm8 ; o32 83 /2 ib [386]
ADC AL,imm8 ; 14 ib [8086]
ADC AX,imm16 ; o16 15 iw [8086]
ADC EAX,imm32 ; o32 15 id [386]
ADD r/m8,reg8 ; 00 /r [8086]
ADD r/m16,reg16 ; o16 01 /r [8086]
ADD r/m32,reg32 ; o32 01 /r [386]
ADD reg8,r/m8 ; 02 /r [8086]
ADD reg16,r/m16 ; o16 03 /r [8086]
ADD reg32,r/m32 ; o32 03 /r [386]
ADD r/m8,imm8 ; 80 /0 ib [8086]
ADD r/m16,imm16 ; o16 81 /0 iw [8086]
ADD r/m32,imm32 ; o32 81 /0 id [386]
ADD r/m16,imm8 ; o16 83 /0 ib [8086]
ADD r/m32,imm8 ; o32 83 /0 ib [386]
ADD AL,imm8 ; 04 ib [8086]
ADD AX,imm16 ; o16 05 iw [8086]
ADD EAX,imm32 ; o32 05 id [386]
AND r/m8,reg8 ; 20 /r [8086]
AND r/m16,reg16 ; o16 21 /r [8086]
AND r/m32,reg32 ; o32 21 /r [386]
AND reg8,r/m8 ; 22 /r [8086]
AND reg16,r/m16 ; o16 23 /r [8086]
AND reg32,r/m32 ; o32 23 /r [386]
AND r/m8,imm8 ; 80 /4 ib [8086]
AND r/m16,imm16 ; o16 81 /4 iw [8086]
AND r/m32,imm32 ; o32 81 /4 id [386]
AND r/m16,imm8 ; o16 83 /4 ib [8086]
AND r/m32,imm8 ; o32 83 /4 ib [386]
AND AL,imm8 ; 24 ib [8086]
AND AX,imm16 ; o16 25 iw [8086]
AND EAX,imm32 ; o32 25 id [386]
ARPL r/m16,reg16 ; 63 /r [286,PRIV]
BOUND reg16,mem ; o16 62 /r [186]
BOUND reg32,mem ; o32 62 /r [386]
BSF reg16,r/m16 ; o16 0F BC /r [386]
BSF reg32,r/m32 ; o32 0F BC /r [386]
BSR reg16,r/m16 ; o16 0F BD /r [386]
BSR reg32,r/m32 ; o32 0F BD /r [386]
BSWAP reg32 ; o32 0F C8+r [486]
BT r/m16,reg16 ; o16 0F A3 /r [386]
BT r/m32,reg32 ; o32 0F A3 /r [386]
BT r/m16,imm8 ; o16 0F BA /4 ib [386]
BT r/m32,imm8 ; o32 0F BA /4 ib [386]
BTC r/m16,reg16 ; o16 0F BB /r [386]
BTC r/m32,reg32 ; o32 0F BB /r [386]
BTC r/m16,imm8 ; o16 0F BA /7 ib [386]
BTC r/m32,imm8 ; o32 0F BA /7 ib [386]
BTR r/m16,reg16 ; o16 0F B3 /r [386]
BTR r/m32,reg32 ; o32 0F B3 /r [386]
BTR r/m16,imm8 ; o16 0F BA /6 ib [386]
BTR r/m32,imm8 ; o32 0F BA /6 ib [386]
BTS r/m16,reg16 ; o16 0F AB /r [386]
BTS r/m32,reg32 ; o32 0F AB /r [386]
BTS r/m16,imm ; o16 0F BA /5 ib [386]
BTS r/m32,imm ; o32 0F BA /5 ib [386]
CALL imm ; E8 rw/rd [8086]
CALL imm:imm16 ; o16 9A iw iw [8086]
CALL imm:imm32 ; o32 9A id iw [386]
CALL FAR mem16 ; o16 FF /3 [8086]
CALL FAR mem32 ; o32 FF /3 [386]
CALL r/m16 ; o16 FF /2 [8086]
CALL r/m32 ; o32 FF /2 [386]
CBW ; o16 98 [8086]
CWD ; o16 99 [8086]
CDQ ; o32 99 [386]
CWDE ; o32 98 [386]
CLC ; F8 [8086]
CLD ; FC [8086]
CLI ; FA [8086]
CLTS ; 0F 06 [286,PRIV]
CMC ; F5 [8086]
CMOVcc reg16,r/m16 ; o16 0F 40+cc /r [P6]
CMOVcc reg32,r/m32 ; o32 0F 40+cc /r [P6]
CMP r/m8,reg8 ; 38 /r [8086]
CMP r/m16,reg16 ; o16 39 /r [8086]
CMP r/m32,reg32 ; o32 39 /r [386]
CMP reg8,r/m8 ; 3A /r [8086]
CMP reg16,r/m16 ; o16 3B /r [8086]
CMP reg32,r/m32 ; o32 3B /r [386]
CMP r/m8,imm8 ; 80 /0 ib [8086]
CMP r/m16,imm16 ; o16 81 /0 iw [8086]
CMP r/m32,imm32 ; o32 81 /0 id [386]
DEADCMP r/m16,imm8 ; o16 83 /0 ib [8086]
DEADCMP r/m32,imm8 ; o32 83 /0 ib [386]
CMP AL,imm8 ; 3C ib [8086]
CMP AX,imm16 ; o16 3D iw [8086]
CMP EAX,imm32 ; o32 3D id [386]
CMPSB ; A6 [8086]
CMPSW ; o16 A7 [8086]
CMPSD ; o32 A7 [386]
CMPXCHG r/m8,reg8 ; 0F B0 /r [PENT]
CMPXCHG r/m16,reg16 ; o16 0F B1 /r [PENT]
CMPXCHG r/m32,reg32 ; o32 0F B1 /r [PENT]
CMPXCHG486 r/m8,reg8 ; 0F A6 /r [486,UNDOC]
CMPXCHG486 r/m16,reg16 ; o16 0F A7 /r [486,UNDOC]
CMPXCHG486 r/m32,reg32 ; o32 0F A7 /r [486,UNDOC]
CMPXCHG8B mem ; 0F C7 /1 [PENT]
CPUID ; 0F A2 [PENT]
DAA ; 27 [8086]
DAS ; 2F [8086]
DEC r/m8 ; FE /1 [8086]
DEC r/m16 ; o16 FF /1 [8086]
DEC r/m32 ; o32 FF /1 [386]
DIV r/m8 ; F6 /6 [8086]
DIV r/m16 ; o16 F7 /6 [8086]
DIV r/m32 ; o32 F7 /6 [386]
MMS ; 0F 77 [PENT,MMX]
ENTER imm,imm ; C8 iw ib [186]
F2XM1 ; D9 F0 [8086,FPU]
FABS ; D9 E1 [8086,FPU]
FADD mem32 ; D8 /0 [8086,FPU]
FADD mem64 ; DC /0 [8086,FPU]
FADD fpureg ; D8 C0+r [8086,FPU]
FADD ST0,fpureg ; D8 C0+r [8086,FPU]
FADD TO fpureg ; DC C0+r [8086,FPU]
FADD fpureg,ST0 ; DC C0+r [8086,FPU]
FADDP fpureg ; DE C0+r [8086,FPU]
FADDP fpureg,ST0 ; DE C0+r [8086,FPU]
FBLD mem80 ; DF /4 [8086,FPU]
FBSTP mem80 ; DF /6 [8086,FPU]
FCHS ; D9 E0 [8086,FPU]
FCLEX ; 9B DB E2 [8086,FPU]
FNCLEX ; DB E2 [8086,FPU]
FCMOVB fpureg ; DA C0+r [P6,FPU]
FCMOVB ST0,fpureg ; DA C0+r [P6,FPU]
FCMOVBE fpureg ; DA D0+r [P6,FPU]
FCMOVBE ST0,fpureg ; DA D0+r [P6,FPU]
FCMOVE fpureg ; DA C8+r [P6,FPU]
FCMOVE ST0,fpureg ; DA C8+r [P6,FPU]
FCMOVNB fpureg ; DB C0+r [P6,FPU]
FCMOVNB ST0,fpureg ; DB C0+r [P6,FPU]
FCMOVNBE fpureg ; DB D0+r [P6,FPU]
FCMOVNBE ST0,fpureg ; DB D0+r [P6,FPU]
FCMOVNE fpureg ; DB C8+r [P6,FPU]
FCMOVNE ST0,fpureg ; DB C8+r [P6,FPU]
FCMOVNU fpureg ; DB D8+r [P6,FPU]
FCMOVNU ST0,fpureg ; DB D8+r [P6,FPU]
FCMOVU fpureg ; DA D8+r [P6,FPU]
FCMOVU ST0,fpureg ; DA D8+r [P6,FPU]
FCOM mem32 ; D8 /2 [8086,FPU]
FCOM mem64 ; DC /2 [8086,FPU]
FCOM fpureg ; D8 D0+r [8086,FPU]
FCOM ST0,fpureg ; D8 D0+r [8086,FPU]
FCOMP mem32 ; D8 /3 [8086,FPU]
FCOMP mem64 ; DC /3 [8086,FPU]
FCOMP fpureg ; D8 D8+r [8086,FPU]
FCOMP ST0,fpureg ; D8 D8+r [8086,FPU]
FCOMPP ; DE D9 [8086,FPU]
FCOMI fpureg ; DB F0+r [P6,FPU]
FCOMI ST0,fpureg ; DB F0+r [P6,FPU]
FCOMIP fpureg ; DF F0+r [P6,FPU]
FCOMIP ST0,fpureg ; DF F0+r [P6,FPU]
FCOS ; D9 FF [386,FPU]
FDECSTP ; D9 F6 [8086,FPU]
FDISI ; 9B DB E1 [8086,FPU]
FNDISI ; DB E1 [8086,FPU]
FENI ; 9B DB E0 [8086,FPU]
FNENI ; DB E0 [8086,FPU]
FDIV mem32 ; D8 /6 [8086,FPU]
FDIV mem64 ; DC /6 [8086,FPU]
FDIV fpureg ; D8 F0+r [8086,FPU]
FDIV ST0,fpureg ; D8 F0+r [8086,FPU]
FDIV TO fpureg ; DC F8+r [8086,FPU]
FDIV fpureg,ST0 ; DC F8+r [8086,FPU]
FDIVR mem32 ; D8 /0 [8086,FPU]
FDIVR mem64 ; DC /0 [8086,FPU]
FDIVR fpureg ; D8 F8+r [8086,FPU]
FDIVR ST0,fpureg ; D8 F8+r [8086,FPU]
FDIVR TO fpureg ; DC F0+r [8086,FPU]
FDIVR fpureg,ST0 ; DC F0+r [8086,FPU]
FDIVP fpureg ; DE F8+r [8086,FPU]
FDIVP fpureg,ST0 ; DE F8+r [8086,FPU]
FDIVRP fpureg ; DE F0+r [8086,FPU]
FDIVRP fpureg,ST0 ; DE F0+r [8086,FPU]
FFREE fpureg ; DD C0+r [8086,FPU]
FIADD mem16 ; DE /0 [8086,FPU]
FIADD mem32 ; DA /0 [8086,FPU]
FICOM mem16 ; DE /2 [8086,FPU]
FICOM mem32 ; DA /2 [8086,FPU]
FICOMP mem16 ; DE /3 [8086,FPU]
FICOMP mem32 ; DA /3 [8086,FPU]
FIDIV mem16 ; DE /6 [8086,FPU]
FIDIV mem32 ; DA /6 [8086,FPU]
FIDIVR mem16 ; DE /0 [8086,FPU]
FIDIVR mem32 ; DA /0 [8086,FPU]
FILD mem16 ; DF /0 [8086,FPU]
FILD mem32 ; DB /0 [8086,FPU]
FILD mem64 ; DF /5 [8086,FPU]
FIST mem16 ; DF /2 [8086,FPU]
FIST mem32 ; DB /2 [8086,FPU]
FISTP mem16 ; DF /3 [8086,FPU]
FISTP mem32 ; DB /3 [8086,FPU]
FISTP mem64 ; DF /0 [8086,FPU]
FIMUL mem16 ; DE /1 [8086,FPU]
FIMUL mem32 ; DA /1 [8086,FPU]
FINCSTP ; D9 F7 [8086,FPU]
FINIT ; 9B DB E3 [8086,FPU]
FNINIT ; DB E3 [8086,FPU]
FISUB mem16 ; DE /4 [8086,FPU]
FISUB mem32 ; DA /4 [8086,FPU]
FISUBR mem16 ; DE /5 [8086,FPU]
FISUBR mem32 ; DA /5 [8086,FPU]
FLD mem32 ; D9 /0 [8086,FPU]
FLD mem64 ; DD /0 [8086,FPU]
FLD mem80 ; DB /5 [8086,FPU]
FLD fpureg ; D9 C0+r [8086,FPU]
FLD1 ; D9 E8 [8086,FPU]
FLDL2E ; D9 EA [8086,FPU]
FLDL2T ; D9 E9 [8086,FPU]
FLDLG2 ; D9 EC [8086,FPU]
FLDLN2 ; D9 ED [8086,FPU]
FLDPI ; D9 EB [8086,FPU]
FLDZ ; D9 EE [8086,FPU]
FLDCW mem16 ; D9 /5 [8086,FPU]
FLDENV mem ; D9 /4 [8086,FPU]
FMUL mem32 ; D8 /1 [8086,FPU]
FMUL mem64 ; DC /1 [8086,FPU]
FMUL fpureg ; D8 C8+r [8086,FPU]
FMUL ST0,fpureg ; D8 C8+r [8086,FPU]
FMUL TO fpureg ; DC C8+r [8086,FPU]
FMUL fpureg,ST0 ; DC C8+r [8086,FPU]
FMULP fpureg ; DE C8+r [8086,FPU]
FMULP fpureg,ST0 ; DE C8+r [8086,FPU]
FNOP ; D9 D0 [8086,FPU]
FPATAN ; D9 F3 [8086,FPU]
FPTAN ; D9 F2 [8086,FPU]
FPREM ; D9 F8 [8086,FPU]
FPREM1 ; D9 F5 [386,FPU]
FRNDINT ; D9 FC [8086,FPU]
FSAVE mem ; 9B DD /6 [8086,FPU]
FNSAVE mem ; DD /6 [8086,FPU]
FRSTOR mem ; DD /4 [8086,FPU]
FSCALE ; D9 FD [8086,FPU]
FSETPM ; DB E4 [286,FPU]
FSIN ; D9 FE [386,FPU]
FSINCOS ; D9 FB [386,FPU]
FSQRT ; D9 FA [8086,FPU]
FST mem32 ; D9 /2 [8086,FPU]
FST mem64 ; DD /2 [8086,FPU]
FST fpureg ; DD D0+r [8086,FPU]
FSTP mem32 ; D9 /3 [8086,FPU]
FSTP mem64 ; DD /3 [8086,FPU]
FSTP mem80 ; DB /0 [8086,FPU]
FSTP fpureg ; DD D8+r [8086,FPU]
FSTCW mem16 ; 9B D9 /0 [8086,FPU]
FNSTCW mem16 ; D9 /0 [8086,FPU]
FSTENV mem ; 9B D9 /6 [8086,FPU]
FNSTENV mem ; D9 /6 [8086,FPU]
FSTSW mem16 ; 9B DD /0 [8086,FPU]
FSTSW AX ; 9B DF E0 [286,FPU]
FNSTSW mem16 ; DD /0 [8086,FPU]
FNSTSW AX ; DF E0 [286,FPU]
FSUB mem32 ; D8 /4 [8086,FPU]
FSUB mem64 ; DC /4 [8086,FPU]
FSUB fpureg ; D8 E0+r [8086,FPU]
FSUB ST0,fpureg ; D8 E0+r [8086,FPU]
FSUB TO fpureg ; DC E8+r [8086,FPU]
FSUB fpureg,ST0 ; DC E8+r [8086,FPU]
FSUBR mem32 ; D8 /5 [8086,FPU]
FSUBR mem64 ; DC /5 [8086,FPU]
FSUBR fpureg ; D8 E8+r [8086,FPU]
FSUBR ST0,fpureg ; D8 E8+r [8086,FPU]
FSUBR TO fpureg ; DC E0+r [8086,FPU]
FSUBR fpureg,ST0 ; DC E0+r [8086,FPU]
FSUBP fpureg ; DE E8+r [8086,FPU]
FSUBP fpureg,ST0 ; DE E8+r [8086,FPU]
FSUBRP fpureg ; DE E0+r [8086,FPU]
FSUBRP fpureg,ST0 ; DE E0+r [8086,FPU]
FTST ; D9 E4 [8086,FPU]
FUCOM fpureg ; DD E0+r [386,FPU]
FUCOM ST0,fpureg ; DD E0+r [386,FPU]
FUCOMP fpureg ; DD E8+r [386,FPU]
FUCOMP ST0,fpureg ; DD E8+r [386,FPU]
FUCOMPP ; DA E9 [386,FPU]
FUCOMI fpureg ; DB E8+r [P6,FPU]
FUCOMI ST0,fpureg ; DB E8+r [P6,FPU]
FUCOMIP fpureg ; DF E8+r [P6,FPU]
FUCOMIP ST0,fpureg ; DF E8+r [P6,FPU]
FXAM ; D9 E5 [8086,FPU]
FXCH ; D9 C9 [8086,FPU]
FXCH fpureg ; D9 C8+r [8086,FPU]
FXCH fpureg,ST0 ; D9 C8+r [8086,FPU]
FXCH ST0,fpureg ; D9 C8+r [8086,FPU]
FXTRACT ; D9 F4 [8086,FPU]
FYL2X ; D9 F1 [8086,FPU]
FYL2XP1 ; D9 F9 [8086,FPU]
HLT ; F4 [8086]
IBTS r/m16,reg16 ; o16 0F A7 /r [386,UNDOC]
IBTS r/m32,reg32 ; o32 0F A7 /r [386,UNDOC]
IDIV r/m8 ; F6 /7 [8086]
IDIV r/m16 ; o16 F7 /7 [8086]
IDIV r/m32 ; o32 F7 /7 [386]
IMUL r/m8 ; F6 /5 [8086]
IMUL r/m16 ; o16 F7 /5 [8086]
IMUL r/m32 ; o32 F7 /5 [386]
IMUL reg16,r/m16 ; o16 0F AF /r [386]
IMUL reg32,r/m32 ; o32 0F AF /r [386]
IMUL reg16,imm8 ; o16 6B /r ib [286]
IMUL reg16,imm16 ; o16 69 /r iw [286]
IMUL reg32,imm8 ; o32 6B /r ib [386]
IMUL reg32,imm32 ; o32 69 /r id [386]
IMUL reg16,r/m16,imm8 ; o16 6B /r ib [286]
IMUL reg16,r/m16,imm16 ; o16 69 /r iw [286]
IMUL reg32,r/m32,imm8 ; o32 6B /r ib [386]
IMUL reg32,r/m32,imm32 ; o32 69 /r id [386]
IN AL,imm8 ; E4 ib [8086]
IN AX,imm8 ; o16 E5 ib [8086]
IN EAX,imm8 ; o32 E5 ib [386]
IN AL,DX ; EC [8086]
IN AX,DX ; o16 ED [8086]
IN EAX,DX ; o32 ED [386]
INC r/m8 ; FE /0 [8086]
INC r/m16 ; o16 FF /0 [8086]
INC r/m32 ; o32 FF /0 [386]
INSB ; 6C [186]
INSW ; o16 6D [186]
INSD ; o32 6D [386]
INT imm8 ; CD ib [8086]
INT1 ; F1 [P6]
ICEBP ; F1 [P6]
INT01 ; F1 [P6]
INT3 ; CC [8086]
INTO ; CE [8086]
INVD ; 0F 08 [486]
INVLPG mem ; 0F 01 /0 [486]
IRET ; CF [8086]
IRETW ; o16 CF [8086]
IRETD ; o32 CF [386]
JCXZ imm ; o16 E3 rb [8086]
JECXZ imm ; o32 E3 rb [386]
JMP imm ; E9 rw/rd [8086]
JMP SHORT imm ; EB rb [8086]
JMP imm:imm16 ; o16 EA iw iw [8086]
JMP imm:imm32 ; o32 EA id iw [386]
JMP FAR mem ; o16 FF /5 [8086]
JMP FAR mem ; o32 FF /5 [386]
JMP r/m16 ; o16 FF /4 [8086]
JMP r/m32 ; o32 FF /4 [386]
Jcc imm ; 70+cc rb [8086]
Jcc NEAR imm ; 0F 80+cc rw/rd [386]
LAHF ; 9F [8086]
LAR reg16,r/m16 ; o16 0F 02 /r [286,PRIV]
LAR reg32,r/m32 ; o32 0F 02 /r [286,PRIV]
LDS reg16,mem ; o16 C5 /r [8086]
LDS reg32,mem ; o32 C5 /r [8086]
LES reg16,mem ; o16 C4 /r [8086]
LES reg32,mem ; o32 C4 /r [8086]
LFS reg16,mem ; o16 0F B4 /r [386]
LFS reg32,mem ; o32 0F B4 /r [386]
LGS reg16,mem ; o16 0F B5 /r [386]
LGS reg32,mem ; o32 0F B5 /r [386]
LSS reg16,mem ; o16 0F B2 /r [386]
LSS reg32,mem ; o32 0F B2 /r [386]
LEA reg16,mem ; o16 8D /r [8086]
LEA reg32,mem ; o32 8D /r [8086]
LEAVE ; C9 [186]
LGDT mem ; 0F 01 /2 [286,PRIV]
LIDT mem ; 0F 01 /3 [286,PRIV]
LLDT r/m16 ; 0F 00 /2 [286,PRIV]
LMSW r/m16 ; 0F 01 /6 [286,PRIV]
LOADALL ; 0F 07 [386,UNDOC]
LOADALL286 ; 0F 05 [286,UNDOC]
LODSB ; AC [8086]
LODSW ; o16 AD [8086]
LODSD ; o32 AD [386]
LOOP imm ; E2 rb [8086]
LOOP imm,CX ; a16 E2 rb [8086]
LOOP imm,ECX ; a32 E2 rb [386]
LOOPE imm ; E1 rb [8086]
LOOPE imm,CX ; a16 E1 rb [8086]
LOOPE imm,ECX ; a32 E1 rb [386]
LOOPZ imm ; E1 rb [8086]
LOOPZ imm,CX ; a16 E1 rb [8086]
LOOPZ imm,ECX ; a32 E1 rb [386]
LOOPNE imm ; E0 rb [8086]
LOOPNE imm,CX ; a16 E0 rb [8086]
LOOPNE imm,ECX ; a32 E0 rb [386]
LOOPNZ imm ; E0 rb [8086]
LOOPNZ imm,CX ; a16 E0 rb [8086]
LOOPNZ imm,ECX ; a32 E0 rb [386]
LSL reg16,r/m16 ; o16 0F 03 /r [286,PRIV]
LSL reg32,r/m32 ; o32 0F 03 /r [286,PRIV]
LTR r/m16 ; 0F 00 /3 [286,PRIV]
MOV r/m8,reg8 ; 88 /r [8086]
MOV r/m16,reg16 ; o16 89 /r [8086]
MOV r/m32,reg32 ; o32 89 /r [386]
MOV reg8,r/m8 ; 8A /r [8086]
MOV reg16,r/m16 ; o16 8B /r [8086]
MOV reg32,r/m32 ; o32 8B /r [386]
MOV reg8,imm8 ; B0+r ib [8086]
MOV reg16,imm16 ; o16 B8+r iw [8086]
MOV reg32,imm32 ; o32 B8+r id [386]
MOV r/m8,imm8 ; C6 /0 ib [8086]
MOV r/m16,imm16 ; o16 C7 /0 iw [8086]
MOV r/m32,imm32 ; o32 C7 /0 id [386]
MOV AL,memoffs8 ; A0 ow/od [8086]
MOV AX,memoffs16 ; o16 A1 ow/od [8086]
MOV EAX,memoffs32 ; o32 A1 ow/od [386]
MOV memoffs8,AL ; A2 ow/od [8086]
MOV memoffs16,AX ; o16 A3 ow/od [8086]
MOV memoffs32,EAX ; o32 A3 ow/od [386]
MOV r/m16,segreg ; o16 8C /r [8086]
MOV r/m32,segreg ; o32 8C /r [386]
MOV segreg,r/m16 ; o16 8E /r [8086]
MOV segreg,r/m32 ; o32 8E /r [386]
MOV reg32,CR0/2/3/4 ; 0F 20 /r [386]
MOV reg32,DR0/1/2/3/6/7 ; 0F 21 /r [386]
MOV reg32,TR3/4/5/6/7 ; 0F 24 /r [386]
MOV CR0/2/3/4,reg32 ; 0F 22 /r [386]
MOV DR0/1/2/3/6/7,reg32 ; 0F 23 /r [386]
MOV TR3/4/5/6/7,reg32 ; 0F 26 /r [386]
MOVD mmxreg,r/m32 ; 0F 6E /r [PENT,MMX]
MOVD r/m32,mmxreg ; 0F 7E /r [PENT,MMX]
MOVQ mmxreg,r/m64 ; 0F 6F /r [PENT,MMX]
MOVQ r/m64,mmxreg ; 0F 7F /r [PENT,MMX]
MOVSB ; A4 [8086]
MOVSW ; o16 A5 [8086]
MOVSD ; o32 A5 [386]
MOVSX reg16,r/m8 ; o16 0F BE /r [386]
MOVSX reg32,r/m8 ; o32 0F BE /r [386]
MOVSX reg32,r/m16 ; o32 0F BF /r [386]
MOVZX reg16,r/m8 ; o16 0F B6 /r [386]
MOVZX reg32,r/m8 ; o32 0F B6 /r [386]
MOVZX reg32,r/m16 ; o32 0F B7 /r [386]
MUL r/m8 ; F6 /4 [8086]
MUL r/m16 ; o16 F7 /4 [8086]
MUL r/m32 ; o32 F7 /4 [386]
NEG r/m8 ; F6 /3 [8086]
NEG r/m16 ; o16 F7 /3 [8086]
NEG r/m32 ; o32 F7 /3 [386]
NOT r/m8 ; F6 /2 [8086]
NOT r/m16 ; o16 F7 /2 [8086]
NOT r/m32 ; o32 F7 /2 [386]
NOP ; 90 [8086]
OR r/m8,reg8 ; 08 /r [8086]
OR r/m16,reg16 ; o16 09 /r [8086]
OR r/m32,reg32 ; o32 09 /r [386]
OR reg8,r/m8 ; 0A /r [8086]
OR reg16,r/m16 ; o16 0B /r [8086]
OR reg32,r/m32 ; o32 0B /r [386]
OR r/m8,imm8 ; 80 /1 ib [8086]
OR r/m16,imm16 ; o16 81 /1 iw [8086]
OR r/m32,imm32 ; o32 81 /1 id [386]
OR r/m16,imm8 ; o16 83 /1 ib [8086]
OR r/m32,imm8 ; o32 83 /1 ib [386]
OR AL,imm8 ; 0C ib [8086]
OR AX,imm16 ; o16 0D iw [8086]
OR EAX,imm32 ; o32 0D id [386]
OUT imm8,AL ; E6 ib [8086]
OUT imm8,AX ; o16 E7 ib [8086]
OUT imm8,EAX ; o32 E7 ib [386]
OUT DX,AL ; EE [8086]
OUT DX,AX ; o16 EF [8086]
OUT DX,EAX ; o32 EF [386]
OUTSB ; 6E [186]
OUTSW ; o16 6F [186]
OUTSD ; o32 6F [386]
PACKSSDW mmxreg,r/m64 ; 0F 6B /r [PENT,MMX]
PACKSSWB mmxreg,r/m64 ; 0F 63 /r [PENT,MMX]
PACKUSWB mmxreg,r/m64 ; 0F 67 /r [PENT,MMX]
PADDB mmxreg,r/m64 ; 0F FC /r [PENT,MMX]
PADDW mmxreg,r/m64 ; 0F FD /r [PENT,MMX]
PADDD mmxreg,r/m64 ; 0F FE /r [PENT,MMX]
PADDSB mmxreg,r/m64 ; 0F EC /r [PENT,MMX]
PADDSW mmxreg,r/m64 ; 0F ED /r [PENT,MMX]
PADDUSB mmxreg,r/m64 ; 0F DC /r [PENT,MMX]
PADDUSW mmxreg,r/m64 ; 0F DD /r [PENT,MMX]
PADDSIW mmxreg,r/m64 ; 0F 51 /r [CYRIX,MMX]
PAND mmxreg,r/m64 ; 0F DB /r [PENT,MMX]
PANDN mmxreg,r/m64 ; 0F DF /r [PENT,MMX]
PAVEB mmxreg,r/m64 ; 0F 50 /r [CYRIX,MMX]
PCMPEQB mmxreg,r/m64 ; 0F 74 /r [PENT,MMX]
PCMPEQW mmxreg,r/m64 ; 0F 75 /r [PENT,MMX]
PCMPEQD mmxreg,r/m64 ; 0F 76 /r [PENT,MMX]
PCMPGTB mmxreg,r/m64 ; 0F 64 /r [PENT,MMX]
PCMPGTW mmxreg,r/m64 ; 0F 65 /r [PENT,MMX]
PCMPGTD mmxreg,r/m64 ; 0F 66 /r [PENT,MMX]
PDISTIB mmxreg,mem64 ; 0F 54 /r [CYRIX,MMX]
PMACHRIW mmxreg,mem64 ; 0F 5E /r [CYRIX,MMX]
PMADDWD mmxreg,r/m64 ; 0F F5 /r [PENT,MMX]
PMAGW mmxreg,r/m64 ; 0F 52 /r [CYRIX,MMX]
PMULHRW mmxreg,r/m64 ; 0F 59 /r [CYRIX,MMX]
PMULHRIW mmxreg,r/m64 ; 0F 5D /r [CYRIX,MMX]
PMULHW mmxreg,r/m64 ; 0F E5 /r [PENT,MMX]
PMULLW mmxreg,r/m64 ; 0F D5 /r [PENT,MMX]
PMVZB mmxreg,mem64 ; 0F 58 /r [CYRIX,MMX]
PMVNZB mmxreg,mem64 ; 0F 5A /r [CYRIX,MMX]
PMVLZB mmxreg,mem64 ; 0F 5B /r [CYRIX,MMX]
PMVGEZB mmxreg,mem64 ; 0F 5C /r [CYRIX,MMX]
POP reg16 ; o16 58+r [8086]
POP reg32 ; o32 58+r [386]
POP r/m16 ; o16 8F /0 [8086]
POP r/m32 ; o32 8F /0 [386]
POP CS ; 0F [8086,UNDOC]
POP DS ; 1F [8086]
POP ES ; 07 [8086]
POP SS ; 17 [8086]
POP FS ; 0F A1 [386]
POP GS ; 0F A9 [386]
POPA ; 61 [186]
POPAW ; o16 61 [186]
POPAD ; o32 61 [386]
POPF ; 9D [186]
POPFW ; o16 9D [186]
POPFD ; o32 9D [386]
POR mmxreg,r/m64 ; 0F EB /r [PENT,MMX]
PSLLW mmxreg,r/m64 ; 0F F1 /r [PENT,MMX]
PSLLW mmxreg,imm8 ; 0F 71 /6 ib [PENT,MMX]
PSLLD mmxreg,r/m64 ; 0F F2 /r [PENT,MMX]
PSLLD mmxreg,imm8 ; 0F 72 /6 ib [PENT,MMX]
PSLLQ mmxreg,r/m64 ; 0F F3 /r [PENT,MMX]
PSLLQ mmxreg,imm8 ; 0F 73 /6 ib [PENT,MMX]
PSRAW mmxreg,r/m64 ; 0F E1 /r [PENT,MMX]
PSRAW mmxreg,imm8 ; 0F 71 /4 ib [PENT,MMX]
PSRAD mmxreg,r/m64 ; 0F E2 /r [PENT,MMX]
PSRAD mmxreg,imm8 ; 0F 72 /4 ib [PENT,MMX]
PSRLW mmxreg,r/m64 ; 0F D1 /r [PENT,MMX]
PSRLW mmxreg,imm8 ; 0F 71 /2 ib [PENT,MMX]
PSRLD mmxreg,r/m64 ; 0F D2 /r [PENT,MMX]
PSRLD mmxreg,imm8 ; 0F 72 /2 ib [PENT,MMX]
PSRLQ mmxreg,r/m64 ; 0F D3 /r [PENT,MMX]
PSRLQ mmxreg,imm8 ; 0F 73 /2 ib [PENT,MMX]
PSUBB mmxreg,r/m64 ; 0F F8 /r [PENT,MMX]
PSUBW mmxreg,r/m64 ; 0F F9 /r [PENT,MMX]
PSUBD mmxreg,r/m64 ; 0F FA /r [PENT,MMX]
PSUBSB mmxreg,r/m64 ; 0F E8 /r [PENT,MMX]
PSUBSW mmxreg,r/m64 ; 0F E9 /r [PENT,MMX]
PSUBUSB mmxreg,r/m64 ; 0F D8 /r [PENT,MMX]
PSUBUSW mmxreg,r/m64 ; 0F D9 /r [PENT,MMX]
PSUBSIW mmxreg,r/m64 ; 0F 55 /r [CYRIX,MMX]
PUNPCKHBW mmxreg,r/m64 ; 0F 68 /r [PENT,MMX]
PUNPCKHWD mmxreg,r/m64 ; 0F 69 /r [PENT,MMX]
PUNPCKHDQ mmxreg,r/m64 ; 0F 6A /r [PENT,MMX]
PUNPCKLBW mmxreg,r/m64 ; 0F 60 /r [PENT,MMX]
PUNPCKLWD mmxreg,r/m64 ; 0F 61 /r [PENT,MMX]
PUNPCKLDQ mmxreg,r/m64 ; 0F 62 /r [PENT,MMX]
PUSH reg16 ; o16 50+r [8086]
PUSH reg32 ; o32 50+r [386]
PUSH r/m16 ; o16 FF /6 [8086]
PUSH r/m32 ; o32 FF /6 [386]
PUSH CS ; 0E [8086]
PUSH DS ; 1E [8086]
PUSH ES ; 06 [8086]
PUSH SS ; 16 [8086]
PUSH FS ; 0F A0 [386]
PUSH GS ; 0F A8 [386]
PUSH imm8 ; 6A ib [286]
PUSH imm16 ; o16 68 iw [286]
PUSH imm32 ; o32 68 id [386]
PUSHA ; 60 [186]
PUSHAD ; o32 60 [386]
PUSHAW ; o16 60 [186]
PUSHF ; 9C [186]
PUSHFD ; o32 9C [386]
PUSHFW ; o16 9C [186]
PXOR mmxreg,r/m64 ; 0F EF /r [PENT,MMX]
RCL r/m8,1 ; D0 /2 [8086]
RCL r/m8,CL ; D2 /2 [8086]
RCL r/m8,imm8 ; C0 /2 ib [286]
RCL r/m16,1 ; o16 D1 /2 [8086]
RCL r/m16,CL ; o16 D3 /2 [8086]
RCL r/m16,imm8 ; o16 C1 /2 ib [286]
RCL r/m32,1 ; o32 D1 /2 [386]
RCL r/m32,CL ; o32 D3 /2 [386]
RCL r/m32,imm8 ; o32 C1 /2 ib [386]
RCR r/m8,1 ; D0 /3 [8086]
RCR r/m8,CL ; D2 /3 [8086]
RCR r/m8,imm8 ; C0 /3 ib [286]
RCR r/m16,1 ; o16 D1 /3 [8086]
RCR r/m16,CL ; o16 D3 /3 [8086]
RCR r/m16,imm8 ; o16 C1 /3 ib [286]
RCR r/m32,1 ; o32 D1 /3 [386]
RCR r/m32,CL ; o32 D3 /3 [386]
RCR r/m32,imm8 ; o32 C1 /3 ib [386]
RDMSR ; 0F 32 [PENT]
RDPMC ; 0F 33 [P6]
RDTSC ; 0F 31 [PENT]
RET ; C3 [8086]
RET imm16 ; C2 iw [8086]
RETF ; CB [8086]
RETF imm16 ; CA iw [8086]
RETN ; C3 [8086]
RETN imm16 ; C2 iw [8086]
ROL r/m8,1 ; D0 /0 [8086]
ROL r/m8,CL ; D2 /0 [8086]
ROL r/m8,imm8 ; C0 /0 ib [286]
ROL r/m16,1 ; o16 D1 /0 [8086]
ROL r/m16,CL ; o16 D3 /0 [8086]
ROL r/m16,imm8 ; o16 C1 /0 ib [286]
ROL r/m32,1 ; o32 D1 /0 [386]
ROL r/m32,CL ; o32 D3 /0 [386]
ROL r/m32,imm8 ; o32 C1 /0 ib [386]
ROR r/m8,1 ; D0 /1 [8086]
ROR r/m8,CL ; D2 /1 [8086]
ROR r/m8,imm8 ; C0 /1 ib [286]
ROR r/m16,1 ; o16 D1 /1 [8086]
ROR r/m16,CL ; o16 D3 /1 [8086]
ROR r/m16,imm8 ; o16 C1 /1 ib [286]
ROR r/m32,1 ; o32 D1 /1 [386]
ROR r/m32,CL ; o32 D3 /1 [386]
ROR r/m32,imm8 ; o32 C1 /1 ib [386]
RSM ; 0F AA [PENT]
SAHF ; 9E [8086]
SAL r/m8,1 ; D0 /4 [8086]
SAL r/m8,CL ; D2 /4 [8086]
SAL r/m8,imm8 ; C0 /4 ib [286]
SAL r/m16,1 ; o16 D1 /4 [8086]
SAL r/m16,CL ; o16 D3 /4 [8086]
SAL r/m16,imm8 ; o16 C1 /4 ib [286]
SAL r/m32,1 ; o32 D1 /4 [386]
SAL r/m32,CL ; o32 D3 /4 [386]
SAL r/m32,imm8 ; o32 C1 /4 ib [386]
SAR r/m8,1 ; D0 /0 [8086]
SAR r/m8,CL ; D2 /0 [8086]
SAR r/m8,imm8 ; C0 /0 ib [286]
SAR r/m16,CL ; o16 D3 /0 [8086]
SAR r/m16,imm8 ; o16 C1 /0 ib [286]
SAR r/m32,CL ; o32 D3 /0 [386]
SAR r/m32,imm8 ; o32 C1 /0 ib [386]
SALC ; D6 [8086,UNDOC]
SBB r/m8,reg8 ; 18 /r [8086]
SBB r/m16,reg16 ; o16 19 /r [8086]
SBB r/m32,reg32 ; o32 19 /r [386]
SBB reg8,r/m8 ; 1A /r [8086]
SBB reg16,r/m16 ; o16 1B /r [8086]
SBB reg32,r/m32 ; o32 1B /r [386]
SBB r/m8,imm8 ; 80 /3 ib [8086]
SBB r/m16,imm16 ; o16 81 /3 iw [8086]
SBB r/m32,imm32 ; o32 81 /3 id [386]
SBB r/m16,imm8 ; o16 83 /3 ib [8086]
SBB r/m32,imm8 ; o32 83 /3 ib [8086]
SBB AL,imm8 ; 1C ib [8086]
SBB AX,imm16 ; o16 1D iw [8086]
SBB EAX,imm32 ; o32 1D id [386]
SCASB ; AE [8086]
SCASW ; o16 AF [8086]
SCASD ; o32 AF [386]
SETcc r/m8 ; 0F 90+cc /2 [386]
SGDT mem ; 0F 01 /0 [286,PRIV]
SIDT mem ; 0F 01 /1 [286,PRIV]
SLDT r/m16 ; 0F 00 /0 [286,PRIV]
SHL r/m8,1 ; D0 /4 [8086]
SHL r/m8,CL ; D2 /4 [8086]
SHL r/m8,imm8 ; C0 /4 ib [286]
SHL r/m16,1 ; o16 D1 /4 [8086]
SHL r/m16,CL ; o16 D3 /4 [8086]
SHL r/m16,imm8 ; o16 C1 /4 ib [286]
SHL r/m32,1 ; o32 D1 /4 [386]
SHL r/m32,CL ; o32 D3 /4 [386]
SHL r/m32,imm8 ; o32 C1 /4 ib [386]
SHR r/m8,1 ; D0 /5 [8086]
SHR r/m8,CL ; D2 /5 [8086]
SHR r/m8,imm8 ; C0 /5 ib [286]
SHR r/m16,1 ; o16 D1 /5 [8086]
SHR r/m16,CL ; o16 D3 /5 [8086]
SHR r/m16,imm8 ; o16 C1 /5 ib [286]
SHR r/m32,1 ; o32 D1 /5 [386]
SHR r/m32,CL ; o32 D3 /5 [386]
SHR r/m32,imm8 ; o32 C1 /5 ib [386]
SHLD r/m16,reg16,imm8 ; o16 0F A4 /r ib [386]
SHLD r/m16,reg32,imm8 ; o32 0F A4 /r ib [386]
SHLD r/m16,reg16,CL ; o16 0F A5 /r [386]
SHLD r/m16,reg32,CL ; o32 0F A5 /r [386]
SHRD r/m16,reg16,imm8 ; o16 0F AC /r ib [386]
SHRD r/m32,reg32,imm8 ; o32 0F AC /r ib [386]
SHRD r/m16,reg16,CL ; o16 0F AD /r [386]
SHRD r/m32,reg32,CL ; o32 0F AD /r [386]
SMI ; F1 [386,UNDOC]
SMSW r/m16 ; 0F 01 /4 [286,PRIV]
STC ; F9 [8086]
STD ; FD [8086]
STI ; FB [8086]
STOSB ; AA [8086]
STOSW ; o16 AB [8086]
STOSD ; o32 AB [386]
STR r/m16 ; 0F 00 /1 [286,PRIV]
SUB r/m8,reg8 ; 28 /r [8086]
SUB r/m16,reg16 ; o16 29 /r [8086]
SUB r/m32,reg32 ; o32 29 /r [386]
SUB reg8,r/m8 ; 2A /r [8086]
SUB reg16,r/m16 ; o16 2B /r [8086]
SUB reg32,r/m32 ; o32 2B /r [386]
SUB r/m8,imm8 ; 80 /5 ib [8086]
SUB r/m16,imm16 ; o16 81 /5 iw [8086]
SUB r/m32,imm32 ; o32 81 /5 id [386]
SUB r/m16,imm8 ; o16 83 /5 ib [8086]
SUB r/m32,imm8 ; o32 83 /5 ib [386]
SUB AL,imm8 ; 2C ib [8086]
SUB AX,imm16 ; o16 2D iw [8086]
SUB EAX,imm32 ; o32 2D id [386]
TEST r/m8,reg8 ; 84 /r [8086]
TEST r/m16,reg16 ; o16 85 /r [8086]
TEST r/m32,reg32 ; o32 85 /r [386]
TEST r/m8,imm8 ; F6 /7 ib [8086]
TEST r/m16,imm16 ; o16 F7 /7 iw [8086]
TEST r/m32,imm32 ; o32 F7 /7 id [386]
TEST AL,imm8 ; A8 ib [8086]
TEST AX,imm16 ; o16 A9 iw [8086]
TEST EAX,imm32 ; o32 A9 id [386]
UMOV r/m8,reg8 ; 0F 10 /r [386,UNDOC]
UMOV r/m16,reg16 ; o16 0F 11 /r [386,UNDOC]
UMOV r/m32,reg32 ; o32 0F 11 /r [386,UNDOC]
UMOV reg8,r/m8 ; 0F 12 /r [386,UNDOC]
UMOV reg16,r/m16 ; o16 0F 13 /r [386,UNDOC]
UMOV reg32,r/m32 ; o32 0F 13 /r [386,UNDOC]
VERR r/m16 ; 0F 00 /4 [286,PRIV]
VERW r/m16 ; 0F 00 /5 [286,PRIV]
WAIT ; 9B [8086]
WBINVD ; 0F 09 [486]
WRMSR ; 0F 30 [PENT]
XADD r/m8,reg8 ; 0F C0 /r [486]
XADD r/m16,reg16 ; o16 0F C1 /r [486]
XADD r/m32,reg32 ; o32 0F C1 /r [486]
XBTS reg16,r/m16 ; o16 0F A6 /r [386,UNDOC]
XBTS reg32,r/m32 ; o32 0F A6 /r [386,UNDOC]
XCHG reg8,r/m8 ; 86 /r [8086]
XCHG reg16,r/m8 ; o16 87 /r [8086]
XCHG reg32,r/m32 ; o32 87 /r [386]
XCHG r/m8,reg8 ; 86 /r [8086]
XCHG r/m16,reg16 ; o16 87 /r [8086]
XCHG r/m32,reg32 ; o32 87 /r [386]
XCHG AX,reg16 ; o16 90+r [8086]
XCHG EAX,reg32 ; o32 90+r [386]
XCHG reg16,AX ; o16 90+r [8086]
XCHG reg32,EAX ; o32 90+r [386]
XLATB ; D7 [8086]
XOR r/m8,reg8 ; 30 /r [8086]
XOR r/m16,reg16 ; o16 31 /r [8086]
XOR r/m32,reg32 ; o32 31 /r [386]
XOR reg8,r/m8 ; 32 /r [8086]
XOR reg16,r/m16 ; o16 33 /r [8086]
XOR reg32,r/m32 ; o32 33 /r [386]
XOR r/m8,imm8 ; 80 /6 ib [8086]
XOR r/m16,imm16 ; o16 81 /6 iw [8086]
XOR r/m32,imm32 ; o32 81 /6 id [386]
XOR r/m16,imm8 ; o16 83 /6 ib [8086]
XOR r/m32,imm8 ; o32 83 /6 ib [386]
XOR AL,imm8 ; 34 ib [8086]
XOR AX,imm16 ; o16 35 iw [8086]
XOR EAX,imm32 ; o32 35 id [386]

Test details

Test 1

Group: 1

Verdict: ACCEPTED

input
1

correct output
#

user output
#

Test 2

Group: 2

Verdict: ACCEPTED

input
2

correct output
##
#.

user output
##
#.

Test 3

Group: 3

Verdict: ACCEPTED

input
3

correct output
####
#.#.
##..
#..#

user output
####
#.#.
##..
#..#

Test 4

Group: 4

Verdict: ACCEPTED

input
4

correct output
########
#.#.#.#.
##..##..
#..##..#
####....
...

user output
########
#.#.#.#.
##..##..
#..##..#
####....
...

Test 5

Group: 5

Verdict: ACCEPTED

input
5

correct output
################
#.#.#.#.#.#.#.#.
##..##..##..##..
#..##..##..##..#
####....####....
...

user output
################
#.#.#.#.#.#.#.#.
##..##..##..##..
#..##..##..##..#
####....####....
...

Test 6

Group: 6

Verdict: ACCEPTED

input
6

correct output
##############################...

user output
##############################...

Test 7

Group: 7

Verdict: ACCEPTED

input
7

correct output
##############################...

user output
##############################...

Test 8

Group: 8

Verdict: ACCEPTED

input
8

correct output
##############################...

user output
##############################...

Test 9

Group: 9

Verdict: ACCEPTED

input
9

correct output
##############################...

user output
##############################...

Test 10

Group: 10

Verdict: ACCEPTED

input
10

correct output
##############################...

user output
##############################...