Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

C++でHello worldを書いてみた

歌舞伎座.tech#8「C++初心者会」LT

  • Login to see the comments

C++でHello worldを書いてみた

  1. 1. C++ で Hello world を書いてみた 2015/5/17 hotpepsi
  2. 2. 自己紹介  twitter: @hotpepsi  趣味 : 競技プログラミング、 テニス、ピアノ  キャッチフレーズ : bootstrap から Bootstrap まで
  3. 3. デモ  Ubuntu 14.04 x86-64 $ make -f hello_gen.mk g++ -fno-operator-names -o hello_gen_gen hello_gen_gen.cc ./hello_gen_gen > numbers.cc g++ -o hello_gen hello_gen.cc ./hello_gen > _.c cc -c -Wa,-R -w _.c ld _.o -e _ -o hello ./hello Hello, world!
  4. 4. ソースコードの先頭部分 _[]={ '('-'!'|((','-' ')<<('$'-' '))| (('$'-' '|(('$'-' ')<<('$'-' ')))<<('('-' '))| (('$'-' '|(('#'-'!')<<('$'-' '))| ((('/'-' ')<<('$'-' '))<<('('-' ')))<<('='-'-')), ...
  5. 5. 記号プログラミング ( 二番煎じ )
  6. 6. C で記号プログラミング ( 復習 )  記号のみでソースコードを記述  int 型の配列 _ を定義して、 text セグメントに 配置してプログラムとして実行する  エントリポイントを _start ではなく _ にする ことでアルファベット (main) を書くことを回 避  というような記号だけのソースコードを生成 するジェネレータを (C で ) 書いた
  7. 7.  強化点のご紹介 logo generator: http://www.schoolidolproject.com/
  8. 8. 強化点 1  2010: C  2015: C++ ← New!
  9. 9. マクロがテンプレートに  2010: マクロ  MAKE32(_4,_8,_6,_5,_6,_C,_6,_C), // Hell  2015: テンプレート  Symbolizer<‘H’>().s // H マクロは地獄
  10. 10. struct Symbolizer  Symbolizer<0>().s -> !””  文字列 ( ポインタ ) の否定はゼロ  Symbolizer<1>().s -> !!””  ゼロの否定は 1  Symbolizer<n>().s -> Symbolizer<(n & 1)>().s | (Symbolizer<(n>>1)>().s << 1)
  11. 11. テンプレートの優位性  マクロ :  0 から 16 までの値を用意する必要があった  テンプレート :  特殊化により、最低限 0, 1, n を用意すれば 、任意の数値が生成できる  例 : コンパイラにフィボナッチ数を計算させる  0 の部分を生成しないようにしたり、 2, 3, 4, ... と個別に用意すれば、コードがコンパ クトに
  12. 12. 強化点 2  2010: バイナリ (0xB8, 0x04, ...)  2015: ニーモニック (mov ...)
  13. 13. C++ でバイナリ生成といえば ...  Xbyak  ニーモニックによる記述が可能に  可読性と保守性の大幅な向上  2010:  MAKE32(_B,_8,_0,_4,_0,_0,_0,_0)  2015:  mov(eax, 4);
  14. 14. コード生成のステップ 1. コードジェネレータジェネレータ (C++)  Xbyak でバイナリ生成  バイナリを Symbolizer の呼び出しに置換 して出力 2. コードジェネレータ (C++)  Symbolizer により記号化して出力 3. 記号だけのソースコード (C)
  15. 15. 強化点 3  2010: x86  2015: x86 + x86-64
  16. 16. x86-64 対応 (1)  32bit/64bit の両方に対応したい が、 #ifdef は減らしたい ↓  同じバイト列を生成するようにする
  17. 17. x86-64 対応 (2)  x86 と x86-64 の命令バイト列はほぼ共 通  64bit の即値代入命令を使い、後半 32bit に jmp 命令を埋め込むこと で、 32bit モードの時だけ分岐する  これにより同じバイト列で両方に対応  デュアルアーキテクチャ  x86 と x64 の両方で動くシェルコードを書いてみる http://inaz2.hatenablog.com/entry/2014/07/06/185125
  18. 18. objdump: x86 $ objdump -d hello hello: file format elf32-i386 Disassembly of section .text: 08048080 <_>: 8048080: c7 44 24 f0 48 65 6c 6c c7 44 24 f4 6f 2c 20 77 .D$.Hell.D$.o, w 8048090: c7 44 24 f8 6f 72 6c 64 66 c7 44 24 fc 21 0a ba .D$.orldf.D$.!.. 80480a0: 0e 00 00 00 48 bb 01 00 00 00 eb 19 00 00 48 8d ....H.........H. 80480b0: 74 24 f0 bf 01 00 00 00 89 f8 0f 05 31 ff b8 3c t$..........1..< 80480c0: 00 00 00 0f 05 8d 4c 24 f0 b8 04 00 00 00 cd 80 ......L$........ 80480d0: 31 db b8 01 00 00 00 cd 80 00 00 00 1...........
  19. 19. objdump: x86-64 $ objdump -d hello hello: file format elf64-x86-64 Disassembly of section .text: 08048080 <_>: 8048080: c7 44 24 f0 48 65 6c 6c c7 44 24 f4 6f 2c 20 77 .D$.Hell.D$.o, w 8048090: c7 44 24 f8 6f 72 6c 64 66 c7 44 24 fc 21 0a ba .D$.orldf.D$.!.. 80480a0: 0e 00 00 00 48 bb 01 00 00 00 eb 19 00 00 48 8d ....H.........H. 80480b0: 74 24 f0 bf 01 00 00 00 89 f8 0f 05 31 ff b8 3c t$..........1..< 80480c0: 00 00 00 0f 05 8d 4c 24 f0 b8 04 00 00 00 cd 80 ......L$........ 80480d0: 31 db b8 01 00 00 00 cd 80 00 00 00 1...........
  20. 20. 完全に一致 ファイルフォーマット以外は完全に 一致
  21. 21. コードジェネレータジェネレータ Put St r i ng( const st d: : st r i ng &message) { unsi gned i nt * dat a = ( unsi gned i nt * ) message. dat a( ) ; mov( dwor d[ esp - 16] , dat a[ 0] ) ; mov( dwor d[ esp - 12] , dat a[ 1] ) ; mov( dwor d[ esp - 8] , dat a[ 2] ) ; mov( wor d[ esp - 4] , dat a[ 3] ) ; mov( edx, message. l engt h( ) ) ; dec( eax) ; mov( ebx, 1) ; j mp( " @f " ) ; add( byt e[ eax] , al ) ; dec( eax) ; l ea( esi , pt r [ esp - 16] ) ; mov( edi , 1) ; mov( eax, edi ) ; syscal l ( ) ; xor ( edi , edi ) ; mov( eax, 60) ; syscal l ( ) ; L( " @@" ) ; l ea( ecx, pt r [ esp - 16] ) ; mov( eax, 4) ; i nt 80h( ) ; xor ( ebx, ebx) ; mov( eax, 1) ; i nt 80h( ) ; } スタック上にメッセージを 置く (x86/x86-64 共通 ) x86-64 用コード x86 用コード https://github.com/firewood/test/blob/master/hello_gen_gen.cc
  22. 22. ソースコード _[]={ '('-'!'|((','-' ')<<('$'-' '))| (('$'-' '|(('$'-' ')<<('$'-' ')))<<('('-' '))| (('$'-' '|(('#'-'!')<<('$'-' '))| ((('/'-' ')<<('$'-' '))<<('('-' ')))<<('='-'-')), ... F0 24 C7 44 mov dword ptr[esp-16], imm

×