Skip to content

Instantly share code, notes, and snippets.

@hangingman
Last active February 23, 2023 04:21
Show Gist options
  • Save hangingman/b1fa7598976e753d59e24599040903dc to your computer and use it in GitHub Desktop.
Save hangingman/b1fa7598976e753d59e24599040903dc to your computer and use it in GitHub Desktop.
Pass1 Assembly
graph TB
    Pass1-->InitLC["LC := 0"]
    InitLC-->ReadToken["字句読み取り"]
    ReadToken-->SearchPseudoOpTable["疑似命令を検索"]
    SearchPseudoOpTable-->IsPsedoOp{"疑似命令か?"}
	  IsPsedoOp--No-->SearchMachineOpTable["オペコードを検索"]
	  SearchMachineOpTable-->SetL["L := 機械語のサイズ"]
	  SetL-->ProcessLit["リテラルテーブルを処理"]

    IsPsedoOp--Yes-->WhichOne["疑似命令処理へ"]
	  WhichOne--DS/DC/DB/DW/DD-->AdjLC["LCを正しいサイズに調整"]
	  AdjLC-->SetLWithDT["L := データフィールドのサイズ"]
	  SetLWithDT-->IsThereLabel

    WhichOne--EQ/EQU-->EvalOp["オペランドを評価"]
	  EvalOp-->UpdSym["シンボルテーブルのラベルのレコードに値を設定"]
	  UpdSym-->ReadToken
	  
	  WhichOne--START/ORG-->ChgLC["LCを変更"]
	  ChgLC-->ReadToken
	  
	  WhichOne--END-->EvalEnd["リテラルを処理"]
	  EvalEnd-->RewindAndNext["構文解析してるならばASTを巻き戻してPass2へ"]
	  RewindAndNext-->Complete(("完了"))

	  ProcessLit-->IsThereLabel{"ラベルが存在するか?"}
	  IsThereLabel--No-->IncLC["LC := LC + L"]
	  IsThereLabel--Yes-->UpdLC["シンボルテーブルのラベルのレコードに現在のLCを設定"]
	  UpdLC-->IncLC
	  
	  IncLC-->ReadToken
Loading
@hangingman
Copy link
Author

hangingman commented Feb 13, 2023

この辺も参考になる
https://studylib.net/doc/9675898/ppt
https://studylib.net/doc/7872280/notes-%232---assemblers
https://slideplayer.com/slide/5898467/
http://osnet.cs.nchu.edu.tw/powpoint/MASM_SP_962/SystemSoftware/Chapter2.pdf


Loc/Block

  • Locはバイト数で数える
  • Locは全体的に+3ずつ増加
    • なぜ3固定なのか、アセンブラはSICという仮想アセンブラ。x86だと可変な気がするがどうだろう。
    • Instruction Lengthが3なので、それをちゃんと合わせないと
  • Blockとはなにか
    • Blockは通常のC言語での { ... } のようなものでnaskには不要
    • BlockごとにAddressを管理することで別処理を作ることができる(難しい)

image
image

@hangingman
Copy link
Author

hangingman commented Feb 20, 2023

symbol tableにアドレスを入れるタイミングとその処理

  • (1) entry: のようなラベルがあった場合
  • (2) JMP entry のようにforward referenceしている場合
    • Two Pass Assemblers Tutorial
    • 最初は先にあるラベルのアドレスは不明なので、アドレスは空白でシンボルテーブルに入れる

残った問題

アセンブラの実装において
JMP entry
のようなラベルジャンプの構文があったとする、このときアセンブラの内部実装にてLOCをinstructionのsizeで更新しなければなりません

しかし、JMP命令は
JMP rel8
JMP rel32
の2種類の可能性があり、

  • rel8の場合instructionのsizeは合計2
  • rel32の場合instructionのsizeは合計5

アセンブラを構文解析した時点ではJMPが0xEBなのか0xE9なのか指定はありません
これをどのように判定すべきか?

結論

  • pass1, pass2でlocの計算が異なることはあるものだと割り切る
  • pass1ではJMPのオペコードは0xEB, 0xE9どちらになるかは判定しない
  • pass1では仮に0xEBとしておき、-127 <= symbol_table["entry"]に格納した値 <= 127 であれば0xEB、そうでなければ0xE9であると判定するようにする

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment