Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
47. オペコードなどについて考察する
  • Loading branch information
sozysozbot committed Dec 9, 2017
1 parent 8312027 commit 9c38426
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 15 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -4,3 +4,5 @@ main-c
main-hs
*.hi
*.o
ladirvirelyl-hs
xarzniar-hs
30 changes: 30 additions & 0 deletions assembler/CommonIO.hs
@@ -0,0 +1,30 @@
{-# OPTIONS -Wall -fno-warn-unused-do-bind #-}
module CommonIO
(semicolonExtension
,parse'
,(>>>=)
) where
import System.IO
--import System.Environment(getArgs)
--import Control.Monad
--import Data.List

import Parse
--import Execute
--import Linker
import Messages
import Types


semicolonExtension :: String -> String
semicolonExtension = unlines . map (takeWhile (/=';')) . lines

parse' :: FilePath -> IO ()
parse' filepath = do
str <- semicolonExtension <$> readFile filepath
putStrLn' English $ NormalMessage $ "\nparsing " ++ filepath ++ ":\n"
fullParse' str >>>= print

(>>>=) :: (Message a) => Either a b -> (b -> IO ()) -> IO ()
Right b >>>= action = action b
Left a >>>= _ = hPutStrLn stderr (show' English a)
3 changes: 2 additions & 1 deletion assembler/Makefile
@@ -1,7 +1,8 @@
.PHONY: c haskell

haskell:
ghc main.hs -o main-hs -Wall
ghc xarzniar.hs -o xarzniar-hs -Wall
ghc ladirvirelyl.hs -o ladirvirelyl-hs -Wall

c:
gcc main.c parse.c -o main-c
28 changes: 28 additions & 0 deletions assembler/ladirvirelyl.hs
@@ -0,0 +1,28 @@
{-# OPTIONS -Wall -fno-warn-unused-do-bind #-}
-- import System.IO
import System.Environment(getArgs)
import Control.Monad
import Data.List

-- import Parse
-- import Execute
-- import Linker
import Messages
import Types
import CommonIO


main :: IO ()
main = do
args <- getArgs
main'' args

main'' :: [FilePath] -> IO ()
main'' paths = do
mapM_ parse' paths
strs <- forM paths (fmap semicolonExtension . readFile)
putStrLn' English $ NormalMessage $ "\ncompiling " ++ intercalate ", " paths ++ ":\n"
fullCompile' strs

fullCompile' :: [String] -> IO ()
fullCompile' strs = undefined
20 changes: 6 additions & 14 deletions assembler/main.hs → assembler/xarzniar.hs
Expand Up @@ -9,13 +9,12 @@ import Execute
import Linker
import Messages
import Types
import CommonIO

semicolonExtension :: String -> String
semicolonExtension = unlines . map (takeWhile (/=';')) . lines

{-
fullExecute :: String -> IO ()
fullExecute = fullExecute' . return

-}
fullExecute' :: [String] -> IO ()
fullExecute' strs = strs `getProgramAndApply` \program ->
let (boolerh, logs) = execute program in do
Expand All @@ -26,9 +25,7 @@ fullExecute' strs = strs `getProgramAndApply` \program ->
getProgramAndApply :: [String] -> (Program -> IO ()) -> IO ()
strs `getProgramAndApply` f = mapM fullParse' strs >>>= \ps -> linker ps >>>= f

(>>>=) :: (Message a) => Either a b -> (b -> IO ()) -> IO ()
Right b >>>= action = action b
Left a >>>= _ = hPutStrLn stderr (show' English a)


main :: IO ()
main = do
Expand Down Expand Up @@ -66,15 +63,10 @@ main'' paths = do
strs <- forM paths (fmap semicolonExtension . readFile)
putStrLn' English $ NormalMessage $ "\nrunning " ++ intercalate ", " paths ++ ":\n"
fullExecute' strs

{-
main' :: FilePath -> IO ()
main' filepath = main'' [filepath]

parse' :: FilePath -> IO ()
parse' filepath = do
str <- semicolonExtension <$> readFile filepath
putStrLn' English $ NormalMessage $ "\nparsing " ++ filepath ++ ":\n"
fullParse' str >>>= print
-}


demo :: IO ()
Expand Down
111 changes: 111 additions & 0 deletions opcode.html
Expand Up @@ -1832,6 +1832,117 @@ <h2 id="i46">46. エントリーポイント</h2>

<p>よさそう。</p>

<h2 id="i47">47. オペコードなどについて考察する</h2>
<p>そろそろオペコードやっていきましょうか。</p>
<p>「データへのアクセスは32bit固定長なのになんで命令は8bit単位なのか」などという突っ込みどころが存在するが、まあ気にせずやっていきましょう。</p>
<p>とりあえず、前に炭酸ソーダさんが作ってくださった<a href="https://app.simplenote.com/publish/GW9zdn"></a>を見てみよう。</p>
<pre>
8ビットを基本とした可変長セット
回路設計が簡単になるように考慮
'i'c順を基にする

命令の構成
00oooooo 命令 o:OPCODE
rrrmmmmm 1つめのオペランド。MODEがimmの場合REGは無視される。r:REG m:MODE
(imm/disp)
rrrmmmmm 2つめのオペランド
(imm/disp)
(rrrmmmmm 3つめのオペランド)
(imm/disp)

OPCODE
0xxxxx: オペランド2つの命令
000000: ata +
000001: nta -
000010: ada &amp;
000011: ekc |
000100: dto >>>
000101: dro <<
000110: dtosna >>
000111: dal ~^
001000: krz =
001001: malkrz
01cccc: fi
10xxxx: オペランド3つの命令
100000: inj
101000: lat
101001: latsna

COND
0000 llonys >
0001 xtlonys <=
0010 xolonys >=
0011 xylonys <
0110 clo ==
0111 niv !=
1000 llo >
1001 xtlo <=
1010 xolo >=
1011 xylo <
比較は 右の値 + (-左の値) で行う。順番が逆なのはntaに合わせるため
上記ビットをscznに割り当てる
Z: 加算の結果が0かどうか
C: 加算で最上位ビットで繰り上がりが起きて捨てられたか
判定は、((z AND Z) OR NOT(c OR C)) XOR n で決定する
sが1の場合は比較処理の前に両方の値の最上位ビットを反転さそる

REG
000: f0
001: f1
010: f2
011: f3
101: f5
111: xx

MODE
00000: reg
00100: imm8
00101: imm16
00110: imm32
10000: reg@
10100: reg+disp8@
10101: reg+disp16@
10110: reg+disp32@
11rrr: reg+reg@ r:2つめのreg
immかdispを含むとき、その値を表す8/16/32ビットの値が後続する。
imm8/16は符号無し、disp8/16符号あり(C0ならFFFFFFC0として扱う)


'c'i
nll fib1
krz f0 f5+ 4@
krz f1 0
krz f2 1
fi f0 0 clo l' is malkrz xx ka
nta f0 1
krz f3 f1
ata f3 f2
inj f1 f2 f3
krz xx is
krz f0 f1 l' ka
krz xx f5@

1482E8D4: 08 B4 04 00
1482E8D8: 08 04 00 20
1482E8DC: 08 04 01 40
1482E8E0: 16 00 04 00
1482E8E4: 09 06 14 82 E8 FC E0
1482E8EB: 01 04 01 00
1482E8EF: 08 20 60
1482E8F2: 00 40 60
1482E8F5: 20 60 40 20
1482E8F5: 08 06 14 82 E8 E0 E0
1482E8FC: 08 20 00
1482E8FF: 08 B0 E0
</pre>
<p>とのこと。</p>
<p>よさそう(よさそう)</p>
<p>とりあえずアセンブラでも考えてみるか?Haskellに触れるのは大分久しぶりだな。</p>
<p>インタプリタの方をxarzniarと改名し、ladirvirelyl.hsというファイルを新たに作成。</p>
<p>共通化できそうな処理はCommonIO.hsとして分離し、とりあえず形式だけ合わせたダミーを作成。</p>
<p>さて、まともなコンパイラとリンカを作らねばなぁ。nヶ月前に書いたコードだからどういう構成になってるのかも読み返さねばだし。</p>

<hr>
<h2>xxx. To do</h2>
<h3>xxx-1. 割り算</h3>
Expand Down

0 comments on commit 9c38426

Please sign in to comment.