(案) >pr 1+2*3 → こんなふうに普通に書いたら、インタプリタ実行 7 >!pr 1+2*3 → こんなふうに!を頭に付けたらgccでコンパイルして実行 7
#include <stdio.h>
int main()
{
puts("hello, wolrd");
return 0;
}#include <stdlib.h>
int __getmainargs(int *argc, char ***argv, char ***env, int doWildCard, void *);
int mmain(int argc, char **argv);
void mainCRTStartup()
{
int argc, startupinfo[100/4 /* でもたぶん68バイトしか使ってない */];
char **argv, **env;
__getmainargs(&argc, &argv, &env, 0, startupinfo);
exit(mmain(argc, argv));
}OUTPUT_FORMAT(pei-i386)
SECTIONS
{
. = SIZEOF_HEADERS;
. = ALIGN(__section_alignment__);
.text __image_base__ + ( __section_alignment__ < 0x1000 ? . : __section_alignment__ ) :
{
*(.text)
*(SORT(.text$*))
*(.rdata)
*(SORT(.rdata$*))
}
.idata BLOCK(__section_alignment__) :
{
SORT(*)(.idata$2)
SORT(*)(.idata$3)
/* These zeroes mark the end of the import list. */
LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
SORT(*)(.idata$4)
SORT(*)(.idata$5)
SORT(*)(.idata$6)
SORT(*)(.idata$7)
__data_start__ = . ;
*(.data)
*(.data2)
*(SORT(.data$*))
}
.bss BLOCK(__section_alignment__) :
{
__bss_start__ = . ;
*(.bss)
*(COMMON)
__bss_end__ = . ;
}
}c:\mingw516\bin\gcc -m32 -Os mstartup.c -c -o mstartup.obj c:\mingw516\bin\gcc -m32 -Os %1.c -c -o %1.obj -Dmain=mmain c:\mingw516\bin\ld -T ldscript.txt -o %1.exe -Bdynamic -s mstartup.obj %1.obj -Bdynamic -Lc:/mingw516/bin/../lib/gcc/mingw32/3.4.5 ^ -Lc:/mingw516/bin/../lib/gcc -Lc:/mingw516/bin/../lib/gcc/mingw32/3.4.5/../../../../mingw32/lib ^ -Lc:/mingw516/bin/../lib/gcc/mingw32/3.4.5/../../.. -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 -ladvapi32 ^ -lshell32 -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt
prompt>mcc hello
prompt>gcc --verbose hello.c -O3 -o hello.exeでデフォルトを出力させて、そこから「たぶんここはC言語では使わないだろう」と思うところを削っていって、それでちょっとだけ並べ替えて作りました(.rdataが.textの中に入るように、.dataが.idataの中に入るように)。
prompt>gcc --verbose hello.c -O3 -o hello.exeってやって取得しました。collect2.exe(=ldの実体)への引数もこれで分かります。そのうちの.oファイルについては不要なもの(=消してみても動作に支障がなかったもの)は全部消してサイズを節約しています。
[改造前] APlay *p = aOpenPlay(100000); // 適当な大きさのバッファ. APlay_mml(p, 0, "CDEFEDCR EFGAGFER"); APlay_mml(p, 1, "R1R1 CDEFEDCR"); APlay_run(p); [改造後] PLAY "CDEFEDCR EFGAGFER"; PLAY1 "R1R1 CDEFEDCR" →もはやワンライナーで十分。openもrunも自動でやる。
APlay *p = aOpenPlay16(100000); // 1- APlay_mml(p, 0, "T180 @1 r2.e-8d-8 r4g-4g-4e-8d-8 r4g-4g-4e-8d-8 r4g-4r4g-4"); APlay_mml(p, 1, "@1 r2.e-8d-8 r4<b-4b-4>e-8d-8 r4<b-4b-4>e-8d-8 r4<b-4r4b-4"); APlay_mml(p, 2, "@1 r2.r4 <g-4r4r2 g-4r4r2 g-4r4e-4r4"); // 5- APlay_mml(p, 0, "r4f4f4e-8d-8 r4f4f4e-8d-8 r4f4f4e-8d-8 r4f4r4f4"); APlay_mml(p, 1, "r4>c-4c-4e-8d-8 r4c-4c-4e-8d-8 r4c-4c-4e-8d-8 r4c-4r4c-4"); APlay_mml(p, 2, "d-4r4r2 d-4r4r2 d-4r4r2 d-4r4e-4r4"); // 9- APlay_mml(p, 0, "r4g-4g-4e-8d-8 r4g-4g-4e-8d-8 r4g-4g-4e-8d-8 r4g-4r4g-4"); APlay_mml(p, 1, "r4<b-4b-4>e-8d-8 r4<b-4b-4>e-8d-8 r4<b-4b-4>e-8d-8 r4<b-4r4b-4"); APlay_mml(p, 2, "g-4r4r2 >b-4r4r2 b-4r4r2 b-4r4>d-4r4"); // 13- APlay_mml(p, 0, "r4f4f4e-8d-8 r4f4f4e-8d-8 r4f4f4e-8d-8 r4f4r4f4"); APlay_mml(p, 1, "r4>c-4c-4e-8d-8 r4c-4c-4e-8d-8 r4c-4c-4e-8d-8 r4c-4r4c-4"); APlay_mml(p, 2, "e-4r4r2 e-4r4r2 e-4r4r2 e-4r4d-4r4"); // 17- APlay_mml(p, 0, "r4g-4g-4e-8d-8 r4g-4r4g-4 r4g-4r4g-4 r1"); APlay_mml(p, 1, "r4<b-4b-4>e-8d-8 r4<b-4r4b-4 r4b-4r4b-4 r1"); APlay_mml(p, 2, "<b-4r4r2 <g-4r4d-4r4 g-4r4d-4r4 g-4f4g-4g4"); // 21- APlay_mml(p, 0, "r4f4f4e-8d-8 r4f4r4f4 r4f4r4f4 r1"); APlay_mml(p, 1, "r4>c-4c-4e-8d-8 r4c-4r4c-4 r4c-4r4c-4 r1"); APlay_mml(p, 2, "a-4r4r2 a-4r4d-4r4 a-4r4d-4r4 a-4g4a-4a4"); // 25- APlay_mml(p, 0, "r4g-4g-4e-8d-8 r4g-4g-4e-8d-8 r4g-4g-4e-8d-8 r4g-4r4g-4"); APlay_mml(p, 1, "r4<b-4b-4>e-8d-8 r4<b-4b-4>e-8d-8 r4<b-4b-4>e-8d-8 r4<b-4r4b-4"); APlay_mml(p, 2, "b-4r4r2 g-4r4r2 g-4r4r2 g-4r4e-4r4"); // 29- APlay_mml(p, 0, "r4f4f4e-8d-8 r4f4f4e-8d-8 r4f4f4e-8d-8 r4f4r4f4"); APlay_mml(p, 1, "r4>c-4c-4e-8d-8 r4c-4c-4e-8d-8 r4c-4c-4e-8d-8 r4c-4r4c-4"); APlay_mml(p, 2, "d-4r4r2 d-4r4r2 d-4r4r2 d-4r4e-4r4"); // 33- APlay_mml(p, 0, "r4g-4g-4r4 g-4d-8d-8d4d-4 r4f4g-4r4"); APlay_mml(p, 1, "r4<b-4b-4r4 b-4>d-8d-8d4d-4 r4c-4<b-4r4"); APlay_mml(p, 2, "g-4r4r2 d-4r4r2 r4d-4<g-4r4"); APlay_run(p);
[1] 「1」を表示してみよう。 PR 1 [2] Iに1を入れてIを表示してみよう。 I = 1; PR I [3] [2]の続きとして、Iを1ずつ増やして、3まで表示してみよう(ここでテキストエディタの使い方なども教える)。RUNで実行。 I = 1; PR I; I = I + 1; PR I; I = I + 1; PR I; [4] GOを使って読み飛ばしてみるよ。どうなると思う?・・・もしGO命令がなかったらどうなると思う? NO1: PR 1; GO NO3; NO2: PR 2; NO3: PR 3; NO4: PR 4; [5] GOで前に戻ることもできるよ。どうなると思う? NO1: PR 1; GO NO1; [6] じゃあこれはどうなるかな? I = 1; NO1: PR I; I = I + 1; GO NO1; 数字がつながって見にくかったら、 PR I; の後に PRSP; を追加しよう。 [7] ずっと止まらないのは困るかな。じゃあ、100になったら止まるようにしよう。 I = 1; NO1: PR I; PRSP; I = I + 1; IF (I <= 100) GO NO1; // 101になったらgoしなくなるよ! [8] 2から100までの偶数を表示するプログラムを書いてみよう! [9] 1から99までの奇数を表示するプログラムを書いてみよう! [10] 1, 2, 4, 8, 16, 32, ... で65536までを表示るプログラムを書いてみよう! [11] 1から10までの和は55だけど、それを計算させてみよう。 PR 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 でも1から100までだったら、この調子では書けないね。どうしたらいいかな? J = 0; I = 1; NO1: J = J + I; I = I + 1; IF (I <= 100) GO NO1; PR J; どうしてこれでうまくいくのか説明ができるかな?
char *myfunc(int a, int b)
{
char *s = malloc(100);
sprintf(s, "hello: a+b=%d\n", a + b);
return s;
}>!prs myfunc(1, 2) hello: a+b=3 >
| コメント | お名前 | NameLink | |