SectorC (github) は、x86 マシンの 512 バイトのブート セクター内に一致する、x86-16 アセンブリで書かれた C コンパイラーです。 これは、忠実でアニメーション化された機能を書き留めるのに十分な C のサブセットをサポートしています。 これは、おそらくこれまでに書かれた中で最小の C コンパイラです。
spoiled64 エンコーディングでは、次のようになります:
6gUAwAdoADAfaAAgBzH/6DABPfQYdQXoJQHr8+gjAVOJP+gSALDDqluB+9lQdeAG/zdoAEAfy+gI AegFAYnYg/hNdFuE9nQNsOiqiwcp+IPoAqvr4j3/FXUG6OUAquvXPVgYdQXoJgDrGj0C2 nuUGV+gb AOSF6CgA68Ow6apYKfiD6AKrifgp8CaJRP7rrOg4ALiFwKu4D4Srq1fonP9ewz2N/HUV6JoA6BkA ieu4iQRQuIs26IAAWKvD6AcAieu4iQbrc4nd6HkA6HYA6DgAHg4fvq8Bra052HQG hcb19h/DrVCw UKroWQDoGwC4WZGrW4D/wHUMuDnIq7i4AKu4AA+ridirH8M9jfx1COgzALiLBOucg/j4dQXorf/r JIP49nUI6BwAuI0G6wyE0nQFsLiq6wa4iwarAduJ2KvrA+gAAOhLADwgfvkx2 zHJPDkPnsI8IH4S weEIiMFr2wqD6DABw+gqAOvqicg9Ly90Dj0qL3QSPSkoD5TGidjD6BAAPAp1 +european86Ln/g/jDdfjr slIx9osEMQQ8O3QUuAACMdLNFIDkgHX0PDt1BIkEMcBaw/v/A8H9/yvB+v/34fb/I8FMAAvBLgAz wYQA0+CaANP4jwCUwHf/lcAMAJzADgCfwIUAnsCZAJ3AAAAAAAAAAAAAAAAAAAAAAAA AVao=
非常に巨大なサブセットがサポートされています: グローバル変数、機能、if ステートメント、while ステートメント、トータルロット演算子、ポインタの逆参照、インラインのマシンコード、コメントなど。これらすべての側面により、かなり親切にこのプログラムが組み立てられます。
たとえば、次のプログラムは、シフトする正弦波をアニメーション化します。
int y; int x; int x_0; void sin_positive_estimate() { y=( x_0 ( 157 - x_0 ) )>> 7; void sin() { x_0=x; while( x_0> 314 ){ x_0=x_0 - 314; if( x_0 <=157 ){ sin_positive_approx(); } if( x_0> 157 ){ x_0=x_0 - 157; sin_positive_about(); y=0 - y; y=100 + y; int オフセット; int x_end; voiddraw_sine_wave() { x=オフセット; x_end=x + 314; while( x <=x_end ){ sin(); ピクセル_x=x - オフセット; ピクセル_y=y; vga_set_pixel(); x=x + 1; int v_1; int v_2; void prolong() { v_1=0; while( v_1 <50 ){ v_2=0; while( v_2 <10000 ){ v_2=v_2 + 1; } v_1=v_1 + 1; }}void main(){ vga_init(); offset=0; while( 1 ){ vga_clear(); draw_sine_wave(); delay(); offset=offset + 1; if( offset>=314 ){ // 2^16 整数オーバーフローから飛び出た方法を保持するために値を変更します offset=offset - 314;
スクリーンショット
SectorC に魅了され始めたとき、私は倫理的に OTCC の難読化解除を実行し、さまざまな提案が新たに頭にロードされました。 さらに、私は倫理的に、justine.lol と の健康的な用量を摂取しました。 Tom7 不条理な出来事すべてにインスピレーションを与えてくれました。
私は成功するだろうと思っていましたか? 私はNOを疑いました。 510 バイトの命令メモリ内の合計 C コンパイラと一致しますか? 真実の公正な適切な幸運 (皮肉)。
トークン化
最初の欠点は気まぐれでした。 C では、トークナイザー/レクサーだけで 1 つの 512 バイト セクターより大きく見えます。 ここで、バイトの任意の循環を満足して「トークン」を獲得する必要があります。
例:
int Vital() { if( a <5 ){ func();
消費され、次のように変換されます:
'int' TOKEN_KEYWORD_INT 'vital' TOKEN_IDENTIFIER '(' TOKEN_LPAREN ')' TOKEN_RPAREN '{' TOKEN_LBRACE 'if' TOKEN_KEYWORD_IF '(' TOKEN_LPAREN 'a' TOKEN_IDENTIFIER '<' TOKEN_OPERATOR '5' TOKEN_NUMBER ') ' TOKEN_RPAREN '{' TOKEN_LBRACE 'func' TOKEN_IDENTIFIER '(' TOKEN_LPAREN ')' TOKEN_RPAREN ';' TOKEN_SEMI '}' TOKEN_RBRACE '}' TOKEN_RBRACE
特に キー フレーズを認識する必要があります
、識別子
、オペラト