* スクリプト [#a5edfb45] #contents いつものように妄想という名の遊び。 * バイトコード [#k6da8bb7] スクリプトを解析後,変換されるバイトコード。 命令長が多少長くなっても,1命令で処理される内容が多い方がよいだろう。 * アセンブラ言語 [#fba2a405] ** オペランド [#t4cad9d2] *** num - 数値 [#ae8a2597] 頭に何も付けず数値,この場合は10進数表記。 もしくは頭に表記接頭辞''f'',''b'',''d'',''h'',''x'',を付ける。 符号を付ける場合は,表記接頭辞より手前に書く。 #code(){{ // 10進数表記 copy4 &bp[-4] 12345 copy4 &bp[-4] d12345 // 2進数表記 copy4 &bp[-4] b0001 // 8進数表記 copy4 &bp[-4] h7543 // 16進数表記 copy4 &bp[-4] x0123ABCD // 浮動点小数 copy4 &bp[-4] f1.23456 }} *** pointer value [#dbd08b25] :@ - シンボル| シンボル名に使っていい文字列は[a-zA-Z0-9_]。ただし1文字目に数値は使えない。 宣言するときはシンボル名の後に'':''。 参照するときは頭に@を付け,その後シンボル名。 #code(){{ VALUE_ONE: s32 1 func: copy4 &bp[-4] @VALUE_ONE[0] }} :bp - ベースポインタレジスタ| スタック上のベースとなる位置。 #code(){{ func: copy4 &bp[-4] 1 }} :reg - 計算用レジスタ| 好きに使って良いテンポラリレジスタ。 reg[0]からreg[31]まで使える。 エイリアスもある。 r0 == ®[0] , r1 == ®[4] , ... r7 = ®[28] :& - アドレス値を受け取る| 先頭に''&''。 #code(){{ func: copy4 &bp[-4] &bp }} :* - アドレス先の値を受け取る| 先頭に''*''。 #code(){{ func: copy4 &bp[-4] *bp[-8] }} :相対アドレスの指定| 後ろに[数値]で指定。 省略したら[0]と等価。 :example| #code(){{ # addr is 0x100 CONST_VALUE: s32 10 s32 20 u32 0x100 u32 0x110 #addr is 0x110 MUTABLE_VALUE: s32 0 s32 0 func: copy4 @MUTABLE_VALUE @CONST_VALUE # 0x110 = 0x100 copy4 @MUTABLE_VALUE @CONST_VALUE[0] # 0x110 = 10 copy4 @MUTABLE_VALUE &@CONST_VALUE[1] # 0x110 = 0x108 copy4 @MUTABLE_VALUE *@CONST_VALUE[2] # 0x110 = 10 }} ** ニーモニック命令 [#uc3b37a5] *** 表記 [#b934f54d] #code(){{ Operation: OperationCode Argument OperationCode Argument Argument OperactionCode: addi4 copy4 ... Argument: Name:Type Name: a-zA-Z Type: [aisuf][1248] # prefix is type kind. sufix is type size. }} :型の接頭辞| -a - any なんでもよし -i - integer 整数 -s - signed integer 符号付き整数 -u - unsigned integer 符号無し整数 -f - float 浮動小数 -p - address アドレス :オペランドの種類| -TypeA - numが使える -TypeP - numが使えない *** add - addition [#qe926862] :code| addi1 addr:p lhs:i1 rhs:i1 addi2 addr:p lhs:i2 rhs:i2 addi4 addr:p lhs:i4 rhs:i4 addi8 addr:p lhs:i8 rhs:i8 addf4 addr:p lhs:f4 rhs:f4 addf8 addr:p lhs:f4 rhs:f8 addr is TypeP lhs is TypeA rhs is TypeA :c summary| *addr = lhs + rhs; *** band - bit and [#ke51ecc3] :code| and1 addr:p lhs:a1 rhs:a1 and2 addr:p lhs:a2 rhs:a2 and4 addr:p lhs:a4 rhs:a4 and8 addr:p lhs:a8 rhs:a8 addr is TypeP lhs is TypeA rhs is TypeA :c summary| *addr = lhs & rhs; *** bnot - bit not [#t94f668f] :code| bnot1 addr:p val:a1 bnot2 addr:p val:a2 bnot4 addr:p val:a4 bnot8 addr:p val:a8 addr is TypeP val is TypeA :c summary| *addr = ~val; *** bor - bit or [#s44cc09f] :code| bor1 addr:p lhs:a1 rhs:a1 bor2 addr:p lhs:a2 rhs:a2 bor4 addr:p lhs:a4 rhs:a4 bor8 addr:p lhs:a8 rhs:a8 addr is TypeP lhs is TypeA rhs is TypeA :c summary| *addr = lhs | rhs; *** bxor - bit xor [#c38745c8] :code| bxor1 addr:p lhs:a1 rhs:a1 bxor2 addr:p lhs:a2 rhs:a2 bxor4 addr:p lhs:a4 rhs:a4 bxor8 addr:p lhs:a8 rhs:a8 addr is TypeP lhs is TypeA rhs is TypeA :c summary| *addr = lhs ^ rhs; *** call - call function [#h8315355] :code| call symbol:a symbol is TypeP *** cmp - compare [#cc7b57c2] :code| cmps1 lhs:s1 rhs:s1 cmps2 lhs:s2 rhs:s2 cmps4 lhs:s4 rhs:s4 cmps8 lhs:s8 rhs:s8 cmpu1 lhs:u1 rhs:u1 cmpu2 lhs:u2 rhs:u2 cmpu4 lhs:u4 rhs:u4 cmpu8 lhs:u8 rhs:u8 cmpf4 lhs:f4 rhs:f4 cmpf8 lhs:f8 rhs:f8 lhs is TypeA rhs is TypeA :c summary| cr[0] = lhs < rhs; cr[1] = lhs == rhs; cr[2] = lhs == NaN; (only cmpf) cr[3] = rhs == NaN; (only cmpf) *** cnv - type convert [#we231cea] :code| ''F4'' cnvF4tF8 dest:p src:f4 cnvF4tS1 dest:p src:f4 cnvF4tS2 dest:p src:f4 cnvF4tS4 dest:p src:f4 cnvF4tS8 dest:p src:f4 cnvF4tU1 dest:p src:f4 cnvF4tU2 dest:p src:f4 cnvF4tU4 dest:p src:f4 cnvF4tU8 dest:p src:f4 ''F8'' cnvF8tF4 dest:p src:f8 cnvF8tS1 dest:p src:f8 cnvF8tS2 dest:p src:f8 cnvF8tS4 dest:p src:f8 cnvF8tS8 dest:p src:f8 cnvF8tU1 dest:p src:f8 cnvF8tU2 dest:p src:f8 cnvF8tU4 dest:p src:f8 cnvF8tU8 dest:p src:f8 ''S1'' cnvS1tF4 dest:p src:s1 cnvS1tF8 dest:p src:s1 cnvS1tS2 dest:p src:s1 cnvS1tS4 dest:p src:s1 cnvS1tS8 dest:p src:s1 cnvS1tU1 dest:p src:s1 cnvS1tU2 dest:p src:s1 cnvS1tU4 dest:p src:s1 cnvS1tU8 dest:p src:s1 ''S2'' cnvS2tF4 dest:p src:s2 cnvS2tF8 dest:p src:s2 cnvS2tS1 dest:p src:s2 cnvS2tS4 dest:p src:s2 cnvS2tS8 dest:p src:s2 cnvS2tU1 dest:p src:s2 cnvS2tU2 dest:p src:s2 cnvS2tU4 dest:p src:s2 cnvS2tU8 dest:p src:s2 ''S4'' cnvS4tF4 dest:p src:s4 cnvS4tF8 dest:p src:s4 cnvS4tS1 dest:p src:s4 cnvS4tS2 dest:p src:s4 cnvS4tS8 dest:p src:s4 cnvS4tU1 dest:p src:s4 cnvS4tU2 dest:p src:s4 cnvS4tU4 dest:p src:s4 cnvS4tU8 dest:p src:s4 ''S8'' cnvS8tF4 dest:p src:s8 cnvS8tF8 dest:p src:s8 cnvS8tS1 dest:p src:s8 cnvS8tS2 dest:p src:s8 cnvS8tS4 dest:p src:s8 cnvS8tU1 dest:p src:s8 cnvS8tU2 dest:p src:s8 cnvS8tU4 dest:p src:s8 cnvS8tU8 dest:p src:s8 ''U1'' cnvU1tF4 dest:p src:u1 cnvU1tF8 dest:p src:u1 cnvU1tS1 dest:p src:u1 cnvU1tS2 dest:p src:u1 cnvU1tS4 dest:p src:u1 cnvU1tS8 dest:p src:u1 cnvU1tU2 dest:p src:u1 cnvU1tU4 dest:p src:u1 cnvU1tU8 dest:p src:u1 ''U2'' cnvU2tF4 dest:p src:u2 cnvU2tF8 dest:p src:u2 cnvU2tS1 dest:p src:u2 cnvU2tS2 dest:p src:u2 cnvU2tS4 dest:p src:u2 cnvU2tS8 dest:p src:u2 cnvU2tU1 dest:p src:u2 cnvU2tU4 dest:p src:u2 cnvU2tU8 dest:p src:u2 ''U4'' cnvU4tF4 dest:p src:u4 cnvU4tF8 dest:p src:u4 cnvU4tS1 dest:p src:u4 cnvU4tS2 dest:p src:u4 cnvU4tS4 dest:p src:u4 cnvU4tS8 dest:p src:u4 cnvU4tU1 dest:p src:u4 cnvU4tU2 dest:p src:u4 cnvU4tU8 dest:p src:u4 ''U8' cnvU8tF4 dest:p src:u8 cnvU8tF8 dest:p src:u8 cnvU8tS1 dest:p src:u8 cnvU8tS2 dest:p src:u8 cnvU8tS4 dest:p src:u8 cnvU8tS8 dest:p src:u8 cnvU8tU1 dest:p src:u8 cnvU8tU2 dest:p src:u8 cnvU8tU4 dest:p src:u8 dest is TypeP src is TypeA :c summary| *dest = (type)*src; *** copy - single data copy [#e24d1a69] :code| copy1 addr:p val:a1 copy2 addr:p val:a2 copy4 addr:p val:a4 copy8 addr:p val:a8 addr is TypeP val is TypeA :c summary| *addr = val *** dec - decremental [#c3d22c67] :code| decf4 addr:p decf8 addr:p deci1 addr:p deci2 addr:p deci4 addr:p deci8 addr:p addr is TypeP :c summary| --*addr; *** div - division [#q8f62086] :code| divf4 addr:p lhs:f4 rhs:f4 divf8 addr:p lhs:f8 rhs:f8 divs1 addr:p lhs:s1 rhs:s1 divs2 addr:p lhs:s2 rhs:s2 divs4 addr:p lhs:s4 rhs:s4 divs8 addr:p lhs:s8 rhs:s8 divu1 addr:p lhs:u1 rhs:u1 divu2 addr:p lhs:u2 rhs:u2 divu4 addr:p lhs:u4 rhs:u4 divu8 addr:p lhs:u8 rhs:u8 addr is TypeP lhs is TypeA rhs is TypeA :c summary| *addr = lhs / rhs; *** enter - begin of function [#s4d19122] :code| enter push_stack_size:u4 enterR push_stack_size:u4 push_stack_size is TypeA :asm summary| enter: push bp; bp = sp; sp -= push_stack_size; enterR: push bp; push reg; bp = sp; sp -= push_stack_size; *** inc - incremental [#c31d1776] :code| incf4 addr:p incf8 addr:p inci1 addr:p inci2 addr:p inci4 addr:p inci8 addr:p addr is TypeP :c summary| ++*addr; *** jump - jump program address [#y641cfb3] :code| jump dest:p jumpe dest:p # if equal jumpne dest:p # if not equal jumpl dest:p # if less jumple dest:p # if less equal jumpu dest:p # if NaN exist jumpnu dest:p # if not NaN exist dest is TypeP *** leave - end of function [#j3a9666b] :code| leave leaveR :asm summary| leave: sp = bp; pop bp; leaveR: sp = bp; pop reg; pop bp; *** mcopy - multi data copy [#k4bc823b] :code| mcopy4 dest:p src:p length:u4 dest is TypeP src is TypeP length is TypeA :c summary| memcpy(dest,src,length); *** mod - [#g5b972f0] :code| mods1 addr:p lhs:s1 rhs:s1 mods2 addr:p lhs:s2 rhs:s2 mods4 addr:p lhs:s4 rhs:s4 mods8 addr:p lhs:s8 rhs:s8 modu1 addr:p lhs:u1 rhs:u1 modu2 addr:p lhs:u2 rhs:u2 modu4 addr:p lhs:u4 rhs:u4 modu8 addr:p lhs:u8 rhs:u8 addr is TypeP lhs is TypeA rhs is TypeA :c summary| *addr = lhs % rhs; *** mul - multiply [#sbf078cf] :code| mulf4 addr:p lhs:f4 rhs:f4 mulf8 addr:p lhs:f8 rhs:f8 muls1 addr:p lhs:s1 rhs:s1 muls2 addr:p lhs:s2 rhs:s2 muls4 addr:p lhs:s4 rhs:s4 muls8 addr:p lhs:s8 rhs:s8 mulu1 addr:p lhs:u1 rhs:u1 mulu2 addr:p lhs:u2 rhs:u2 mulu4 addr:p lhs:u4 rhs:u4 mulu8 addr:p lhs:u8 rhs:u8 addr is TypeP lhs is TypeA rhs is TypeA :c summary| *addr = lhs * rhs; *** sll - shift left as logical [#e4fbcec7] :code| sll1 addr:p lhs:a1 rhs:u1 sll2 addr:p lhs:a2 rhs:u2 sll4 addr:p lhs:a4 rhs:u4 sll8 addr:p lhs:a8 rhs:u8 addr is TypeP lhs is TypeA rhs is TypeA :c summary| *addr = lhs << rhs; *** srl - shift right as logical [#r4a47f80] :code| slr1 addr:p lhs:a1 rhs:u1 slr2 addr:p lhs:a2 rhs:u2 slr4 addr:p lhs:a4 rhs:u4 slr8 addr:p lhs:a8 rhs:u8 addr is TypeP lhs is TypeA rhs is TypeA :c dummary| *addr = lhs >> rhs; *** sub - substitute [#cafb3924] :code| subf4 addr:p lhs:f4 rhs:f4 subf8 addr:p lhs:f8 rhs:f8 subi1 addr:p lhs:i1 rhs:i1 subi2 addr:p lhs:i2 rhs:i2 subi4 addr:p lhs:i4 rhs:i4 subi8 addr:p lhs:i8 rhs:i8 addr is TypeP lhs is TypeA rhs is TypeA :c summary| *addr = lhs - rhs; ** メモ [#n35db29d] #code(){{ main: enter 4 # push bp , bp = sp , sp = bp-4 leave # sp = bp , pop bp }} #code(c,){{ const int CONST_VALUE = 1; const int* CONST_VALUE_ADDR = &CONST_VALUE; struct Pos { int x; int y; }; const Pos CONST_OBJ_VALUE = {0,0}; const Pos* CONST_OBJ_VALUE_ADDR = &CONST_OBJ_VALUE; void func() { int stack_value; // -4(bp) int* stack_value_ptr: // -8(bp) int i; // -12(bp) i = 1; // 値 load i 1 // シンボルを参照 // load bp[-12] @CONST_VALUE_ADDR[0] i = *CONST_VALUE_ADDR; // シンボルを参照 // load bp[-12] @CONST_OBJ_VALUE_ADDR[4] i = CONST_OBJ_VALUE.y; // ベースポインタの相対指定 // load bp[-12] bp[-4] i = stack_value; // ベースポインタの相対アドレス // load bp[-8] &bp[-4] stack_value_addr = &stack_value; // ベースポインタの相対指定をアドレスとみなし参照 // load bp[-12] *bp[-8] i = *stack_value_ptr; } }} op[i1-i8f4-f8] val[p] val[i1-i8f4-f8] op[a1-a8] val[p] val[a1-a8] op[a1-a8] val[p] op[f4-f8s1-s8u1-u8] val[f4-f8s1-s8u1-u8] val[f4-f8s1-s8u1-u8] op[i1-i9f4-f8] val[p] op[f4-f8s1-s8u1-u8] val[p] val[f4-f8s1-s8u1-u8] op val:u4 op val:p op val:p val:p val:u4 op[s1-s8u1-u8] val[p] val[s1-s8u1-u8] op[a1-a8] val[p] val[u1-u8] cnvは特殊 val[p]: &bp[n] &symbol[n] ®[n] ®[n][n] *bp[n] *symbol[n] *reg[n] *reg[n][n] 値は禁止。 [0] : アドレスorアドレス参照 [12] 00 : bp [3] 0 : 12bit 相対アドレス指定 1 : 20bit 相対アドレス指定 [12] 01 : reg [1] 1 : symbol val[afisu]: num bp[n] symbol[n] reg[n] reg[n][n] *bp[n] *symbol[n] *reg[n] *reg[n][n] &bp[n] &symbol[n] ®[n] ®[n][n] [01] 00 : アドレス 01 : アドレス参照 10 : データ [23] 00 : num [45] type [67] type size [8-] data 00 : reg or bp 1 : symbol 11 : reg |