পটভূমি
আমি আমার পুরানো 8 বিট 6502 চিপ পছন্দ করি। 6502 মেশিন কোডে পিপিসিজি-তে কিছু চ্যালেঞ্জগুলি সমাধান করা এমনকি মজাদার। তবে কিছু জিনিস যা সহজ হওয়া উচিত (যেমন, ডেটাতে পড়া বা স্টাডআউট থেকে আউটপুট) মেশিন কোডে করা অযথা জটিল are সুতরাং আমার মনের মধ্যে একটি মোটামুটি ধারণা আছে: 6502 দ্বারা অনুপ্রাণিত আমার নিজস্ব 8-বিট ভার্চুয়াল মেশিন আবিষ্কার করুন, তবে চ্যালেঞ্জগুলির জন্য আরও ব্যবহারযোগ্য হতে পারে এমন নকশা সংশোধন করে। কোনও কিছুর বাস্তবায়ন শুরু করে, আমি বুঝতে পেরেছিলাম যে ভিএম এর ডিজাইনটি ন্যূনতম ন্যূনতম করে দেওয়া হলে এটি নিজের পক্ষে একটি দুর্দান্ত চ্যালেঞ্জ হতে পারে :)
কার্য
নিম্নলিখিত স্পেসিফিকেশন মেনে একটি 8-বিট ভার্চুয়াল মেশিন প্রয়োগ করুন। এটি কোড-গল্ফ , সুতরাং কয়েকটি বাইটের সাথে বাস্তবায়নটি জয়ী হয়।
ইনপুট
আপনার প্রয়োগের নিম্নলিখিত ইনপুট গ্রহণ করা উচিত:
একটি স্বাক্ষরবিহীন বাইট
pc
, এটি প্রাথমিক প্রোগ্রামের কাউন্টার (মেমরির ঠিকানা যেখানে ভিএম বাস্তবায়ন শুরু করে,0
ভিত্তিতে)সর্বাধিক দৈর্ঘ্যের
256
এন্ট্রি সহ বাইটগুলির একটি তালিকা, এটি ভার্চুয়াল মেশিনের র্যাম (এটির প্রাথমিক সামগ্রী সহ)
আপনি যে কোনও সংবেদনশীল বিন্যাসে এই ইনপুট নিতে পারেন।
আউটপুট
ভিএম সমাপ্ত হওয়ার পরে র্যামের চূড়ান্ত বিষয়বস্তু বাইটগুলির একটি তালিকা (নীচে দেখুন)। আপনি ধরে নিতে পারেন যে আপনি কেবল ইনপুট পেয়েছেন যা শেষ পর্যন্ত শেষের দিকে নিয়ে যায়। যে কোনও বুদ্ধিমান বিন্যাস অনুমোদিত।
ভার্চুয়াল সিপিইউ
ভার্চুয়াল সিপিইউ রয়েছে
- একটি 8-বিট প্রোগ্রাম কাউন্টার,
- একটি 8-বিট জড়িত রেজিস্টার বলা হয়
A
এবং - একটি 8 বিট সূচক রেজিস্টার বলা হয়
X
।
তিনটি স্থিতির পতাকা রয়েছে:
Z
- কিছু অপারেশন ফলাফল পরে শূন্য পতাকা সেট করা হয়0
N
someণাত্মক পতাকাটি কিছু অপারেশন ফলাফলের পরে নেতিবাচক সংখ্যার পরে সেট করা হয় (ফলাফলের বিট 7 সেট করা হয়)C
- বহনের পতাকাটি ফলাফলের "অনুপস্থিত" বিটের জন্য সংযোজন এবং শিফট দ্বারা সেট করা হয়
শুরু করার পরে, ফ্ল্যাগ সব সরিয়ে ফেলা হয়, প্রোগ্রাম কাউন্টার একটি প্রদত্ত মান এবং বিষয়বস্তু সেট করা হয় A
এবংX
অনির্দিষ্ট হয়।
8-বিট মানগুলি হয় প্রতিনিধিত্ব করে
- একটি স্বাক্ষরবিহীনপরিসরে পূর্ণসংখ্যা
[0..255]
- একটি স্বাক্ষরিত পূর্ণসংখ্যা, 2 এর পরিপূরক
[-128..127]
প্রসঙ্গে উপর নির্ভর করে। যদি কোনও অপারেশন ওভার-বা আন্ডারফ্লো হয় তবে মানটি চারদিকে .েকে যায় (এবং সংযোজনের ক্ষেত্রে ক্যারি পতাকাটি প্রভাবিত হয়)।
পরিসমাপ্তি
ভার্চুয়াল মেশিন কখন শেষ হয়
- একজন
HLT
নির্দেশ পৌঁছেছে - একটি অ-বিদ্যমান মেমরি ঠিকানা প্রবেশ করা হয়
- প্রোগ্রামের কাউন্টারটি মেমোরিটির বাইরে চলে যায় (নোট করুন এটি ভিএমএমকে পূর্ণ 256 বাইট মেমরির দেওয়া হলেও এটি মোড়ানো হয় না)
ঠিকানা মোড
- অন্তর্নিহিত - নির্দেশের কোনও যুক্তি নেই, অপরেন্ডটি নিহিত রয়েছে
- আশু - নির্দেশনার পরে অপারেন্ডটি বাইট হয়
- আপেক্ষিক - (কেবল শাখার জন্য) নির্দেশিকা সই হওয়ার পরে বাইট (2 এর পরিপূরক) এবং শাখা নেওয়া হলে প্রোগ্রামের কাউন্টারে যুক্ত করার জন্য অফসেটটি নির্ধারণ করে।
0
নিম্নলিখিত নির্দেশের অবস্থান - পরম - নির্দেশের পরে বাইট হ'ল অপারেন্ডের ঠিকানা
- সূচিবদ্ধ - নির্দেশের পরে বাইট
X
হ'ল অপারেন্ডের ঠিকানা (রেজিস্টার)
নির্দেশনা
প্রতিটি নির্দেশিকায় একটি অপকোড (একটি বাইট) থাকে এবং ঠিকানার মোডে তাত্ক্ষণিক , আপেক্ষিক , পরম এবং দ্বিতীয় যুক্তি বাইটকে সূচিত করা হয় । ভার্চুয়াল সিপিইউ কোনও নির্দেশনা কার্যকর করলে, এটি অনুসারে প্রোগ্রামের কাউন্টারকে বাড়িয়ে দেয় ( 1
বা দ্বারা 2
)।
এখানে প্রদর্শিত সমস্ত অপকড হেক্সে রয়েছে।
LDA
- লোড অপারেন্ড ইনA
- অপকডস: তাত্ক্ষণিক:,
00
নিরঙ্কুশ :, সূচকযুক্ত02
:04
- পতাকা:
Z
,N
- অপকডস: তাত্ক্ষণিক:,
STA
-A
অপারেন্ড মধ্যে স্টোর- অপকডস: তাত্ক্ষণিক:,
08
নিরঙ্কুশ :, সূচকযুক্ত0a
:0c
- অপকডস: তাত্ক্ষণিক:,
LDX
- লোড অপারেন্ড ইনX
- অপকডস: তাত্ক্ষণিক:,
10
পরম:12
:14
- পতাকা:
Z
,N
- অপকডস: তাত্ক্ষণিক:,
STX
-X
অপারেন্ড মধ্যে স্টোর- অপকডস: তাত্ক্ষণিক:,
18
নিরঙ্কুশ :, সূচকযুক্ত1a
:1c
- অপকডস: তাত্ক্ষণিক:,
AND
- বিটওয়াইস এবং এরA
এবং অপারেন্ড করাA
- অপকডস: তাত্ক্ষণিক:,
30
পরম:32
:34
- পতাকা:
Z
,N
- অপকডস: তাত্ক্ষণিক:,
ORA
- বিটওয়াইস বা এরA
এবং অপারেন্ড করাA
- অপকডস: তাত্ক্ষণিক:,
38
পরম:3a
:3c
- পতাকা:
Z
,N
- অপকডস: তাত্ক্ষণিক:,
EOR
- বিটওয়াইজ জোর (একচেটিয়া বা) এর মধ্যেA
এবং অপারেন্ডA
- অপকডস: তাত্ক্ষণিক:,
40
পরম:42
:44
- পতাকা:
Z
,N
- অপকডস: তাত্ক্ষণিক:,
LSR
- লজিকাল শিফট ডান, অপরেন্দ্রের সমস্ত বিট এক জায়গায় ডানদিকে স্থানান্তর করুন, বিট 0 বহন করতে যায়- অপকডস: তাত্ক্ষণিক:,
48
নিরঙ্কুশ :, সূচকযুক্ত4a
:4c
- পতাকা:
Z
,N
,C
- অপকডস: তাত্ক্ষণিক:,
ASL
- গাণিতিক শিফট বাম, অপারেন্ডের সমস্ত বিট এক জায়গায় বামে স্থানান্তরিত করুন, বিট 7 বহন করতে যায়- অপকডস: তাত্ক্ষণিক:,
50
নিরঙ্কুশ :, সূচকযুক্ত52
:54
- পতাকা:
Z
,N
,C
- অপকডস: তাত্ক্ষণিক:,
ROR
- ডানদিকে ঘোরান, অপরেন্দ্রের সমস্ত বিট এক জায়গায় ডানদিকে সরান, ক্যারিটি বিট 7 তে যায়, বিট 0 বহন করতে যায়- অপকডস: তাত্ক্ষণিক:,
58
নিরঙ্কুশ :, সূচকযুক্ত5a
:5c
- পতাকা:
Z
,N
,C
- অপকডস: তাত্ক্ষণিক:,
ROL
- বামদিকে ঘোরান, অপারেন্ডের সমস্ত বিট এক জায়গায় বামে স্থানান্তরিত করুন, বিট 0 তে যান, বিট 7 বহন করতে যান- অপকডস: তাত্ক্ষণিক:,
60
নিরঙ্কুশ :, সূচকযুক্ত62
:64
- পতাকা:
Z
,N
,C
- অপকডস: তাত্ক্ষণিক:,
ADC
- ক্যারি যুক্ত করুন, অপরেন্দ্র প্লাস ক্যারি যুক্ত করা হবেA
, বহন ওভারফ্লোতে সেট করা আছে- অপকডস: তাত্ক্ষণিক:,
68
নিরঙ্কুশ :, সূচকযুক্ত6a
:6c
- পতাকা:
Z
,N
,C
- অপকডস: তাত্ক্ষণিক:,
INC
- একের পর এক ইনক্রিমেন্ট অপারেন্ড- অপকডস: তাত্ক্ষণিক:,
78
নিরঙ্কুশ :, সূচকযুক্ত7a
:7c
- পতাকা:
Z
,N
- অপকডস: তাত্ক্ষণিক:,
DEC
- হ্রাস অপারেন্ড এক এক- অপকডস: তাত্ক্ষণিক:,
80
নিরঙ্কুশ :, সূচকযুক্ত82
:84
- পতাকা:
Z
,N
- অপকডস: তাত্ক্ষণিক:,
CMP
-A
অপারেন্ডকে বিয়োগ করে অপারেন্ডের সাথে তুলনা করুনA
, ফলাফলটি ভুলে যান। ক্যারিটি আন্ডারফ্লোতে সাফ হয়ে যায়, অন্যথায় সেট করুন- অপকডস: তাত্ক্ষণিক:,
88
নিরঙ্কুশ :, সূচকযুক্ত8a
:8c
- পতাকা:
Z
,N
,C
- অপকডস: তাত্ক্ষণিক:,
CPX
- তুলনাX
- হিসাবে একইCMP
জন্যX
- অপকডস: তাত্ক্ষণিক:,
90
নিরঙ্কুশ :, সূচকযুক্ত92
:94
- পতাকা:
Z
,N
,C
- অপকডস: তাত্ক্ষণিক:,
HLT
- অবসান- অপকডস: অন্তর্নিহিত:
c0
- অপকডস: অন্তর্নিহিত:
INX
-X
এক এক করে বৃদ্ধি- অপকডস: অন্তর্নিহিত:
c8
- পতাকা:
Z
,N
- অপকডস: অন্তর্নিহিত:
DEX
-X
এক এক করে হ্রাস- অপকডস: অন্তর্নিহিত:
c9
- পতাকা:
Z
,N
- অপকডস: অন্তর্নিহিত:
SEC
- বহন পতাকা সেট- অপকডস: অন্তর্নিহিত:
d0
- পতাকা:
C
- অপকডস: অন্তর্নিহিত:
CLC
- পরিষ্কার বহন পতাকা- অপকডস: অন্তর্নিহিত:
d1
- পতাকা:
C
- অপকডস: অন্তর্নিহিত:
BRA
- সর্বদা শাখা- অপকডস: আপেক্ষিক:
f2
- অপকডস: আপেক্ষিক:
BNE
-Z
পতাকা সাফ হলে শাখা- অপকডস: আপেক্ষিক:
f4
- অপকডস: আপেক্ষিক:
BEQ
-Z
পতাকা সেট করা হলে শাখা- অপকডস: আপেক্ষিক:
f6
- অপকডস: আপেক্ষিক:
BPL
-N
পতাকা সাফ হলে শাখা- অপকডস: আপেক্ষিক:
f8
- অপকডস: আপেক্ষিক:
BMI
-N
পতাকা সেট করা হলে শাখা- অপকডস: আপেক্ষিক:
fa
- অপকডস: আপেক্ষিক:
BCC
-C
পতাকা সাফ হলে শাখা- অপকডস: আপেক্ষিক:
fc
- অপকডস: আপেক্ষিক:
BCS
-C
পতাকা সেট করা হলে শাখা- অপকডস: আপেক্ষিক:
fe
- অপকডস: আপেক্ষিক:
Opcodes
উপরের তালিকা থেকে কোনও বৈধ নির্দেশনার মানচিত্র না পাওয়া কোনও অপকোড পাওয়া গেলে ভিএম এর আচরণ অপরিজ্ঞাত।
অনুযায়ী জনাথন অ্যালান অনুরোধ , আপনি পারে দেখানো opcodes পরিবর্তে opcodes আপনার নিজস্ব সেট চয়ন করুন নির্দেশাবলী অধ্যায়। যদি আপনি এটি করেন, আপনার অবশ্যই হবে তবে আপনার উত্তরে উপরে ব্যবহৃত অপকডগুলিতে একটি পূর্ণ ম্যাপিং যুক্ত ।
ম্যাপিংটি জোড়গুলির সাথে একটি হেক্স ফাইল হওয়া উচিত <official opcode> <your opcode>
, উদাহরণস্বরূপ যদি আপনি দুটি অপকড প্রতিস্থাপন করেন:
f4 f5
10 11
নিউলাইনগুলি এখানে কিছু যায় আসে না।
পরীক্ষার কেস (অফিসিয়াল অপকডস)
// some increments and decrements
pc: 0
ram: 10 10 7a 01 c9 f4 fb
output: 10 20 7a 01 c9 f4 fb
// a 16bit addition
pc: 4
ram: e0 08 2a 02 02 00 6a 02 0a 00 02 01 6a 03 0a 01
output: 0a 0b 2a 02 02 00 6a 02 0a 00 02 01 6a 03 0a 01
// a 16bit multiplication
pc: 4
ram: 5e 01 28 00 10 10 4a 01 5a 00 fc 0d 02 02 d1 6a 21 0a 21 02 03 6a 22 0a 22 52
02 62 03 c9 f8 e6 c0 00 00
output: 00 00 00 00 10 10 4a 01 5a 00 fc 0d 02 02 d1 6a 21 0a 21 02 03 6a 22 0a 22 52
02 62 03 c9 f8 e6 c0 b0 36
আমি পরে আরও টেস্টকেস যুক্ত করতে পারি।
রেফারেন্স এবং পরীক্ষা
নিজস্ব পরীক্ষা-নিরীক্ষার সাহায্যে, এখানে কিছু (সম্পূর্ণরূপে গল্ফ করা হয়নি) রেফারেন্স বাস্তবায়ন রয়েছে - এটি stderr
চলমান চলাকালীন ট্রেসিং তথ্য (বিচ্ছিন্ন নির্দেশাবলী সহ) আউটপুট এবং অপকডগুলিকে রূপান্তর করতে পারে ।
উত্সটি পাওয়ার প্রস্তাবিত উপায়:
git clone https://github.com/zirias/gvm --branch challenge --single-branch --recurse-submodules
বা চেকআউট শাখা challenge
এবং একটি কgit submodule update --init --recursive
আমার কাস্টম বিল্ড সিস্টেমটি পেতে ক্লোনিংয়ের পরে ।
জিএনইউ মেক দিয়ে সরঞ্জামটি তৈরি করুন (কেবল টাইপ করুন make
, বা gmake
আপনার সিস্টেমে থাকলে ডিফল্ট মেক GNU মেক হয় না)।
ব্যবহার :gvm [-s startpc] [-h] [-t] [-c convfile] [-d] [-x] <initial_ram
-s startpc
- প্রাথমিক প্রোগ্রাম কাউন্টার, ডিফল্ট0
-h
- ইনপুট হেক্সে রয়েছে (অন্যথায় বাইনারি)-t
- মৃত্যুদন্ড কার্যকর করতেstderr
-c convfile
- দেওয়া ম্যাপিং অনুসারে ওপকোডগুলি রূপান্তর করুনconvfile
-d
- বাইনারি তথ্য হিসাবে ফলস্বরূপ মেমরি ডাম্প-x
- হেমস হিসাবে ফলস্বরূপ মেমরি ডাম্পinitial_ram
- প্রাথমিক র্যামের সামগ্রীগুলি হেক্স বা বাইনারি হয়
নোট করুন রূপান্তর বৈশিষ্ট্যটি চলমান সময় অপকডগুলিকে সংশোধনকারী প্রোগ্রামগুলিতে ব্যর্থ হবে।
দাবি অস্বীকার: উপরোক্ত নিয়ম এবং চশমা এই চ্যালেঞ্জটির পক্ষে রচয়িতা, এই সরঞ্জামটি নয়। এটি বিশেষত ওপকোড রূপান্তর বৈশিষ্ট্যের জন্য প্রযোজ্য। আপনি যদি মনে করেন যে এখানে উপস্থাপিত সরঞ্জামটির মধ্যে একটি বাগ চিকিত্সা রয়েছে তবে দয়া করে একটি মন্তব্যে রিপোর্ট করুন :)
BRA
("শাখা সর্বদা") নিয়ন্ত্রণ প্রবাহে কোনও শাখা প্রবর্তন না করে, তাকে বলা উচিত নয় JMP
?
BRA
পরে চিপ ডিজাইনে ( 50৫০২ এর মতো নির্দেশ নেই) 65C02 এবং এমসির 68000 এর মতো JMP
বিদ্যমান রয়েছে well পার্থক্যটি হ'ল BRA
আপেক্ষিক ঠিকানা JMP
ব্যবহার করে এবং নিখুঁত ঠিকানা ব্যবহার করে। সুতরাং, আমি কেবল এই নকশাগুলি অনুসরণ করেছি - সত্যই, এটি সমস্ত যৌক্তিক মনে হয় না;)