mirror of
https://github.com/bolero-MURAKAMI/Sprout
synced 2025-08-03 12:49:50 +00:00
add examble: perseptron/g3.cpp brainfuck/x86_compile.cpp
This commit is contained in:
parent
5ccbc4e903
commit
03b4eda323
15 changed files with 1411 additions and 8 deletions
45
example/brainfuck/bottles.bf
Normal file
45
example/brainfuck/bottles.bf
Normal file
|
@ -0,0 +1,45 @@
|
|||
// 99 Bottles of Beer
|
||||
">+++++++++[<+++++++++++>-]<[>[-]>[-]<<[>+>+<<-]>>[<<+>>-]>>>"
|
||||
"[-]<<<+++++++++<[>>>+<<[>+>[-]<<-]>[<+>-]>[<<++++++++++>>>+<"
|
||||
"-]<<-<-]+++++++++>[<->-]>>+>[<[-]<<+>>>-]>[-]+<<[>+>-<<-]<<<"
|
||||
"[>>+>+<<<-]>>>[<<<+>>>-]>[<+>-]<<-[>[-]<[-]]>>+<[>[-]<-]<+++"
|
||||
"+++++[<++++++<++++++>>-]>>>[>+>+<<-]>>[<<+>>-]<[<<<<<.>>>>>-"
|
||||
"]<<<<<<.>>[-]>[-]++++[<++++++++>-]<.>++++[<++++++++>-]<++.>+"
|
||||
"++++[<+++++++++>-]<.><+++++..--------.-------.>>[>>+>+<<<-]>"
|
||||
">>[<<<+>>>-]<[<<<<++++++++++++++.>>>>-]<<<<[-]>++++[<+++++++"
|
||||
"+>-]<.>+++++++++[<+++++++++>-]<--.---------.>+++++++[<------"
|
||||
"---->-]<.>++++++[<+++++++++++>-]<.+++..+++++++++++++.>++++++"
|
||||
"++[<---------->-]<--.>+++++++++[<+++++++++>-]<--.-.>++++++++"
|
||||
"[<---------->-]<++.>++++++++[<++++++++++>-]<++++.-----------"
|
||||
"-.---.>+++++++[<---------->-]<+.>++++++++[<+++++++++++>-]<-."
|
||||
">++[<----------->-]<.+++++++++++..>+++++++++[<---------->-]<"
|
||||
"-----.---.>>>[>+>+<<-]>>[<<+>>-]<[<<<<<.>>>>>-]<<<<<<.>>>+++"
|
||||
"+[<++++++>-]<--.>++++[<++++++++>-]<++.>+++++[<+++++++++>-]<."
|
||||
"><+++++..--------.-------.>>[>>+>+<<<-]>>>[<<<+>>>-]<[<<<<++"
|
||||
"++++++++++++.>>>>-]<<<<[-]>++++[<++++++++>-]<.>+++++++++[<++"
|
||||
"+++++++>-]<--.---------.>+++++++[<---------->-]<.>++++++[<++"
|
||||
"+++++++++>-]<.+++..+++++++++++++.>++++++++++[<---------->-]<"
|
||||
"-.---.>+++++++[<++++++++++>-]<++++.+++++++++++++.++++++++++."
|
||||
"------.>+++++++[<---------->-]<+.>++++++++[<++++++++++>-]<-."
|
||||
"-.---------.>+++++++[<---------->-]<+.>+++++++[<++++++++++>-"
|
||||
"]<--.+++++++++++.++++++++.---------.>++++++++[<---------->-]"
|
||||
"<++.>+++++[<+++++++++++++>-]<.+++++++++++++.----------.>++++"
|
||||
"+++[<---------->-]<++.>++++++++[<++++++++++>-]<.>+++[<----->"
|
||||
"-]<.>+++[<++++++>-]<..>+++++++++[<--------->-]<--.>+++++++[<"
|
||||
"++++++++++>-]<+++.+++++++++++.>++++++++[<----------->-]<++++"
|
||||
".>+++++[<+++++++++++++>-]<.>+++[<++++++>-]<-.---.++++++.----"
|
||||
"---.----------.>++++++++[<----------->-]<+.---.[-]<<<->[-]>["
|
||||
"-]<<[>+>+<<-]>>[<<+>>-]>>>[-]<<<+++++++++<[>>>+<<[>+>[-]<<-]"
|
||||
">[<+>-]>[<<++++++++++>>>+<-]<<-<-]+++++++++>[<->-]>>+>[<[-]<"
|
||||
"<+>>>-]>[-]+<<[>+>-<<-]<<<[>>+>+<<<-]>>>[<<<+>>>-]<>>[<+>-]<"
|
||||
"<-[>[-]<[-]]>>+<[>[-]<-]<++++++++[<++++++<++++++>>-]>>>[>+>+"
|
||||
"<<-]>>[<<+>>-]<[<<<<<.>>>>>-]<<<<<<.>>[-]>[-]++++[<++++++++>"
|
||||
"-]<.>++++[<++++++++>-]<++.>+++++[<+++++++++>-]<.><+++++..---"
|
||||
"-----.-------.>>[>>+>+<<<-]>>>[<<<+>>>-]<[<<<<++++++++++++++"
|
||||
".>>>>-]<<<<[-]>++++[<++++++++>-]<.>+++++++++[<+++++++++>-]<-"
|
||||
"-.---------.>+++++++[<---------->-]<.>++++++[<+++++++++++>-]"
|
||||
"<.+++..+++++++++++++.>++++++++[<---------->-]<--.>+++++++++["
|
||||
"<+++++++++>-]<--.-.>++++++++[<---------->-]<++.>++++++++[<++"
|
||||
"++++++++>-]<++++.------------.---.>+++++++[<---------->-]<+."
|
||||
">++++++++[<+++++++++++>-]<-.>++[<----------->-]<.+++++++++++"
|
||||
"..>+++++++++[<---------->-]<-----.---.+++.---.[-]<<<]"
|
2
example/brainfuck/echo.bf
Normal file
2
example/brainfuck/echo.bf
Normal file
|
@ -0,0 +1,2 @@
|
|||
// echo
|
||||
"+[>,.<]"
|
6
example/brainfuck/fizzBuzz.bf
Normal file
6
example/brainfuck/fizzBuzz.bf
Normal file
|
@ -0,0 +1,6 @@
|
|||
// FizzBuzz
|
||||
"++++++++++++[->++++++>+++++++++>+++++>++++++++++>++++++++++>+++>>>>>>++++++++<<<<<<<<<<<<]>-->--->++"
|
||||
"++++>--->++>---->>>>+++>+++++>++++[>>>+[-<<[->>+>+<<<]>>>[-<<<+>>>]+<[[-]>-<<[->+>+<<]>>[-<<+>>]+<[["
|
||||
"-]>-<<<+>->]>[-<<<--------->+++++++++>>>>>+<<<]<]>[-<+++++++[<<+++++++>>-]<++++++++>>]>>>]<<<<<<[<<<"
|
||||
"<]>-[-<<+>+>]<[->+<]+<[[-]>-<]>[->+++<<<<<<<<<.>.>>>..>>+>>]>>-[-<<<+>+>>]<<[->>+<<]+<[[-]>-<]>[->>+"
|
||||
"++++<<<<<<<<.>.>..>>+>>]<+<[[-]>-<]>[->>>>>[>>>>]<<<<[.<<<<]<]<<.>>>>>>-]"
|
3
example/brainfuck/hello.bf
Normal file
3
example/brainfuck/hello.bf
Normal file
|
@ -0,0 +1,3 @@
|
|||
// Hello, world!
|
||||
"+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-."
|
||||
"------------.<++++++++.--------.+++.------.--------.>+."
|
11
example/brainfuck/quine.bf
Normal file
11
example/brainfuck/quine.bf
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Quine
|
||||
"-"
|
||||
">++>+++>+>+>+++>>>>>>>>>>>>>>>>>>>>>>+>+>++>+++>++>>+++"
|
||||
">+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>+>>+++>>>>+++>>>+++"
|
||||
">+>>>>>>>++>+++>+++>+>>+++>+++>+>+++>+>+++>+>++>+++>>>+"
|
||||
">+>+>+>++>+++>+>+>>+++>>>>>>>+>+>>>+>+>++>+++>+++>+>>+++"
|
||||
">+++>+>+++>+>++>+++>++>>+>+>++>+++>+>+>>+++>>>+++>+>>>++"
|
||||
">+++>+++>+>>+++>>>+++>+>+++>+>>+++>>+++>>"
|
||||
"+[[>>+[>]+>+[<]<-]>>[>]<+<+++[<]<<+]"
|
||||
">>>[>]+++>+"
|
||||
"[+[<++++++++++++++++>-]<++++++++++.<]"
|
2
example/brainfuck/self.bf
Normal file
2
example/brainfuck/self.bf
Normal file
|
@ -0,0 +1,2 @@
|
|||
// Self-describing
|
||||
"+++++[>+++++++++<-],[[>--.++>+<<-]>+.->[<.>-]<<,]"
|
578
example/brainfuck/x86_compile.cpp
Normal file
578
example/brainfuck/x86_compile.cpp
Normal file
|
@ -0,0 +1,578 @@
|
|||
/*=============================================================================
|
||||
Copyright (c) 2011-2014 Bolero MURAKAMI
|
||||
https://github.com/bolero-MURAKAMI/Sprout
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/endian_traits.hpp>
|
||||
#include <sprout/string.hpp>
|
||||
#include <sprout/array.hpp>
|
||||
#include <sprout/sub_array.hpp>
|
||||
#include <sprout/container/functions.hpp>
|
||||
#include <sprout/range/algorithm.hpp>
|
||||
#include <sprout/preprocessor/stringize.hpp>
|
||||
#include <sprout/assert.hpp>
|
||||
|
||||
|
||||
//
|
||||
// PE関連の構造体
|
||||
// <windows.h> からコピペ
|
||||
//
|
||||
typedef unsigned long DWORD;
|
||||
typedef int BOOL;
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short WORD;
|
||||
|
||||
|
||||
//
|
||||
// File header format.
|
||||
//
|
||||
|
||||
typedef struct _IMAGE_FILE_HEADER {
|
||||
WORD Machine;
|
||||
WORD NumberOfSections;
|
||||
DWORD TimeDateStamp;
|
||||
DWORD PointerToSymbolTable;
|
||||
DWORD NumberOfSymbols;
|
||||
WORD SizeOfOptionalHeader;
|
||||
WORD Characteristics;
|
||||
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
|
||||
|
||||
|
||||
//
|
||||
// Directory format.
|
||||
//
|
||||
|
||||
typedef struct _IMAGE_DATA_DIRECTORY {
|
||||
DWORD VirtualAddress;
|
||||
DWORD Size;
|
||||
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
|
||||
|
||||
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
|
||||
|
||||
//
|
||||
// Optional header format.
|
||||
//
|
||||
|
||||
typedef struct _IMAGE_OPTIONAL_HEADER {
|
||||
//
|
||||
// Standard fields.
|
||||
//
|
||||
|
||||
WORD Magic;
|
||||
BYTE MajorLinkerVersion;
|
||||
BYTE MinorLinkerVersion;
|
||||
DWORD SizeOfCode;
|
||||
DWORD SizeOfInitializedData;
|
||||
DWORD SizeOfUninitializedData;
|
||||
DWORD AddressOfEntryPoint;
|
||||
DWORD BaseOfCode;
|
||||
DWORD BaseOfData;
|
||||
|
||||
//
|
||||
// NT additional fields.
|
||||
//
|
||||
|
||||
DWORD ImageBase;
|
||||
DWORD SectionAlignment;
|
||||
DWORD FileAlignment;
|
||||
WORD MajorOperatingSystemVersion;
|
||||
WORD MinorOperatingSystemVersion;
|
||||
WORD MajorImageVersion;
|
||||
WORD MinorImageVersion;
|
||||
WORD MajorSubsystemVersion;
|
||||
WORD MinorSubsystemVersion;
|
||||
DWORD Win32VersionValue;
|
||||
DWORD SizeOfImage;
|
||||
DWORD SizeOfHeaders;
|
||||
DWORD CheckSum;
|
||||
WORD Subsystem;
|
||||
WORD DllCharacteristics;
|
||||
DWORD SizeOfStackReserve;
|
||||
DWORD SizeOfStackCommit;
|
||||
DWORD SizeOfHeapReserve;
|
||||
DWORD SizeOfHeapCommit;
|
||||
DWORD LoaderFlags;
|
||||
DWORD NumberOfRvaAndSizes;
|
||||
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
|
||||
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
|
||||
|
||||
|
||||
//
|
||||
// Section header format.
|
||||
//
|
||||
|
||||
#define IMAGE_SIZEOF_SHORT_NAME 8
|
||||
|
||||
typedef struct _IMAGE_SECTION_HEADER {
|
||||
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
|
||||
// union {
|
||||
// DWORD PhysicalAddress;
|
||||
// DWORD VirtualSize;
|
||||
// } Misc;
|
||||
struct {
|
||||
DWORD VirtualSize;
|
||||
} Misc;
|
||||
DWORD VirtualAddress;
|
||||
DWORD SizeOfRawData;
|
||||
DWORD PointerToRawData;
|
||||
DWORD PointerToRelocations;
|
||||
DWORD PointerToLinenumbers;
|
||||
WORD NumberOfRelocations;
|
||||
WORD NumberOfLinenumbers;
|
||||
DWORD Characteristics;
|
||||
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
|
||||
|
||||
|
||||
//
|
||||
// 出力バイナリサイズ
|
||||
//
|
||||
#ifndef BRAINFUCK_BINARY_SIZE
|
||||
# define BRAINFUCK_BINARY_SIZE (16 * 1024)
|
||||
#endif
|
||||
|
||||
//
|
||||
// ループ制限
|
||||
//
|
||||
#ifndef BRAINFUCK_LOOP_LIMIT
|
||||
# define BRAINFUCK_LOOP_LIMIT 256
|
||||
#endif
|
||||
|
||||
//
|
||||
// 入力ファイル名
|
||||
//
|
||||
#ifndef BRAINFUCK_SOURCE_FILE
|
||||
# define BRAINFUCK_SOURCE_FILE a.bf
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// 定数
|
||||
//
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t bin_size = BRAINFUCK_BINARY_SIZE;
|
||||
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t loop_limit = BRAINFUCK_LOOP_LIMIT;
|
||||
|
||||
SPROUT_STATIC_CONSTEXPR auto source = sprout::to_string(
|
||||
# include SPROUT_PP_STRINGIZE(BRAINFUCK_SOURCE_FILE)
|
||||
);
|
||||
|
||||
SPROUT_STATIC_CONSTEXPR std::int32_t addr_putchar = 0x00405044;
|
||||
SPROUT_STATIC_CONSTEXPR std::int32_t addr_getchar = addr_putchar + 4;
|
||||
SPROUT_STATIC_CONSTEXPR std::int32_t addr_buf = 0x00406000;
|
||||
|
||||
|
||||
//
|
||||
// 出力用関数
|
||||
//
|
||||
template<typename OutputIterator, typename T>
|
||||
SPROUT_CXX14_CONSTEXPR std::size_t
|
||||
write_bytes(OutputIterator& out, T const& val) {
|
||||
typedef sprout::little_endian_traits<T> traits;
|
||||
for (std::size_t i = 0; i != traits::size(); ++i) {
|
||||
*out++ = sprout::little_endian_traits<T>::get_byte(val, i);
|
||||
}
|
||||
return traits::size();
|
||||
}
|
||||
template<typename OutputIterator, typename T, std::size_t N>
|
||||
SPROUT_CXX14_CONSTEXPR std::size_t
|
||||
write_bytes(OutputIterator& out, T const(& vals)[N]) {
|
||||
typedef sprout::little_endian_traits<T> traits;
|
||||
for (std::size_t i = 0; i != N; ++i) {
|
||||
::write_bytes(out, vals[i]);
|
||||
}
|
||||
return traits::size() * N;
|
||||
}
|
||||
template<typename OutputIterator, typename Head, typename... Tail>
|
||||
SPROUT_CXX14_CONSTEXPR std::size_t
|
||||
write_bytes(OutputIterator& out, Head const& head, Tail const&... tail) {
|
||||
return ::write_bytes(out, head) + ::write_bytes(out, tail...);
|
||||
}
|
||||
|
||||
template<typename OutputIterator>
|
||||
SPROUT_CXX14_CONSTEXPR std::size_t
|
||||
write_pe_header(OutputIterator& out, std::size_t n = 0) {
|
||||
SPROUT_CONSTEXPR unsigned char stub[] = {
|
||||
// 00-3b: DOS Header
|
||||
'M', 'Z', 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x00,
|
||||
0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 3c-3f: Pointer to PE Header (=80)
|
||||
0x80, 0x00, 0x00, 0x00,
|
||||
// 40-7f: DOS Stub
|
||||
0xba, 0x10, 0x00, 0x0e, 0x1f, 0xb4, 0x09, 0xcd, 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x90, 0x90,
|
||||
'T', 'h', 'i', 's', ' ', 'p', 'r', 'o', 'g', 'r', 'a', 'm', ' ', 'c', 'a', 'n',
|
||||
'n', 'o', 't', ' ', 'b', 'e', ' ', 'r', 'u', 'n', ' ', 'i', 'n', ' ', 'D', 'O',
|
||||
'S', ' ', 'm', 'o', 'd', 'e', '.', '\r', '\n', '$', 0, 0, 0, 0, 0, 0,
|
||||
// 80-83: PE Signature
|
||||
'P', 'E', 0, 0
|
||||
};
|
||||
n += ::write_bytes(
|
||||
out,
|
||||
stub
|
||||
);
|
||||
|
||||
SPROUT_CONSTEXPR ::IMAGE_FILE_HEADER coff = {
|
||||
0x014c, // Machine
|
||||
3, // NumberOfSections
|
||||
0, // TimeDateStamp
|
||||
0, // PointerToSymbolTable
|
||||
0, // NumberOfSymbols
|
||||
sizeof(::IMAGE_OPTIONAL_HEADER32), // SizeOfOptionalHeader
|
||||
0x030f // Characteristics
|
||||
};
|
||||
n += ::write_bytes(
|
||||
out,
|
||||
coff.Machine,
|
||||
coff.NumberOfSections,
|
||||
coff.TimeDateStamp,
|
||||
coff.PointerToSymbolTable,
|
||||
coff.NumberOfSymbols,
|
||||
coff.SizeOfOptionalHeader,
|
||||
coff.Characteristics
|
||||
);
|
||||
|
||||
SPROUT_CONSTEXPR ::IMAGE_OPTIONAL_HEADER32 opt = {
|
||||
0x010b, // Magic
|
||||
6, 0, // MajorLinkerVersion, MinorLinkerVersion
|
||||
::bin_size, // SizeOfCode
|
||||
0, // SizeOfInitializedData
|
||||
65536, // SizeOfUninitializedData
|
||||
0x1000, // AddressOfEntryPoint
|
||||
0x1000, // BaseOfCode
|
||||
0x6000, // BaseOfData
|
||||
0x00400000, // ImageBase
|
||||
0x1000, // SectionAlignment
|
||||
0x0200, // FileAlignment
|
||||
4, 0, // MajorOperatingSystemVersion, MinorOperatingSystemVersion
|
||||
0, 0, // MajorImageVersion, MinorImageVersion
|
||||
4, 0, // MajorSubsystemVersion, MinorSubsystemVersion
|
||||
0, // Win32VersionValue
|
||||
0x16000, // SizeOfImage
|
||||
0x200, // SizeOfHeaders
|
||||
0, // CheckSum
|
||||
3, // Subsystem
|
||||
0, // DllCharacteristics
|
||||
1024 * 1024, // SizeOfStackReserve
|
||||
8 * 1024, // SizeOfStackCommit
|
||||
1024 * 1024, // SizeOfHeapReserve
|
||||
4 * 1024, // SizeOfHeapCommit
|
||||
0, // LoaderFlags
|
||||
16, // NumberOfRvaAndSizes
|
||||
{
|
||||
{},
|
||||
{
|
||||
0x5000, // VirtualAddress (import table)
|
||||
100 // Size
|
||||
},
|
||||
{}
|
||||
}
|
||||
};
|
||||
n += ::write_bytes(
|
||||
out,
|
||||
opt.Magic,
|
||||
opt.MajorLinkerVersion, opt.MinorLinkerVersion,
|
||||
opt.SizeOfCode,
|
||||
opt.SizeOfInitializedData,
|
||||
opt.SizeOfUninitializedData,
|
||||
opt.AddressOfEntryPoint,
|
||||
opt.BaseOfCode,
|
||||
opt.BaseOfData,
|
||||
opt.ImageBase,
|
||||
opt.SectionAlignment,
|
||||
opt.FileAlignment,
|
||||
opt.MajorOperatingSystemVersion, opt.MinorOperatingSystemVersion,
|
||||
opt.MajorImageVersion, opt.MinorImageVersion,
|
||||
opt.MajorSubsystemVersion, opt.MinorSubsystemVersion,
|
||||
opt.Win32VersionValue,
|
||||
opt.SizeOfImage,
|
||||
opt.SizeOfHeaders,
|
||||
opt.CheckSum,
|
||||
opt.Subsystem,
|
||||
opt.DllCharacteristics,
|
||||
opt.SizeOfStackReserve,
|
||||
opt.SizeOfStackCommit,
|
||||
opt.SizeOfHeapReserve,
|
||||
opt.SizeOfHeapCommit,
|
||||
opt.LoaderFlags,
|
||||
opt.NumberOfRvaAndSizes,
|
||||
opt.DataDirectory[0].VirtualAddress, opt.DataDirectory[0].Size,
|
||||
opt.DataDirectory[1].VirtualAddress, opt.DataDirectory[1].Size
|
||||
);
|
||||
for (std::size_t i = 2; i != IMAGE_NUMBEROF_DIRECTORY_ENTRIES; ++i) {
|
||||
n += ::write_bytes(
|
||||
out,
|
||||
opt.DataDirectory[i].VirtualAddress, opt.DataDirectory[i].Size
|
||||
);
|
||||
}
|
||||
|
||||
SPROUT_CONSTEXPR ::IMAGE_SECTION_HEADER sects[3] = {
|
||||
{
|
||||
".text", // Name
|
||||
{::bin_size}, // Misc.VirtualSize
|
||||
0x1000, // VirtualAddress
|
||||
::bin_size, // SizeOfRawData
|
||||
0x400, // PointerToRawData
|
||||
0, // PointerToRelocations
|
||||
0, // PointerToLinenumbers
|
||||
0, // NumberOfRelocations
|
||||
0, // NumberOfLinenumbers
|
||||
0x60500060 // Characteristics
|
||||
},
|
||||
{
|
||||
".idata", // Name
|
||||
{100}, // Misc.VirtualSize
|
||||
0x5000, // VirtualAddress
|
||||
512, // SizeOfRawData
|
||||
0x200, // PointerToRawData
|
||||
0, // PointerToRelocations
|
||||
0, // PointerToLinenumbers
|
||||
0, // NumberOfRelocations
|
||||
0, // NumberOfLinenumbers
|
||||
0xc0300040 // Characteristics
|
||||
},
|
||||
{
|
||||
".bss", // Name
|
||||
{65536}, // Misc.VirtualSize
|
||||
0x6000, // VirtualAddress
|
||||
0, // SizeOfRawData
|
||||
0, // PointerToRawData
|
||||
0, // PointerToRelocations
|
||||
0, // PointerToLinenumbers
|
||||
0, // NumberOfRelocations
|
||||
0, // NumberOfLinenumbers
|
||||
0xc0400080 // Characteristics
|
||||
}
|
||||
};
|
||||
for (std::size_t i = 0; i != 3; ++i) {
|
||||
n += ::write_bytes(
|
||||
out,
|
||||
sects[i].Name,
|
||||
sects[i].Misc.VirtualSize,
|
||||
sects[i].VirtualAddress,
|
||||
sects[i].SizeOfRawData,
|
||||
sects[i].PointerToRawData,
|
||||
sects[i].PointerToRelocations,
|
||||
sects[i].PointerToLinenumbers,
|
||||
sects[i].NumberOfRelocations,
|
||||
sects[i].NumberOfLinenumbers,
|
||||
sects[i].Characteristics
|
||||
);
|
||||
}
|
||||
|
||||
for (; n != 0x200; ) {
|
||||
n += ::write_bytes(
|
||||
out,
|
||||
(unsigned char)0
|
||||
);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
template<typename OutputIterator>
|
||||
SPROUT_CXX14_CONSTEXPR std::size_t
|
||||
write_idata(OutputIterator& out, std::size_t n = 0) {
|
||||
SPROUT_CONSTEXPR int idt[] = {
|
||||
// IDT 1
|
||||
0x5028, 0, 0, 0x5034, 0x5044,
|
||||
// IDT (終端)
|
||||
0, 0, 0, 0, 0
|
||||
};
|
||||
n += ::write_bytes(
|
||||
out,
|
||||
idt
|
||||
);
|
||||
|
||||
SPROUT_CONSTEXPR int ilt_iat[] = {
|
||||
0x5050, 0x505a, 0
|
||||
};
|
||||
|
||||
// ILT
|
||||
n += ::write_bytes(
|
||||
out,
|
||||
ilt_iat
|
||||
);
|
||||
n += ::write_bytes(
|
||||
out,
|
||||
"msvcrt.dll\0\0\0\0\0"
|
||||
);
|
||||
|
||||
// IAT
|
||||
n += ::write_bytes(
|
||||
out,
|
||||
ilt_iat
|
||||
);
|
||||
n += ::write_bytes(
|
||||
out,
|
||||
(std::int16_t)0,
|
||||
"putchar",
|
||||
(std::int16_t)0,
|
||||
"getchar"
|
||||
);
|
||||
|
||||
for (; n != 0x400; ) {
|
||||
n += ::write_bytes(
|
||||
out,
|
||||
(unsigned char)0
|
||||
);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
//
|
||||
// コンパイル
|
||||
//
|
||||
template<std::size_t LoopLimit = 256, typename InputIterator, typename RandomAccessIterator>
|
||||
SPROUT_CXX14_CONSTEXPR std::size_t
|
||||
compile(InputIterator first, InputIterator last, RandomAccessIterator& out_first) {
|
||||
sprout::array<int, LoopLimit> loops {{}}; // ループを保存するスタック
|
||||
auto loop_first = sprout::begin(loops);
|
||||
auto loop_last = sprout::end(loops);
|
||||
auto loop = loop_first;
|
||||
|
||||
int idx = 0;
|
||||
auto out = out_first;
|
||||
|
||||
idx += ::write_bytes(
|
||||
out,
|
||||
(unsigned char)0x31, (unsigned char)0xc9, // xor ecx, ecx
|
||||
(unsigned char)0x57, // push edi
|
||||
(unsigned char)0xbf, ::addr_buf // mov edi, addr_buf
|
||||
);
|
||||
|
||||
for (; first != last; ++first) {
|
||||
switch (*first) {
|
||||
case '>':
|
||||
idx += ::write_bytes(
|
||||
out,
|
||||
(unsigned char)0x66, (unsigned char)0x41 // inc cx
|
||||
);
|
||||
break;
|
||||
case '<':
|
||||
idx += ::write_bytes(
|
||||
out,
|
||||
(unsigned char)0x66, (unsigned char)0x49 // dec cx
|
||||
);
|
||||
break;
|
||||
case '+':
|
||||
idx += ::write_bytes(
|
||||
out,
|
||||
(unsigned char)0xfe, (unsigned char)0x04, (unsigned char)0x0f // inc byte [edi+ecx]
|
||||
);
|
||||
break;
|
||||
case '-':
|
||||
idx += ::write_bytes(
|
||||
out,
|
||||
(unsigned char)0xfe, (unsigned char)0x0c, (unsigned char)0x0f // dec byte [edi+ecx]
|
||||
);
|
||||
break;
|
||||
case '.':
|
||||
idx += ::write_bytes(
|
||||
out,
|
||||
(unsigned char)0x51, // push ecx
|
||||
(unsigned char)0x0f, (unsigned char)0xb6, (unsigned char)0x04, (unsigned char)0x0f, // movzx eax,byte [edi+ecx]
|
||||
(unsigned char)0x50, // push eax
|
||||
(unsigned char)0xa1, ::addr_putchar, // mov eax, [addr_putchar]
|
||||
(unsigned char)0xff, (unsigned char)0xd0, // call eax
|
||||
(unsigned char)0x58, // pop eax
|
||||
(unsigned char)0x59 // pop ecx
|
||||
);
|
||||
break;
|
||||
case ',':
|
||||
idx += ::write_bytes(
|
||||
out,
|
||||
(unsigned char)0x51, // push ecx
|
||||
(unsigned char)0xa1, ::addr_getchar, // mov eax, [addr_getchar]
|
||||
(unsigned char)0xff, (unsigned char)0xd0, // call eax
|
||||
(unsigned char)0x59, // pop ecx
|
||||
(unsigned char)0x88, (unsigned char)0x04, (unsigned char)0x0f // mov [edi+ecx],al
|
||||
);
|
||||
break;
|
||||
case '[':
|
||||
SPROUT_ASSERT_MSG(loop != loop_last, "loop overflow");
|
||||
*loop++ = idx; // インデックスをスタックに積む
|
||||
idx += ::write_bytes(
|
||||
out,
|
||||
(unsigned char)0x80, (unsigned char)0x3c, (unsigned char)0x0f, (unsigned char)0x00, // cmp byte [edi+ecx],0
|
||||
(unsigned char)0x0f, (unsigned char)0x84, // jz 対応する]の直後
|
||||
(unsigned char)0xde, (unsigned char)0xad, (unsigned char)0xbe, (unsigned char)0xef // (アドレスは後で決定)
|
||||
);
|
||||
break;
|
||||
case ']':
|
||||
{
|
||||
SPROUT_ASSERT_MSG(loop != loop_first, "missing '['");
|
||||
int idx_loop = *--loop;
|
||||
idx += ::write_bytes(
|
||||
out,
|
||||
(unsigned char)0xe9, (std::int32_t)(idx_loop - (idx + 5)) // jmp idx_loop
|
||||
);
|
||||
auto out_loop = out_first + (idx_loop + 6);
|
||||
::write_bytes(
|
||||
out_loop,
|
||||
(std::int32_t)(idx - (idx_loop + 10)) // (アドレス)
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
SPROUT_ASSERT_MSG(idx <= (int)::bin_size - 32, "buffer overflow");
|
||||
}
|
||||
|
||||
SPROUT_ASSERT_MSG(loop == loop_first, "missing ']'");
|
||||
|
||||
// 終了処理
|
||||
idx += ::write_bytes(
|
||||
out,
|
||||
(unsigned char)0x5f, // pop edi
|
||||
(unsigned char)0x31, (unsigned char)0xc0, // xor eax, eax
|
||||
(unsigned char)0xc3 // ret
|
||||
);
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
//
|
||||
// ビルド
|
||||
//
|
||||
template<std::size_t LoopLimit = 256, typename InputIterator, typename RandomAccessIterator>
|
||||
SPROUT_CXX14_CONSTEXPR std::size_t
|
||||
build(InputIterator first, InputIterator last, RandomAccessIterator& out) {
|
||||
std::size_t n = 0;
|
||||
n += ::write_pe_header(out, n); // ヘッダ出力
|
||||
n += ::write_idata(out, n); // .idataセクション出力
|
||||
n += ::compile<LoopLimit>(first, last, out); // コンパイル
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
SPROUT_CXX14_CONSTEXPR sprout::sub_array<sprout::array<unsigned char, ::bin_size> >
|
||||
build_brainfuck() {
|
||||
sprout::array<unsigned char, ::bin_size> bin{{}};
|
||||
auto out = sprout::begin(bin);
|
||||
auto n = ::build<::loop_limit>(sprout::begin(::source), sprout::end(::source), out);
|
||||
return sprout::sub_copy(bin, 0, n);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
SPROUT_CXX14_CONSTEXPR auto bin = ::build_brainfuck();
|
||||
|
||||
char const* filename = argc >= 2 ? argv[1]
|
||||
: "a.exe"
|
||||
;
|
||||
std::ofstream ofs(filename);
|
||||
if (!ofs) {
|
||||
std::cout
|
||||
<< "could not open file" << std::endl
|
||||
;
|
||||
return -1;
|
||||
}
|
||||
sprout::range::copy(bin, std::ostreambuf_iterator<char>(ofs));
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue