* buntan-pc #3
-(by [[K]], 2025.04.24)
** (0)
-https://github.com/buntan-pc/
-これにかかわる開発の話

** 2025.04.24 Thu #0
-今日はWSLをインストール。
--https://learn.microsoft.com/ja-jp/windows/wsl/install#install-wsl-command ここを見てやりました。
 ディストリビューションが正常にインストールされました。'wsl.exe -d Ubuntu' を使用して起動できます
--っていわれたので、たぶんうまくいっています。

-makeとかgccとかが入っていないようなので https://qiita.com/akiraarika932/items/4e001e451aebf39c2cb1 を見てインストール。
--うまくできったっぽい。
-さらに iverilog が必要なので「$ sudo apt install iverilog」でインストール。
-これで、 ucc の中にある e2etest.sh が全部通るようになりました。
-次は kuas でも同じことができるかどうか、ってことですね。

** 2025.04.24 Thu #1
-とりあえず現状を確認するとこんな感じ。
 [  OK  ]: int main() {return 31;} -> '1f'
 [  OK  ]: int main() {return 5 - 3 + 2;} -> '04'
 [  OK  ]: int main() {return 1+2*3;} -> '07'
 [  OK  ]: int main() {int a=3; return 5-a;} -> '02'
 [  OK  ]: int main() {int a=3; int b=5; return b*(a-1);} -> '0a'
 [  OK  ]: int main() {int a; a = 7; return a+1;} -> '08'
 [  OK  ]: int main() {int a = 1; return 5*((a=3)-1);} -> '0a'
 [  OK  ]: int main() {return 3 < 5;} -> '01'
 [  OK  ]: int main() {return 1 > 2;} -> '00'
 [  OK  ]: int main() {int a=0; a=2<3; return a;} -> '01'
 [  OK  ]: int main() {if(0){return 2;} return 3;} -> '03'
 [  OK  ]: int main() {if(4){return 2;} return 3;} -> '02'
 [  OK  ]: int main() {if(0) return 2; else return 4; return 3;} -> '04'
 [  OK  ]: int main() {int a=1; a += 2; a++; return ++a;} -> '05'
 [FAILED]: int main() {int a=3; a += 2; a++; return a++;} timed out, want '06'
 [  OK  ]: int main() {int a=8; a -= 2; return --a;} -> '05'
 [  OK  ]: int main() {int s=0; for(int i=2; i<=4; ++i) s+=i; return s;} -> '09'
 [  OK  ]: int main() {int i = 258; return i >= 250;} -> '01'
 [  OK  ]: int main() {int i = 258; return i * 3 > 750;} -> '01'
 [  OK  ]: int main() {return (10-3) == 7;} -> '01'
 [  OK  ]: int main() {char c = 255; c++; return c == 0;} -> '01'
 [FAILED]: int main() {int a=2; int *p=&a; int b=*p; *p+=3; return a+b;} timed out, want '07'
 [  OK  ]: int main() {return (1 < 3 && 3 < 2) || (2 == 3-1);} -> '01'
 [  OK  ]: int main() {return 3 && 5;} -> '01'
 [FAILED]: int main() {char c = 255; char *p = &c; (*p)++; return *p == 0 && c == 0;} timed out, want '01'
 [  OK  ]: int main() {return 'a' + 2;} -> '63'
 [  OK  ]: int main() {return '\'';} -> '27'
 [  OK  ]: int main() {return '\n' + '\0' - '\a';} -> '03'
 [  OK  ]: int main() {int a = 255; int b = 1025; int c = 255; return b - 1022;} -> '03'
 [  OK  ]: int main() {return *("012" + 1) == 49;} -> '01'
 [  OK  ]: int main() {return "01234"[2] == 50;} -> '01'
 [  OK  ]: int main() {int i = 1; return "0123"[++i + 1];} -> '33'
 [  OK  ]: int main() {int i = 0; while(1){if(i == 5)break; i++;} return i;} -> '05'
 [  OK  ]: int main() {int s=0; for(int i=0;i<3;i++) for(int j=0;j<2;j++){s++;} return s;} -> '06'
 [  OK  ]: int main() {if(0){if(1){return 2;}else{return 3;}}else{if(1){return 4;} return 1;}} -> '04'
 [  OK  ]: int main() {int *p = 0x06; while((p[1]&1) == 0); return *p + 1;} -> '05'
 [  OK  ]: int main() {return -2;} -> 'fe'
 [  OK  ]: int main() {if (-1 < 0) { return 3; } else { return 5; }} -> '03'
 [  OK  ]: int main() {return 0xaf & 0xc1 | 0xfb ^ 255;} -> '85'
 [  OK  ]: int main() {char c = ~043; return c;} -> 'dc'
 [  OK  ]: int main() {int i; int s=0; for(i=0;i<20;i++){if(i>10){continue;} s+=i;} return s;} -> '37'
 [  OK  ]: int main() {int a[2] = {1, 3,}; return a[1];} -> '03'
 [  OK  ]: int main() {int a[2]; a[0] = 1; *(a+1) = 4; return *a + a[a[0]];} -> '05'
 [FAILED]: int main() {int a[3]; int *p = a+1; p[0] = 5; p[1] = 3; return a[1] * a[2];} timed out, want '0f'
 [  OK  ]: int main() {int *p=0x06; int s=0; int c=0; while(1){while((p[1]&1)==0); c=p[0]; if(c==0xfe)break; s+=c;} return s;} -> '05'
 [  OK  ]: int main() {return (010 >> 1) | (002 << 3);} -> '14'
 [  OK  ]: int main() {return 0xefff >> 12;} -> 'fe'
 [  OK  ]: int main() {return 0x8000 >> 15;} -> 'ff'
 [FAILED]: int main() {int i=0; char *s="a"; while(*s){i+=*s++;} return i;} timed out, want '61' timeout
 [FAILED]: int main() {int *p=0x06; char *s="hello"; while(*s){*p=*s++;while((p[1]&4)==0);} *p=4; return 0;} -> '', want 'hello'
 [  OK  ]: int f() { return 2; } int main() { return f() + 1; } -> '03'
 [  OK  ]: int f(int a, int b) { return a+b; } int main() { return f(2,3); } -> '05'
 [  OK  ]: int fib(int n) { if(n<3){return 1;}else{return fib(n-1)+fib(n-2);} } int main() { return fib(6); } -> '08'
 [FAILED]: int main() {int *p = 2; *p = 2; while (*p > 0); return 3; } timed out, want '03'
 [  OK  ]: int f(int ms){int *p=2; *p=ms; while(*p>0); return 0;} int main() {f(0x7fff); return 3;} timed out
 [FAILED]: int main() {char *p=0x80; *p=2; return *p+1; } timed out, want '03'
 [FAILED]: int main() {char *p=0x81; *p=1; return *p+3; } timed out, want '04'
 [FAILED]: int f(){return 0;} int main() {char *p=0x81; *p=3; f(); return p; } timed out, want '81'
 [FAILED]: void f(int *p){*p=2;} int main(){int i; f(&i); return i+1;} timed out, want '03'
 [  OK  ]: int f(){int a=2; int b=5; return a+b;} int main(){int b=1; int a=f(); return a==7 && b==1;} -> '01'
 [  OK  ]: int main(){int i=3; {int i=4;} return i*2;} -> '06'
 [  OK  ]: int main(){int i=3; {int i=4; return i*2;}} -> '08'
 [FAILED]: void isr(){*(int*)0x2f0=4;} int main(){int *p=0x2f0; *p=1; __builtin_set_isr(isr); asm("int"); return *p;} timed out, want '04'
 [  OK  ]: int main(){ char *p="foo" "ba"; int i=0; while(p[i]){i++;} return i;} -> '05'
 [FAILED]: int main(){int *t=2; int *c=4; if(*c){return 4;} *t=3; while(*t); return *c;} timed out, want '01'
 [FAILED]: void _ISR(){*(int*)0x2f0+=1;*(int*)2=0;} int main(){int*t=2;int*p=0x2f0; __builtin_set_isr(_ISR); *p=3;*(int*)4=2;*t=1;while(*t); *t=1;while(*t); return *p;} timed out, want '05'
 [FAILED]: int *t=2; int main(){ *t=3; while (*t>0); return 1; } timed out, want '01'
 [  OK  ]: int tim_cnt __attribute__((at(2))); int main(){ tim_cnt=3; while (tim_cnt>0); return 1; } -> '01'
 [  OK  ]: char large[300]; char c __attribute__((at(546))); int main(){ large[290] = 3; return c - 2; } -> '01'
 [FAILED]: int buf[4096]; int main(){int i; for(i=0; i<4096; i+=256){buf[i] = i;} return buf[1024]-1020; } timed out, want '04'
 [  OK  ]: int main() { int i = -1; if (i < 0) { return 2; } else { return 3; } } -> '02'
 [  OK  ]: int main() { int i = 0x8000; i = i >> 12; return i; } -> 'f8'
 [  OK  ]: int main() { unsigned int u = 0x8000; u = u >> 12; return u; } -> '08'
 [  OK  ]: int main() { int i = 0xffff; return i < 0; } -> '01'
 [  OK  ]: int main() { unsigned u = 0xffff; return u < 0; } -> '00'
 [  OK  ]: int main() { int i = 1; { int v = 3; return i + v; } } -> '04'
 [  OK  ]: int gx=0; void f(int x){gx=x+1;} int main() {int i=3; f(i); return i+gx;} -> '07'
 [  OK  ]: int gx; int main() {__builtin_set_gp(0x300); gx=0x5a; return *((int*)0x300)+1;} -> '5b'
 [FAILED]: int g() {return 7;} int main() {int(*f)()=g; return f();} timed out, want '07'
 [FAILED]: int main() {__builtin_write_pmem(512,3,0x12); __builtin_write_pmem(513,1,0xC800); int(*f)()=512; return f();} timed out, want '12'
 [  OK  ]: int main() {return !0 + !3;} -> '01'
 [  OK  ]: void f(){int i;for(i=0;i<1;++i){int a=7;}} int main(){int i=3; f(); return i;} -> '03'
 [  OK  ]: int main() {return "A\x03B"[1] + '\x01';} -> '04'
 [  OK  ]: #include "head_add.h" int main() { return add(1, 2); } -> '03'
 [  OK  ]: int main() {return ((f() >> 15) & 4) | ((g() >> 15) & 2);} unsigned int f(){return -1;} int g(){return -1;} -> '02'
 [  OK  ]: int main() {return gx[2] - gx[0];} int gx[3] = {3, 5, 7}; -> '04'
 [  OK  ]: int main() {int d=0; switch(1){case 0:return 5; case 1:++d; case 2:++d; break; default: return 6;} return d;} -> '02'
 [  OK  ]: int main() {int d=0; switch(1){case 1:++d;} return d;} -> '01'
 [  OK  ]: int main() {int d=0; switch(2){case 1:++d;} return d;} -> '00'
 [  OK  ]: int f(){int i; for (i=0; i<2; ++i); return i;} int main() {return 13 + f();} -> '0f'
 [FAILED]: int main() {int a[2]; int *p=a; for (int i=0; i<2; ++i) { *p++ = i+1; } return a[1]; } timed out, want '02'
-今のところ失敗するのは19個。

** 2025.04.24 Thu #2
-[FAILED]: int main() {int a=3; a += 2; a++; return a++;} timed out, want '06'
--なるほど、「 dup 0 」がアセンブルできない、と。そうだね、それはまだ作ってない。
--直したら失敗は17個になった。

-[FAILED]: int main() {int a=2; int *p=&a; int b=*p; *p+=3; return a+b;} timed out, want '07'
--なるほど、「 pop 」がアセンブルできない、と。そうだね、それはまだ作ってない。
--直したら失敗は2個になった。あとちょっとだ!

-[FAILED]: int g() {return 7;} int main() {int(*f)()=g; return f();} timed out, want '07'
--なるほど、オペランドなしのcallか・・・。確かに作ってなかったな。
--直したら失敗は0個になった!

** 2025.04.24 Thu #3
-ここまでの内容をまとめました。
-https://essen.osask.jp/files/kuas03a.zip (5.35KB)
--ソースファイルのみです。書いてないけどライセンスはKL-01です。buntan-pcにマージされたものは、MITライセンスになります。
--コンパイルの際は、 kuas.c のみコンパイルすればいいです。aclmini.cは勝手にインクルードされます。

** 2025.04.25 Fri #0
-なんかkuasがすっきりしてないので、見直し中。

** 2025.04.25 Fri #1
-できた。kuas.cの行数は318→285で33行も減って、構造もすっきりして読みやすさも向上したと思うのだけど、zipファイルのサイズは増えている・・・。
-なんかくやしいけど、まあいいかー。
-あと改善点としては、エラーがあったときにちゃんと1を返すようにしました(前までのバージョンは、未実装エラーがあっても手違いで0を返してしまっていたのです)。
-https://essen.osask.jp/files/kuas04a.zip (5.50KB)
--ソースファイルのみです。書いてないけどライセンスはKL-01です。buntan-pcにマージされたものは、MITライセンスになります。
--コンパイルの際は、 kuas.c のみコンパイルすればいいです。aclmini.cは勝手にインクルードされます。

** 2025.04.25 Fri #2
-今日は忙しくてできないけど、そのうち、「自動移植システムというか、移植支援ツールというか、なんかそういう感じのもの」の最初のバージョンを作りたい。

-[Q]前から好きだったエミュレータではなく、移植にしたのはなぜ?
-[A]まず、エミュレータ方式は手段としては最強です。どんなプログラムもエミュレータで解決できます。・・・しかし一方で、エミュレータを載せられるほどのメモリやCPUパワーがない環境もあります。そういう環境のためには、プログラムの移植の方がうれしいです。それで、移植だけでどこまでできるかをやってみたくなったのです。

** 2025.04.25 Fri #3
-例えば以下のようなMS-DOS用のアセンブラプログラムがあったとする。
     ORG   0x100
     MOV   AH,0x02
     MOV   DL,0x20
 l:  INT   0x21
     INC   DX
     CMP   DL,0x7f
     JNE   l
     MOV   AX,0x4c00
     INT   0x21
-これを以下の形に機械的に変換したい。
 jmpVpc:
     switch (vpc) {
     case 0:
         mov8ri(ah, 0x02);
         mov8ri(dl, 0x20);
     lb_l:
         int(0x21, 1);
     case 1:
         inc16(dx);
         cmp8ri(dl, 0x7f);
         jne(lb_l);
         mov16ri(ax, 0x4c00);
         int(0x21, 2);
     case 2:
     }
-ここまで変換できれば、あとはmov8riなどを関数もしくはマクロで用意するだけで、このプログラムは多くの環境で実行可能になるはず。

-ちなみにint()は、第二引数をip値の代わりにスタックに積む。iretで帰ってくるときは、スタックから取り出した値を変数vpcに代入して、goto jmpVpc;すれば目的の場所に行ける。
-incやcmpは変数ZF/CF/SF/OF/PF/AFをセットする。pushfなどの際には、これらのフラグ変数をかき集めてflagsを作る。

** 2025.04.27 Sun #0
-データ部をどうしたらいいかが結構むずかしい。C言語で許される程度まで表現力を下げようとすると、アセンブラでは考えられないほどの表現力になってしまう・・・。
-データ部をどうしたらいいかが結構むずかしい。C言語で許される程度まで表現力を下げようとすると、アセンブラでは考えられないほどのひどい表現力になってしまう・・・。
--やはりコンパイラ的なものを一枚入れるかな・・・。

-こういうのって第一印象が大事だろうと思うので、見栄えの悪すぎる実装例は出せないよなあ。
--ということは、最初は仕様の決まらないデータセグメントを使わない例で説明するべきってことだな。それは難しくない。

// seg(seg,vsg)やofs(lb, vpc)という構文は作れる.
// データのオフセットは共通になる。16bitアクセスがメインなら、データもuint16_tで書かれるべき.

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS