ছোট্ট বাইটকোড ইন্টারপ্রেটার / ভিএম


17

লিডারবোর্ড - জেআইটি সংকলিত (নিম্নে ভাল)

  1. es1024 - 81.2 পয়েন্ট (একটি ওয়ার্কিং সংকলক সহ!)
  2. কিথ র্যান্ডাল - 116 পয়েন্ট
  3. Ell - 121 পয়েন্ট

লিডারবোর্ড - ব্যাখ্যা করা (নিম্নতর ভাল)

  1. মার্টিন বাটনার - 706654 পয়েন্ট (কোথাও প্রায় 2 ঘন্টা)
  2. ক্রিপটাইচ - 30379 পয়েন্ট (97 সেকেন্ড)

আপনার মিশনটি, আপনি যদি এটি গ্রহণ করা পছন্দ করেন তবে হ'ল ছোট্ট সম্ভাব্যতম বাইটকোড দোভাষী / ভিএম লিখুন। নীচে বর্ণিত ভাষাটি সহ ভিএম / ইন্টারপ্রেটার একটি ছোট সিআইএসসি আর্কিটেকচার (ক্রিয়াকলাপ আকারে পৃথক হতে পারে) ব্যবহার করে। সমাপ্তির পরে, আপনাকে অবশ্যই সঠিক সিপিটি (3,126,900,366) মুদ্রিত হয়েছে তা প্রমাণ করতে 3 সিপিইউ নিবন্ধকের মান মুদ্রণ করতে হবে।

সংকলনকারী

আপনি যদি নিজের পরীক্ষা করতে চান তবে নীচে একটি সংকলক পোস্ট করা হয়েছে। আপনার উত্তর দিয়ে আপনার পরীক্ষা পোস্ট করতে নির্দ্বিধায়।

"ভিএম" বিশেষ উল্লেখ

ভিএম-তে 3 32 বিট স্বাক্ষরবিহীন ইন্টিগ্রাল রেজিস্টার রয়েছে: আর 0, আর 1, আর 2। এগুলি 0x00, 0x01 এবং 0x02 হিসাবে হেক্সে উপস্থাপন করা হয়।

নিম্নলিখিত ক্রিয়াকলাপগুলি সমর্থন করা আবশ্যক:

ফর্ম্যাটটি হ'ল [নাম] [... অপারেশনস ...], [হেক্সাডেসিমাল অপ-কোড] [... অপারেশনগুলি পুনরাবৃত্তি করা হয়েছে ...]

  • লোড করুন [নিবন্ধ করুন] [4 বাইট মান], 0x00 [নিবন্ধন করুন] [4 বাইট মান]
  • পুশ [রেজিস্টার], 0x02 [রেজিস্টার]
  • পপ [রেজিস্টার], 0x03 [রেজিস্টার]
  • যোগ করুন [রেজিস্টার, 1 বাইট] [নিবন্ধন, 1 বাইট], 0x04 [নিবন্ধন] [নিবন্ধ]
  • এসইউবি [রেজিস্টার, 1 বাইট] [রেজিস্টার, 1 বাইট], 0x05 [রেজিস্টার] [রেজিস্টার]
  • মুল [রেজিস্টার, 1 বাইট] [রেজিস্টার, 1 বাইট], 0x06 [রেজিস্টার] [রেজিস্টার]
  • ডিআইভি [রেজিস্টার, 1 বাইট] [রেজিস্টার, 1 বাইট], 0x07 [রেজিস্টার] [রেজিস্টার]
  • জেএমপি [কোড লাইন, 4 বাইট], 0x08 [4 বাইট কোড লাইন নম্বর]
  • সিএমপি [রেজিস্টার, 1 বাইট] [রেজিস্টার, 1 বাইট], 0x09 [রেজিস্টার] [রেজিস্টার]
  • ব্রাঞ্চল্ট [কোড লাইন, 4 বাইট], 0x0a [4 বাইট কোড লাইন নম্বর]

কিছু নোট:

  • উপরের গণিত ক্রিয়াকলাপগুলি প্রথম নিবন্ধে আউটপুট রেখে একসাথে 2 টি নিবন্ধকের মান যুক্ত করে।
  • সিএমপি, তুলনা অপারেটর, 2 টি নিবন্ধকের মানগুলির তুলনা করে এবং শাখা নির্দেশাবলীতে ভবিষ্যতের ব্যবহারের জন্য কিছু অভ্যন্তরীণ পতাকায় আউটপুট সংরক্ষণ করতে পারে (এটি বাস্তবায়নের জন্য নির্দিষ্ট হতে পারে)।
  • যদি ব্রাঞ্চকে সিএমপির আগে ডাকা হয়, যদি না ব্রাঞ্চেক বলা হয়, "ভিএম" শাখা করা উচিত নয়।
  • পুশ / পিওপি আশ্চর্যজনকভাবে স্ট্যাক থেকে ধাক্কা বা পপ সংখ্যা।
  • জাম্প এবং ব্রাঞ্চ অপারেটররা বাইনারি ঠিকানা নয়, নির্দিষ্ট ক্রিয়ায় (কোড লাইন) ঝাঁপিয়ে পড়ে।
  • শাখা অপারেশন তুলনা না। বরং তারা নির্বাহের শেষ তুলনা থেকে আউটপুট নেয়।
  • শাখা এবং জাম্প অপারেটরগুলি শূন্য ভিত্তিক লাইন নম্বর সূচক সিস্টেম ব্যবহার করে। (যেমন জেএমপি 0 প্রথম লাইনে ঝাঁপ দেয়)
  • সমস্ত ক্রিয়াকলাপ স্বাক্ষরিত সংখ্যাগুলিতে করা হবে যা ওভারফ্লো শূন্যে চলে যায় এবং পূর্ণসংখ্যার ওভারফ্লোতে কোনও ব্যতিক্রম ছুঁড়ে না।
  • শূন্য দ্বারা বিভাগ অনুমোদিত নয় এবং যেমন, প্রোগ্রামটির আচরণটি সংজ্ঞায়িত হয় না। আপনি (উদাহরণস্বরূপ) ...
    • প্রোগ্রাম ক্রাশ।
    • ভিএম এর কার্যকরকরণের সমাপ্তি এবং এটি বর্তমান অবস্থানে ফিরে আসে।
    • একটি "ERR: বিভাগ দ্বারা 0" বার্তাটি দেখান।
  • প্রোগ্রামের সমাপ্তিটি সংজ্ঞায়িত করা হয় যখন নির্দেশ পয়েন্টারটি প্রোগ্রামের শেষের দিকে পৌঁছায় (একটি ফাঁকা প্রোগ্রাম অনুমান করা যায়)।

আউটপুট আউটপুট অবশ্যই এটি হতে হবে (নতুন লাইনে অন্তর্ভুক্ত)

R0 3126900366
R1 0
R2 10000    

পয়েন্ট পয়েন্টগুলি নিম্নলিখিত সূত্রের ভিত্তিতে গণনা করা হয়:Number Of Characters * (Seconds Needed To Run / 2)

হার্ডওয়্যার পার্থক্যের কারণে বিভিন্ন সময় এড়াতে প্রতিটি পরীক্ষা আমার কম্পিউটারে (i5-4210u, 8 গিগাবাইট র‌্যাম) উবুন্টু সার্ভার বা উইন্ডোজ 8-তে চালানো হবে, সুতরাং কিছু উন্মাদ-বহিরাগত-রেনটাইম ব্যবহার না করার চেষ্টা করুন যা কেবলমাত্র একটি দ্বৈত জি 5 তে সংকলন করে নিখরচায় 762.66 এমবি ফ্রি র‌্যাম সহ ম্যাক প্রো।

যদি আপনি কোনও বিশেষ রানটাইম / ভাষা ব্যবহার করেন তবে দয়া করে এটির একটি লিঙ্ক পোস্ট করুন।

  • আগ্রহী পক্ষের জন্য, আমি এখানে টেস্টিং কোড পোস্ট করেছি (সি # তে লিখিত): http://pastebin.com/WYCG5Uqu

পরীক্ষা প্রোগ্রাম

ধারণা থেকে এসেছিলেন এখানে , তাই আমরা তাদের প্রোগ্রামের একটি কিছুটা পরিমার্জিত সংস্করণ ব্যবহার করব।

প্রোগ্রামটির সঠিক আউটপুট: 3,126,900,366

সি তে:

int s, i, j;
for (s = 0, i = 0; i < 10000; i++) {
    for (j = 0; j < 10000; j++)
        s += (i * j) / 3;
}

কোডে: [R0 টি s এর প্রতিনিধি, i এর R1, i এর R2]

LOAD R0 0
LOAD R2 0 <--outer loop value
LOAD R1 0 <--inner loop value
     --Begin inner loop--
PUSH R1 <--push inner loop value to the stack
MUL R1 R2 <--(i*j)
PUSH R2
LOAD R2 3
DIV R1 R2 <-- / 3
POP R2
ADD R0 R1 <-- s+=
POP R1
PUSH R2 
LOAD R2 1
ADD R1 R2 <--j++
POP R2
PUSH R2
LOAD R2 10000
CMP R1 R2 <-- j < 10000
POP R2
BRANCHLT 3 <--Go back to beginning inner loop
--Drop To outer loop--
LOAD R1 1
ADD R2 R1 <--i++
LOAD R1 10000
CMP R2 R1 <-- i < 10000
LOAD R1 0 <--Reset inner loop
BRANCHLT 2

বাইনারি / হেক্সে:

0x00 0x00 0x00 0x00 0x00 0x00
0x00 0x02 0x00 0x00 0x00 0x00
0x00 0x01 0x00 0x00 0x00 0x00
0x02 0x01
0x06 0x01 0x02
0x02 0x02
0x00 0x02 0x00 0x00 0x00 0x03
0x07 0x01 0x02
0x03 0x02
0x04 0x00 0x01
0x03 0x01
0x02 0x02
0x00 0x02 0x00 0x00 0x00 0x01
0x04 0x01 0x02
0x03 0x02
0x02 0x02
0x00 0x02 0x00 0x00 0x27 0x10
0x09 0x01 0x02
0x03 0x02
0x0a 0x00 0x00 0x00 0x03
0x00 0x01 0x00 0x00 0x00 0x01
0x04 0x02 0x01
0x00 0x01 0x00 0x00 0x27 0x10
0x09 0x02 0x01
0x00 0x01 0x00 0x00 0x00 0x00
0x0a 0x00 0x00 0x00 0x02

বোনাস পয়েন্ট (প্রভাবগুলি বহু গুণে প্রয়োগ করা হয়) উদাহরণস্বরূপ আপনি যদি তিনটি ক্ষেত্রেই যোগ্যতা অর্জন করেন তবে এটি ((অক্ষর * 0.50) * 0.75) * 0.90 হবে

  • 50% হ্রাস যদি দোভাষা প্রকৃতপক্ষে একটি JIT সংকলক হয়
  • 25% হ্রাস যদি এটি কোনও ধরণের লুপ আনরোলিং / অর্থপূর্ণ অপ্টিমাইজেশান প্রয়োগ করে।
  • 10% হ্রাস যদি আপনি ভিএম এর সাথে প্রসারিত করেন
    • ব্রাঞ্চিউকিউ [কোড লাইন, 4 বাইট] (শাখা সমান হলে - অপকোড 0x0 বি)
    • ব্রাঞ্চজিটি [কোড লাইন, 4 বাইট] [শাখা বৃহত্তর হলে - অপকড 0x0 সি)
    • ব্রাঞ্চে [কোড লাইন, 4 বাইট] (শাখা সমান না হলে - অপকোড 0x0 ডি)
    • চালাও [রেজিস্টার 1] [রেজিস্টার 2] (রেজিস্টার 2 এর মান 1 - opcode 0x01 রেজিস্টার করতে সরান)।

প্রত্যাখ্যাত

  • প্রোগ্রামে পরীক্ষার কেস কম্পম্পিলিং নিষিদ্ধ। আপনাকে অবশ্যই এসটিডিইএন বা একটি ফাইল (বাইরের কোডটি গ্রহণ করতে হবে) যা কোনও ব্যাপার নয়।
  • প্রোগ্রামটি না চালিয়ে আউটপুট ফেরত।
  • অন্য কোনও উপায়ে ভিএম প্রয়োজনীয়তা প্রতারণা করার কথা ভাবতে পারেন।

আপনি যে বিষয়গুলি অস্বীকার করেছেন তা নিরুৎসাহিত করার জন্য কেন আরও কয়েকটি পরীক্ষা প্রোগ্রাম অন্তর্ভুক্ত করবেন না? যদি এটি কোনও ভিএম হয় তবে এটি বাইকোডের নির্দিষ্টকরণে লিখিত যে কোনও কিছু চালাতে সক্ষম হবে, তাই না?
কাসরান

আমি আজ রাতে চেষ্টা করব। আমি এখনই সংকলক লিখছি।
রঙিন একরঙা


1
কি CMPএর চেয়ে বড় বা সমতা কম জন্য দেখতে চান? এবং এর ফলাফল কি ঘটে?
es1024

1
MULএবং DIVঅপ্রকাশিত হয়। সেগুলি স্বাক্ষরিত বা স্বাক্ষরিত হওয়া উচিত? গুণের ওভারফ্লোতে কী ঘটে?
feersum

উত্তর:


8

সি, 752 (পতাকা সংজ্ঞায়িত করার জন্য 589 + 163) * 0.5 (জেআইটি) * 0.9 (এক্সটেনশন) * (0.75 অপ্টিমাইজেশন) * (0.64 সেকেন্ড / 2) = 81.216

C[S],J[S],i,j,k,y,c,X,Y,Z;char*R,a,b[9];main(x){R=mmap(0,S,6,34,-1,0);N=85;while(scanf("%c%s%*[ R]%d%*[ R]%d",&a,b,&x,&y)&&~getchar())a-=65,a-1?a-15?a-9?a?a-2?a-3?a-11?a-12?a-17?(N=41,v):(N=137,v):(N=137,u,N=247,g(H,4),N=139,u):(y?N=189+x,s(y):(N=51,g(G,G))):(N=137,u,N=247,g(H,6),N=139,u):(N=57,v,s(0xFC8A9F),--j):(N=1,v):(N=233,J[k++]=i,s(x)):b[1]-80?N=85+x:(N=93+x):(c=b[5],s(0x0F9EE78A),N=(c-69?c-71?c-76?1:8:11:0)+132,J[k++]=i,s(x)),C[++i]=j;U(E8,X)U(F0,Y)U(F8,Z)s(50013);i=j;while(k--)j=C[J[k]]+1,R[j-1]-233&&(j+=4),s(C[*(int*)(R+j)]-j-4);((int(*)())R)();printf("%u %u %u\n",X,Y,Z);}

কোড নেয় ( LOAD R0ইত্যাদি), কোনও চলমান অক্ষর, একক স্থান, মাঝখানে কোনও ফাঁকা রেখা, কোনও মন্তব্য নেই etc.

এরপরে এটি 80386 বাইকোডে রূপান্তরিত হয় এবং কার্যকর হয়।

লোড হচ্ছে 0একটি রেজিস্টার মধ্যে দ্বারা প্রতিস্থাপিত হয় xorনিজেই সঙ্গে রেজিস্টার ing পরিবর্তে moving 0রেজিস্টার, যা তিন বাইট উত্পন্ন বাইটকোড মধ্যে খাটো মধ্যে, এবং খুব সীমিতভাবে দ্রুত হতে পারে।

এর সাথে সংকলন:

gcc -m32 -D"g(a,b)=(N=192|b<<3|a)"-D"s(b)=(*(int*)(R+j)=b,j+=4)"-DN=R[j++]-D"G=((x+1)|4)"
-D"H=((y+1)|4)"-DS=9999-D"u=g(0,G)"-D"v=g(G,H)"-D"U(b,c)=s(0xA3##b##89),--j,s(&c);"
bytecode.c -o bytecode

পজিক্স-কমপ্লায়েন্ট ওএস প্রয়োজন।

এসটিডিআইএন থেকে ইনপুট পড়া হয় ( ./bytecode < fileকোনও ফাইল থেকে পাইপ ব্যবহার করুন)।

পরীক্ষার প্রোগ্রামের জন্য বাইটকোডের ফলাফল:

; start
 0:   55                      push   %ebp
; LOAD R0 0
 1:   33 ed                   xor    %ebp,%ebp
; LOAD R2 0
 3:   33 ff                   xor    %edi,%edi
; LOAD R1 0
 5:   33 f6                   xor    %esi,%esi
; PUSH $1
 7:   56                      push   %esi
; MUL R1 R2
 8:   89 f0                   mov    %esi,%eax
 a:   f7 e7                   mul    %edi
 c:   8b f0                   mov    %eax,%esi
; PUSH R2
 e:   57                      push   %edi
; LOAD R2 3
 f:   bf 03 00 00 00          mov    $0x3,%edi
; DIV R1 R2
14:   89 f0                   mov    %esi,%eax
16:   f7 f7                   div    %edi
18:   8b f0                   mov    %eax,%esi
; POP R2
1a:   5f                      pop    %edi
; ADD R0 R1
1b:   01 f5                   add    %esi,%ebp
; POP R1
1d:   5e                      pop    %esi
; PUSH R2
1e:   57                      push   %edi
; LOAD R2 1
1f:   bf 01 00 00 00          mov    $0x1,%edi
; ADD R1 R2
24:   01 fe                   add    %edi,%esi
; POP R2
26:   5f                      pop    %edi
; PUSH R2
27:   57                      push   %edi
; LOAD R2 10000
28:   bf 10 27 00 00          mov    $0x2710,%ed
; CMP R1 R2
2d:   39 fe                   cmp    %edi,%esi
2f:   9f                      lahf
30:   8a fc                   mov    %ah,%bh
; POP R2
32:   5f                      pop    %edi
; BRANCHLT 3
33:   8a e7                   mov    %bh,%ah
35:   9e                      sahf
36:   0f 8c cb ff ff ff       jl     0x7
; LOAD R1 1
3c:   be 01 00 00 00          mov    $0x1,%esi
; ADD R2 R1
41:   01 f7                   add    %esi,%edi
; LOAD R1 10000
43:   be 10 27 00 00          mov    $0x2710,%es
; CMP R2 R1
48:   39 f7                   cmp    %esi,%edi
4a:   9f                      lahf
4b:   8a fc                   mov    %ah,%bh
; LOAD R1 0
4d:   33 f6                   xor    %esi,%esi
; BRANCHLT 2
4f:   8a e7                   mov    %bh,%ah
51:   9e                      sahf
52:   0f 8c ad ff ff ff       jl     0x5
; copy R0 to X
58:   89 e8                   mov    %ebp,%eax
5a:   a3 28 5b 42 00          mov    %eax,0x425b
; copy R1 to Y
5f:   89 f0                   mov    %esi,%eax
61:   a3 38 55 44 00          mov    %eax,0x4455
; copy R2 to Z
66:   89 f8                   mov    %edi,%eax
68:   a3 40 55 44 00          mov    %eax,0x4455
; exit
6d:   5d                      pop    %ebp
6e:   c3                      ret

Ungolfed:

C[9999],J[9999],i,j,k,y,c,X,Y,Z;
char *R,a,b[9];
main(x){
    // 6 is PROC_WRITE|PROC_EXEC
    // 34 is MAP_ANON|MAP_PRIVATE
    R=mmap(0,'~~',6,34,-1,0);

    N=0x55;
    while(scanf("%c%s%*[ R]%d%*[ R]%d",&a,b,&x,&y)&&~getchar())
        a-=65,
        a-1? // B[RANCH**]
            a-15? // P[USH/OP]
                a-9? // J[MP]
                    a? // A[DD]
                        a-2? // C[MP]
                            a-3? // D[IV]
                                a-11? // L[OAD]
                                    a-12? // M[UL]
                                        a-17? // R[LOAD]
                                            // SUB
                                            (N=0x29,g(G,H))
                                        :(N=0x89,g(G,H))
                                    :(N=0x89,g(0,G),N=0xF7,g(H,4),N=0x8B,g(0,G))
                                :(y?N=0xBD+x,s(y):(N=0x33,g(G,G)))
                            :(N=0x89,g(0,G),N=0xF7,g(H,6),N=0x8B,g(0,G))
                        :(N=0x39,g(G,H),s(0xfc8a9f),--j)
                    :(N=0x1,g(G,H))
                :(N=0xE9,J[k++]=i,s(x))
            :b[1]-80? 
                N=0x55+x // PUSH
            :(N=0x5D+x) // POP
        :(c=b[5],s(0x0f9ee78a),N=(
        c-69? // EQ
            c-71? // GT
                c-76? // LT
                    1 // NE
                :8
            :11
        :0
        )+0x84,J[k++]=i,s(x)),
        C[++i]=j
        ;
    // transfer registers to X,Y,Z
    s(0xA3E889),--j,s(&X);
    s(0xA3F089),--j,s(&Y);
    s(0xA3F889),--j,s(&Z);

    // pop and ret
    s(0xC35D);

    i=j;
    // fix distances for jmp/branch**
    while(k--)
        j=C[J[k]]+1,R[j-1]-0xE9&&(j+=4),
        s(C[*(int*)(R+j)]-j-4);

    // call
    ((int(*)())R)();

    // output
    printf("%u %u %u\n",X,Y,Z);
}

কি দারুন. আমি আশা করি আমি ভিএম-তে সংকলক অন্তর্ভুক্ত করার জন্য একটি বোনাস যুক্ত করতাম।
একরঙা

15 রানের বেশি রান প্রতি গড় .67 সেকেন্ড।
রঙিন একরঙা

আমার একমত হতে হবে যে জোরিংটি একটি অনুকূলিতকরণ। চালাক কোড আকার অনুযায়ী, জোরিং ভিএম এর পারফরম্যান্স বৈশিষ্ট্যগুলি পরিবর্তন করে না (আমি ভুল হলে আমাকে সংশোধন করি)। অপ্টিমাইজেশনের দ্বারা আমি যা বোঝাতে চেয়েছি তা হ'ল ইনপুট কোড থেকে নির্দেশাবলী পরিবর্তন করা বা অপসারণ করা (উদাহরণস্বরূপ রিডানডেন্ট পিওপি ... পুশ সরানো) বা সারিতে 2 টি নির্দেশাবলী উপলব্ধি করে রেজিস্টার লোড করুন, যাতে একটি সরানো যেতে পারে ইত্যাদি।
রঙিন মনোক্রোম

সম্পাদনা: প্রকৃতপক্ষে, এটি একটি অপ্টিমাইজেশন: এটি 15 রানের চেয়ে প্রতি রান প্রতি 0.64 সেকেন্ডে নেমেছে। আমি অনুমান করি যে কোডটি সংক্ষিপ্ত করে ক্যাশে ছোঁড়াছুড়ি বা কিছু বাধা দেয় (বা অতিরিক্ত মেমরির প্রবেশাধিকার সরিয়ে দেয়)?
একরঙা

@ কালারফুলি মোনোক্রোম কিছু আর্কিটেকচার, যখন নিজেকে একটি রেজিস্টারের জোরিংয়ের সাথে উপস্থাপন করা হয়, আসলে নির্দেশটি কার্যকর করে না, তবে কেবল নিবন্ধের শূন্য করে।
es1024

7

সি, স্কোর = 854 বাইট × (~ 0.8 সেকেন্ড / 2) × 0.5 [জেআইটি] × 0.9 [এক্সটেনশানস] = ~ 154 বাইট সেকেন্ড

#define G getchar()
#define L for(i=0;i<3;++i)
#define N*(int*)
#define M(x)"P\x8a\xe7\x9e\xf"#x"    KL"
*T[1<<20],**t=T,*F[1<<20],**f=F,R[3],r[]={1,6,7};char*I[]={"L\xb8    GGJH","I\x8b\xc0HHGH","H\x50GG","H\x58GG","I\3\xc0HHGH","I\53\xc0HHGH","M\x8b\xc0\xf7\xe0\x8b\xc0IHLGJ","O\63\xd2\x8b\xc0\xf7\xf0\x8b\xc0IJNGL","L\xe9    KH","L\73\xc0\x9f\x8a\xfcHHGH",M(\x82),M(\x84),M(\x87),M(\x85)},C[1<<24],*c=C;main(i,o,l,g){N c=0xb7ec8b60;c[4]=70;c+=5;while((o=G)>=0){char*s=I[o];l=*s-'G';memcpy(c,s+1,l);for(s+=l+1;o=*s++;){o-='G';if(o<3){g=r[G];c[*s++-'G']|=g<<3*(o&1);if(o>1)c[*s++-'G']|=g<<3;}else{if(o>3)*f++=c+*s-'G';for(i=4;i;--i)c[*s-'G'+i-1]=G;++s;}}*t++=c;c+=l;}*t=c;while(f>F)--f,**f=(int)T[**f]-(int)*f-4;L N&c[7*i]=0x5893e|r[i]<<19,N&c[3+7*i]=R+i;N&c[21]=0xc361e58b;mprotect((int)C>>12<<12,1<<24,7);((void(*)())C)();L printf("R%d %u\n",i,R[i]);}

gcc vm.c -ovm -m32 -wএকটি x86 POSIX কমপ্লায়েন্ট ওএস দিয়ে কম্পাইল করুন
সাথে চালান ./vm < program, যেখানে programএকটি বাইনারি প্রোগ্রাম ফাইল।


গতির দিকে যাচ্ছি। প্রোগ্রামটি x86 মেশিন কোডে ইনপুট প্রোগ্রামটির একটি দুর্দান্ত সোজা-ফরোয়ার্ড অনুবাদ সম্পাদন করে এবং সিপিইউকে বাকী কাজটি করতে দেয়।

উদাহরণস্বরূপ, পরীক্ষার প্রোগ্রামটির অনুবাদ এখানে। ecx, esiএবং ediযথাযথ R0, R1এবং R2যথাযথ; bhস্থিতি পতাকা ধারণ করে; eaxএবং edxস্ক্র্যাচ রেজিস্টার হয়; কল-স্ট্যাকটি ভিএম এর স্ট্যাকের সাথে মিলে যায়:

# Prologue
     0:   60                      pusha
     1:   8b ec                   mov    ebp,esp
     3:   b7 46                   mov    bh,0x46
# LOAD R0 0
     5:   b9 00 00 00 00          mov    ecx,0x0
# LOAD R2 0 <--outer loop value
     a:   bf 00 00 00 00          mov    edi,0x0
# LOAD R1 0 <--inner loop value
     f:   be 00 00 00 00          mov    esi,0x0
#      --Begin inner loop--
# PUSH R1 <--push inner loop value to the stack
    14:   56                      push   esi
# MUL R1 R2 <--(i*j)
    15:   8b c6                   mov    eax,esi
    15:   f7 e7                   mul    edi
    19:   8b f0                   mov    esi,eax
# PUSH R2
    1b:   57                      push   edi
# LOAD R2 3
    1c:   bf 03 00 00 00          mov    edi,0x3
# DIV R1 R2 <-- / 3
    21:   33 d2                   xor    edx,edx
    23:   8b c6                   mov    eax,esi
    25:   f7 f7                   div    edi
    27:   8b f0                   mov    esi,eax
# POP R2
    29:   5f                      pop    edi
# ADD R0 R1 <-- s+=
    2a:   03 ce                   add    ecx,esi
# POP R1
    2c:   5e                      pop    esi
# PUSH R2
    2d:   57                      push   edi
# LOAD R2 1
    2e:   bf 01 00 00 00          mov    edi,0x1
# ADD R1 R2 <--j++
    33:   03 f7                   add    esi,edi
# POP R2
    35:   5f                      pop    edi
# PUSH R2
    36:   57                      push   edi
# LOAD R2 10000
    37:   bf 10 27 00 00          mov    edi,0x2710
# CMP R1 R2 <-- j < 10000
    3c:   3b f7                   cmp    esi,edi
    3e:   9f                      lahf
    3f:   8a fc                   mov    bh,ah
# POP R2
    41:   5f                      pop    edi
# BRANCHLT 4 <--Go back to beginning inner loop
    42:   8a e7                   mov    ah,bh
    44:   9e                      sahf
    45:   0f 82 c9 ff ff ff       jb     0x14
# --Drop To outer loop--
# LOAD R1 1
    4b:   be 01 00 00 00          mov    esi,0x1
# ADD R2 R1 <--i++
    50:   03 fe                   add    edi,esi
# LOAD R1 10000
    52:   be 10 27 00 00          mov    esi,0x2710
# CMP R2 R1 <-- i < 10000
    57:   3b fe                   cmp    edi,esi
    59:   9f                      lahf
    5a:   8a fc                   mov    bh,ah
# LOAD R1 0 <--Reset inner loop
    5c:   be 00 00 00 00          mov    esi,0x0
# BRANCHLT 3
    61:   8a e7                   mov    ah,bh
    63:   9e                      sahf
    64:   0f 82 a5 ff ff ff       jb     0xf
# Epilogue
    6a:   3e 89 0d 60 ac 04 09    mov    DWORD PTR ds:0x904ac60,ecx
    71:   3e 89 35 64 ac 04 09    mov    DWORD PTR ds:0x904ac64,esi
    78:   3e 89 3d 68 ac 04 09    mov    DWORD PTR ds:0x904ac68,edi
    7f:   8b e5                   mov    esp,ebp
    81:   61                      popa
    82:   c3                      ret

Ungolfed


বাহ ... আমার জেআইটি ছিল 900 ডলারের কোড (সি ++ তে লিখিত) ...
একরঙা

15 রানের জন্য রান প্রতি গড় 0.63 সেকেন্ড।
একরঙা

2

সিজেএম, 222 187 185 বাইট * (খুব ধীর / 2)

আমি কেবল দেখতে চেয়েছিলাম যে আমি সিজেমে লিখে বাইটকোড ভিএম কতটা সংক্ষিপ্ত পেতে পারি। 200 বাইটেরও কম মনে হয় বেশ শালীন। যদিও এটি ধীরে ধীরে ধীরে ধীরে, কারণ সিজেএম নিজেই ব্যাখ্যা করা হয়েছে। পরীক্ষার প্রোগ্রামটি চালাতে যুগে যুগে সময় লাগে।

304402480 6b:P;q:iD-);{(_P=@/(\L*@@+\}h;]:P;TTT]:R;{_Rf=~}:Q;{4G#%R@0=@t:R;}:O;{TP=("R\(\GG*bt:R;  ~R= R\~@t:R; Q+O Q4G#+-O Q*O Q/O ~(:T; Rf=~-:U; GG*bU0<{(:T}*;"S/=~T):TP,<}g3,{'R\_S\R=N}/

এটি চালানোর জন্য, এই সোর্সফোজের লিঙ্কে জাভা ইন্টারপ্রেটার ডাউনলোড করুন , কোডটি সংরক্ষণ করুন vm.cjamএবং এটি দিয়ে চালান

java -jar cjam-0.6.2.jar vm.cjam

প্রোগ্রামটি STDIN এ বাইকোড আশা করে। পাওয়ারশেল একটি ট্রেইলিং লাইন ব্রেক যোগ করে রূপান্তর 0x0aনা করেই কোনও প্রোগ্রামে বাইনারি ডেটা পাইপ করার কোনও উপায় আমি এখনও পাইনি 0x0d 0x0a, যা সত্যই বিরক্তিকর। কোডটি ঠিক করার জন্য 4 বাইট অন্তর্ভুক্ত করে D-);, যা আমি মোট গণনাতে অন্তর্ভুক্ত করি না, কারণ প্রোগ্রামটির কিছুটা অদ্ভুতভাবে এনকোড সংস্করণ পরিবর্তে এটি STDIN এ নিজেই বাইটকোড পেয়ে থাকলে তা করা উচিত নয় because । যদি কেউ এর জন্য কোনও সমাধান জানেন তবে দয়া করে আমাকে জানান let

সামান্য শৃঙ্খলাবদ্ধ:

304402480 6b:P; "Create lookup table for instruction sizes. Store in P.";
q:i             "Read program and convert bytes to integers.";
D-);            "Remove spurious carriage returns. This shouldn't be necessary.";
{(_P=@/(\L*@@+\}h;]:P; "Split into instructions. Store in P.";
"We'll use T for the instruction pointer as it's initialised to 0.";
"Likewise, we'll use U for the CMP flag.";
TTT]:R; "Store [0 0 0] in R for the registers.";
{_Rf=~}:Q; "Register lookup block.";
{4G#%R@0=@t:R;}:O; "Save in register block.";
{TP=("R\(\GG*bt:R;

~R=
R\~@t:R;
Q+O
Q4G#+-O
Q*O
Q/O
~(:T;
Rf=~-:U;
GG*bU0<{(:T}*;"N/=~T):TP,<}g "Run program.";
3,{'R\_S\R=N}/

আমি আগামীকাল একটি যথাযথ ব্যাখ্যা যুক্ত করব।

সংক্ষেপে, আমি সমস্ত রেজিস্টারগুলি, নির্দেশ পয়েন্টারটি এবং ভেরিয়েবলগুলিতে তুলনা পতাকাটি সংরক্ষণ করছি, যাতে আমি সিএম-এর স্ট্যাকটি ভিএম এর স্ট্যাক হিসাবে ব্যবহারের জন্য মুক্ত রাখতে পারি।



1
20 পুনরাবৃত্তির জন্য 15.279 সেকেন্ড গড়। - 15 পরীক্ষা। তার মানে প্রতি পরীক্ষায় 2.12208333 ঘন্টা।
রঙিন একরঙা

1

পাইথন / সি ++, স্কোর = 56.66

1435 অক্ষর * .234 / 2 সেকেন্ড * .5 [জেআইটি] * .75 [অনুকূলিতকরণ] * .90 [অতিরিক্ত নির্দেশ]

ইনপুট প্রোগ্রামটিকে সি ++ তে সংকলিত করে, এতে জিসিসি চালায়, তারপরে ফলাফলটি চালায়। বেশিরভাগ সময় জিসিসির অভ্যন্তরে ব্যয় হয়।

আমি যেটি অপ্টিমাইজেশন করব তা হ'ল স্ট্যাক ক্রিয়াকলাপগুলিকে স্পষ্টভাবে পরিবর্তনশীলগুলিতে হ্রাস করা যদি এটি শব্দার্থতভাবে অনুমোদিত হয়। এটি প্রচুর সাহায্য করে, সংকলিত কোডের প্রায় 10x ভাল রানটাইম (ফলাফলের বাইনারিটি চালাতে প্রায় .056 সেকেন্ড)। আমি নিশ্চিত নই যে জিসিসি কী করছে যা আপনাকে সেই উন্নতি দেয়, তবে এটি ভাল।

import sys,os
x=map(ord,sys.stdin.read())
w=lambda x:(x[0]<<24)+(x[1]<<16)+(x[2]<<8)+x[3]
I=[]
while x:
 if x[0]==0:f='r%d=%d'%(x[1],w(x[2:]));n=6
 if x[0]==1:f='r%d=r%d'%(x[1],x[2]);n=3
 if x[0]==2:f='P%d'%x[1];n=2
 if x[0]==3:f='O%d'%x[1];n=2
 if x[0]==4:f='r%d=r%d+r%d'%(x[1],x[1],x[2]);n=3
 if x[0]==5:f='r%d=r%d-r%d'%(x[1],x[1],x[2]);n=3
 if x[0]==6:f='r%d=r%d*r%d'%(x[1],x[1],x[2]);n=3
 if x[0]==7:f='r%d=r%d/r%d'%(x[1],x[1],x[2]);n=3
 if x[0]==8:f='goto L%d'%w(x[1:]);n=5
 if x[0]==9:f='a=r%d;b=r%d'%(x[1],x[2]);n=3
 if x[0]==10:f='if(a<b)goto L%d'%w(x[1:]);n=5
 if x[0]==11:f='if(a==b)goto L%d'%w(x[1:]);n=5
 if x[0]==12:f='if(a>b)goto L%d'%w(x[1:]);n=5
 if x[0]==13:f='if(a!=b)goto L%d'%w(x[1:]);n=5
 I+=[f];x=x[n:]
D=[]
d=0
for f in I:D+=[d];d+='P'==f[0];d-='O'==f[0]
J=[]
if all(d==D[int(f[f.find('L')+1:])]for f,d in zip(I,D)if f[0]in'gi'):
 H='uint32_t '+','.join('s%d'%i for i in range(max(D)))+';'
 for f,d in zip(I,D):
  if f[0]=='P':f='s%d=r'%d+f[1:]
  if f[0]=='O':f='r'+f[1:]+'=s%d'%(d-1)
  J+=[f]
else:
 H='std::vector<uint32_t>s;'
 for f,d in zip(I,D):
  if f[0]=='P':f='s.push_back(r'+f[1:]+')'
  if f[0]=='O':f='r'+f[1:]+'=s.back();s.pop_back()'
  J+=[f]
P='#include<vector>\n#include<cstdint>\nuint32_t r0,r1,r2,a,b;'+H+'int main(){'
for i,f in enumerate(J):P+='L%d:'%i+f+';'
P+=r'printf("R0 %u\nR1 %u\nR2 %u\n",r0,r1,r2);}'
c=open("t.cc", "w")
c.write(P)
c.close()
os.system("g++ -O1 t.cc")
os.system("./a.out")

অবশ্যই আরও কিছু গল্ফ করা যেতে পারে।


15 রানের বেশি রান প্রতি গড় .477 সেকেন্ড।
রঙিন একরঙা

1

লুয়া 5.2 (বা লুয়াজিআইটি), 740 বাইট

প্রথমে চেষ্টা করুন, কেবলমাত্র গল্ফযুক্ত। এই সংস্করণটি (অন্তত পরীক্ষার প্রোগ্রামে) কাজ করে এবং অতিরিক্ত ওপকোডগুলি প্রয়োগ করে তবে স্বাক্ষরবিহীন গণিতের প্রয়োজনীয়তাটি সমর্থন করে না এবং বিশেষত দ্রুত নয়। বোনাস হিসাবে, যদিও এটি কোনও ভিএম-তে চলছে একটি ভিএম, এবং এটি এমনভাবে লেখা হয়েছে যে এটির ব্যাখ্যা করা যেতে পারে (পিইউসি-লুয়া দিয়ে চালানো) বা সাজ্ট-অফ-জেআইটি (লুয়াজিআইটি দিয়ে চালানো; এখনও ব্যাখ্যা করা, তবে দোভাষী এখন JITted)।

সম্পাদনা: গল্ফ করা আরও ভাল, এখনও বড়।

সম্পাদনা: একটি বড় ত্রুটি স্থির করে এখন গাণিতিককে unsigned longসীমার মধ্যে সীমাবদ্ধ করে । কোনওরকমে হাত থেকে বেরিয়ে যাওয়া থেকে আকার রক্ষা করতে সক্ষম হয়েছে, তবে এটি এখনও ভুল উত্তর দিচ্ছে।

সম্পাদনা: দেখা যাচ্ছে, ফলাফলটি সঠিক ছিল তবে ফলাফল আউট হয়নি। %uপরিবর্তে মুদ্রণ স্যুইচ %dএবং সব ঠিক আছে। আকার এবং গতি কিছুটা উন্নত করতে ভেরিয়েবলগুলির জন্য টেবিল-ভিত্তিক রেজিস্টারগুলিও স্যুইচ করা হয়েছে ।

সম্পাদনা: লুয়া 5.2 এর gotoবক্তব্যটি ব্যবহার করে (লুয়াজিআইটিতেও পাওয়া যায়) আমি "জেআইটি-টু-লুয়া" জেনারেটিং কোডের সাথে দোভাষীকে প্রতিস্থাপন করেছি যা লুয়া ভিএম নিজেই চালিত হয়। এটি সত্যই জেআইটি হিসাবে গণ্য হয়েছে কিনা তা নিশ্চিত নয় তবে এটি গতির উন্নতি করে।

U,S,P,F=table.unpack,table.insert,table.remove,math.floor X,r0,r1,r2,p,m,s=2^32,0,0,0,1,0,{}C={{'r%u=%u',1,4},{'r%u=r%u',1,1},{'S(s,r%u)',1},{'r%u=P(s)',1},{'r%u=(r%u+r%u)%%X',1,0,1},{'r%u=(r%u-r%u)%%X',1,0,1},{'r%u=(r%u*r%u)%%X',1,0,1},{'r%u=F(r%u/r%u)%%X',1,0,1},{'goto L%u',4},{'m=r%u-r%u',1,1},{'if m<0 then goto L%u end',4},{'if m==0 then goto L%u end',4},{'if m>0 then goto L%u end',4},{'if m~=0 then goto L%u end',4}}t={io.open(arg[1],'rb'):read('*a'):byte(1,-1)}i,n,r=1,0,{}while i<=#t do c,i,x,a=C[t[i]+1],i+1,0,{}for j=2,#c do y=c[j]if y>0 then x=0 for k=1,y do i,x=i+1,x*256+t[i]end end S(a,x)end S(r,('::L%d::'):format(n))n=n+1 S(r,c[1]:format(U(a)))end load(table.concat(r,' '))()print(('R0 %u\nR1 %u\nR2 %u'):format(r0,r1,r2))

এখানে আসল, পঠনযোগ্য সংস্করণ।

U,S,P,F=table.unpack,table.insert,table.remove,math.floor

X,r0,r1,r2,p,m,s=2^32,0,0,0,1,0,{}

C={
    {'r%u=%u',1,4},
    {'r%u=r%u',1,1},
    {'S(s,r%u)',1},
    {'r%u=P(s)',1},
    {'r%u=(r%u+r%u)%%X',1,0,1},
    {'r%u=(r%u-r%u)%%X',1,0,1},
    {'r%u=(r%u*r%u)%%X',1,0,1},
    {'r%u=F(r%u/r%u)%%X',1,0,1},
    {'goto L%u',4},
    {'m=r%u-r%u',1,1},
    {'if m<0 then goto L%u end',4},
    {'if m==0 then goto L%u end',4},
    {'if m>0 then goto L%u end',4},
    {'if m~=0 then goto L%u end',4},
}

t={io.open(arg[1],'rb'):read('*a'):byte(1,-1)}
i,n,r=1,0,{}
while i<=#t do
    c,i,x,a=C[t[i]+1],i+1,0,{}
    for j=2,#c do
        y=c[j]
        if y>0 then
            x=0 
            for k=1,y do 
                i,x=i+1,x*256+t[i]
            end 
        end
        S(a,x)
    end
    S(r,('::L%d::'):format(n)) 
    n=n+1
    S(r,c[1]:format(U(a)))
end
load(table.concat(r,' '))()
print(('R0 %u\nR1 %u\nR2 %u'):format(r0,r1,r2))

আমি যখন আপনার প্রোগ্রামটি চালিয়েছি , তখন আমি নিম্নলিখিত ত্রুটিটি পেয়েছি: পেস্টবিন . com / QQBD7Rs8 । আপনি কি বাইটোকোড ওভার স্টিডিন বা ফাইল হিসাবে প্রত্যাশা করছেন?
রঙিন একরঙা

দুঃখিত। উইন্ডোগুলির জন্য আমার বাইনারি দূষিত হয়েছিল। সুতরাং, সমস্ত সিসিসি / লিনাক্স সংস্করণ কাজ করেছে তবে উইন্ডোজগুলি সমস্ত ক্র্যাশ করেছে। তবে এটি এখনও জানাচ্ছে যে আর 0 এবং আর 1 0, আর আর 2 হয় 1
রঙিন মনোক্রোম

আমার সন্দেহ হয় এটি আসলে কার্যকর হচ্ছে না: এটি চালাতে গড়ে 33.8 এমএস সময় নিয়েছে (জিসিসি ~ .25 সেকেন্ড সময় নেয়)।
রঙিন একরঙা

স্ক্রিপ্টটি বাইকোডকে একটি ফাইল হিসাবে প্রত্যাশা করে, ফাইলের নাম কমান্ড লাইনে পাস করার সাথে। যদিও আপনি ঠিক বলেছেন, আমি এটি সনাক্ত করেছি এবং দেখে মনে হচ্ছে এটি কেবল প্রথম বাহ্যিক লুপ করছে doing ড্রইং বোর্ডে ফিরে যাও ...
ক্রিপটাইচ মনিকার সাথে দাঁড়িয়ে আছে

সি-তে চিন্তা করা এবং লুয়াতে লেখার জন্য আমি এটাই পেয়েছি: আমি এর <পরিবর্তে আমার লুপগুলিতে ব্যবহার করেছি <=, তাই চূড়ান্ত শাখার নির্দেশটি রেখে দেওয়া হয়েছিল। এটি এখনও ভুল উত্তর পেয়েছে, তবে এটি করতে এখন কয়েক মিনিট সময় নেয়। :)
ক্রিপটিচ মনিকার সাথে

1

সি শার্প

1505 1475 বাইট

এটি আমার দোভাষীর আমার সংস্করণ, সি # তে লেখা আমার পক্ষে আরও অনুকূলিত / গল্ফ করা হতে পারে তবে আমি কোথায় জানি না;)

গল্ফ সংস্করণ:

using System;using System.Collections.Generic;using System.IO;using System.Linq;class M{static void Main(string[]a){if(a.Length==1&&File.Exists(a[0])){B.E(B.P(File.ReadAllLines(a[0])));Console.WriteLine(B.O);}}}class B{public enum I{L=0x00,P=0x02,Q=0x03,A=0x04,S=0x05,M=0x06,D=0x07,J=0x08,C=0x09,BL=0x0a,BE=0x0b,BG=0x0c,BN=0x0d}public enum R{A,B,C}enum C{N,L,E,G}public static Dictionary<R,uint>r=new Dictionary<R,uint>{{R.A,0},{R.B,0},{R.C,0}};public static Stack<uint>s=new Stack<uint>();static C c=C.N;public static string O{get{return string.Format("R0 {0}\nR1 {1}\nR2 {2}",r[R.A],r[R.B],r[R.C]);}}public static void E(byte[][]l){for(uint i=0;i<l.Length;i++){var q=l[i];switch((I)q[0]){case I.L:r[(R)q[1]]=U(q,2);break;case I.P:r[(R)q[1]]=s.Pop();break;case I.Q:s.Push(r[(R)q[1]]);r[(R)q[1]]=0;break;case I.A:s.Push(r[(R)q[1]]+r[(R)q[2]]);break;case I.S:s.Push(r[(R)q[1]]-r[(R)q[2]]);break;case I.M:s.Push(r[(R)q[1]]*r[(R)q[2]]);break;case I.D:s.Push(r[(R)q[1]]/r[(R)q[2]]);break;case I.J:i=U(q,1)-1;break;case I.C:{uint x=r[(R)q[1]],y=r[(R)q[2]];c=x<y?C.L:x>y?C.G:C.E;}break;case I.BL:if(c==C.L)i=U(q,1)-1;break;case I.BG:if(c==C.G)i=U(q,1)-1;break;case I.BE:if(c==C.E)i=U(q,1)-1;break;case I.BN:if(c!=C.E)i=U(q,1)-1;break;}}}public static byte[][]P(string[]c){return c.Where(l=>!l.StartsWith("#")).Select(r=>r.Split(' ').Where(b=>b.Length>0).Select(b=>Convert.ToByte(b,16)).ToArray()).Where(l=>l.Length>0).ToArray();}static uint U(byte[]b,int i){return(uint)(b[i]<<24|b[i+1]<<16|b[i+2]<<8|b[i+3]);}}

সম্পাদন করা

কিছু অপ্রয়োজনীয় publicএবং privateসংশোধক মুছে ফেলা হয়েছে :

using System;using System.Collections.Generic;using System.IO;using System.Linq;class M{static void Main(string[]a){if(a.Length==1&&File.Exists(a[0])){B.E(B.P(File.ReadAllLines(a[0])));Console.Write(B.O);}}}class B{enum I{L=0x00,P=0x02,Q=0x03,A=0x04,S=0x05,M=0x06,D=0x07,J=0x08,C=0x09,BL=0x0a,BE=0x0b,BG=0x0c,BN=0x0d}enum R{A,B,C}enum C{N,L,E,G}static Dictionary<R,uint>r=new Dictionary<R,uint>{{R.A,0},{R.B,0},{R.C,0}};static Stack<uint>s=new Stack<uint>();static C c=C.N;public static string O{get{return string.Format("R0 {0}\nR1 {1}\nR2 {2}\n",r[R.A],r[R.B],r[R.C]);}}public static void E(byte[][]l){for(uint i=0;i<l.Length;i++){var q=l[i];switch((I)q[0]){case I.L:r[(R)q[1]]=U(q,2);break;case I.P:r[(R)q[1]]=s.Pop();break;case I.Q:s.Push(r[(R)q[1]]);r[(R)q[1]]=0;break;case I.A:s.Push(r[(R)q[1]]+r[(R)q[2]]);break;case I.S:s.Push(r[(R)q[1]]-r[(R)q[2]]);break;case I.M:s.Push(r[(R)q[1]]*r[(R)q[2]]);break;case I.D:s.Push(r[(R)q[1]]/r[(R)q[2]]);break;case I.J:i=U(q,1)-1;break;case I.C:{uint x=r[(R)q[1]],y=r[(R)q[2]];c=x<y?C.L:x>y?C.G:C.E;}break;case I.BL:if(c==C.L)i=U(q,1)-1;break;case I.BG:if(c==C.G)i=U(q,1)-1;break;case I.BE:if(c==C.E)i=U(q,1)-1;break;case I.BN:if(c!=C.E)i=U(q,1)-1;break;}}}public static byte[][]P(string[]c){return c.Where(l=>!l.StartsWith("#")).Select(r=>r.Split(' ').Where(b=>b.Length>0).Select(b=>Convert.ToByte(b,16)).ToArray()).Where(l=>l.Length>0).ToArray();}static uint U(byte[]b,int i){return(uint)(b[i]<<24|b[i+1]<<16|b[i+2]<<8|b[i+3]);}}

কোডটি ব্যাখ্যা করার জন্য ফাইলটি executable.exe filenameকোথায় filenameরয়েছে তা দিয়ে এটি কল করুন

আমার "পরীক্ষার প্রোগ্রাম":

# LOAD R0 5
# CMP R0 R1
# BRANCHEQ 13
# LOAD R1 1
# LOAD R2 1
# CMP R0 R2
# MUL R1 R2
# LOAD R1 1
# ADD R2 R1
# PUSH R2
# PUSH R1 
# BRANCHEQ 13
# JMP 5
# POP R2
# POP R0
# POP R1
# PUSH R0

0x0 0x0 0x0 0x0 0x0 0x5
0x9 0x0 0x1 
0xb 0x0 0x0 0x0 0xd 
0x0 0x1 0x0 0x0 0x0 0x1 
0x0 0x2 0x0 0x0 0x0 0x1 
0x9 0x0 0x2 
0x6 0x1 0x2 
0x0 0x1 0x0 0x0 0x0 0x1 
0x4 0x2 0x1 
0x2 0x2 
0x2 0x1 
0xb 0x0 0x0 0x0 0xd 
0x8 0x0 0x0 0x0 0x5 
0x3 0x2 
0x3 0x0 
0x3 0x1 
0x2 0x0 

দোভাষীর দীর্ঘ নাম ভেরিয়েবল, ক্লাস, ...

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        if (args.Length == 1 && File.Exists(args[0]))
        {
            var code = ByteCodeInterpreter.ParseCode(File.ReadAllLines(args[0]));
            ByteCodeInterpreter.Execute(code);
            Console.WriteLine(ByteCodeInterpreter.Output);
        }
    }
}

public static class ByteCodeInterpreter
{
    public enum Instruction : byte
    {
        LOAD = 0x00,
        PUSH = 0x02,
        POP = 0x03,
        ADD = 0x04,
        SUB = 0x05,
        MUL = 0x06,
        DIV = 0x07,
        JMP = 0x08,
        CMP = 0x09,
        BRANCHLT = 0x0a,
        BRANCHEQ = 0x0b,
        BRANCHGT = 0x0c,
        BRANCHNE = 0x0d
    }

    public enum Register : byte
    {
        R0 = 0x00,
        R1 = 0x01,
        R2 = 0x02
    }

    private enum CompareFlag : byte
    {
        NONE = 0x00,
        LT = 0x01,
        EQ = 0x02,
        GT = 0x03,
    }

    public static readonly Dictionary<Register, uint> register = new Dictionary<Register, uint>
    {
        {Register.R0, 0},
        {Register.R1, 0},
        {Register.R2, 0}
    };

    public static readonly Stack<uint> stack = new Stack<uint>();
    private static CompareFlag compareFlag = CompareFlag.NONE;

    public static string Output
    {
        get
        {
            return string.Format("R0 {0}\nR1 {1}\nR2 {2}", register[Register.R0], register[Register.R1],
                register[Register.R2]);
        }
    }

    public static void Execute(byte[][] lines)
    {
        for (uint i = 0; i < lines.Length; i++)
        {
            var line = lines[i];
            switch ((Instruction)line[0])
            {
                case Instruction.LOAD:
                    register[(Register)line[1]] = GetUint(line, 2);
                    break;
                case Instruction.PUSH:
                    register[(Register)line[1]] = stack.Pop();
                    break;
                case Instruction.POP:
                    stack.Push(register[(Register)line[1]]);
                    register[(Register)line[1]] = 0;
                    break;
                case Instruction.ADD:
                    stack.Push(register[(Register)line[1]] + register[(Register)line[2]]);
                    break;
                case Instruction.SUB:
                    stack.Push(register[(Register)line[1]] - register[(Register)line[2]]);
                    break;
                case Instruction.MUL:
                    stack.Push(register[(Register)line[1]] * register[(Register)line[2]]);
                    break;
                case Instruction.DIV:
                    stack.Push(register[(Register)line[1]] / register[(Register)line[2]]);
                    break;
                case Instruction.JMP:
                    i = GetUint(line, 1) - 1;
                    break;
                case Instruction.CMP:
                    {
                        uint v0 = register[(Register)line[1]], v1 = register[(Register)line[2]];
                        if (v0 < v1)
                            compareFlag = CompareFlag.LT;
                        else if (v0 > v1)
                            compareFlag = CompareFlag.GT;
                        else
                            compareFlag = CompareFlag.EQ;
                    }
                    break;
                case Instruction.BRANCHLT:
                    if (compareFlag == CompareFlag.LT)
                        i = GetUint(line, 1) - 1;
                    break;
                case Instruction.BRANCHGT:
                    if (compareFlag == CompareFlag.GT)
                        i = GetUint(line, 1) - 1;
                    break;
                case Instruction.BRANCHEQ:
                    if (compareFlag == CompareFlag.EQ)
                        i = GetUint(line, 1) - 1;
                    break;
                case Instruction.BRANCHNE:
                    if (compareFlag != CompareFlag.EQ)
                        i = GetUint(line, 1) - 1;
                    break;
            }
        }
    }

    public static byte[][] ParseCode(string[] code)
    {
        return
            code.Where(line => !line.StartsWith("#"))
                .Select(line => line.Split(' ').Where(b => b.Length > 0).Select(b => Convert.ToByte(b, 16)).ToArray())
                .Where(line => line.Length > 0)
                .ToArray();
    }

    private static uint GetUint(byte[] bytes, int index)
    {
        return (uint)(bytes[index] << 24 | bytes[index + 1] << 16 | bytes[index + 2] << 8 | bytes[index + 3]);
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.