From 67dac668e3b0aa09efc38e8646c4d4233b764488 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Fri, 16 Aug 2019 14:08:40 -0700 Subject: sketch of a plan to implement indirect mode --- apps/desugar | Bin 36392 -> 36433 bytes apps/desugar.subx | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/apps/desugar b/apps/desugar index bc5c5c5f..7fb466f7 100755 Binary files a/apps/desugar and b/apps/desugar differ diff --git a/apps/desugar.subx b/apps/desugar.subx index a8ffefb9..6b602015 100644 --- a/apps/desugar.subx +++ b/apps/desugar.subx @@ -65,6 +65,8 @@ $main:end: b8/copy-to-EAX 1/imm32/exit cd/syscall 0x80/imm8 +# error messages considered: +# *x + 34 -> error: base+disp addressing must be within '()' convert: # in : (address buffered-file), out : (address buffered-file) -> # pseudocode: # var line = new-stream(512, 1) @@ -73,7 +75,7 @@ convert: # in : (address buffered-file), out : (address buffered-file) -> write == 0) break # end of file # while true - # var word-slice = next-word(line) + # var word-slice = next-word-or-expression(line) # if slice-empty?(word-slice) # end of line # break # if slice-starts-with?(word-slice, "#") # comment @@ -81,7 +83,10 @@ convert: # in : (address buffered-file), out : (address buffered-file) -> error: no space after '*' +# *(... -> error: *(...) expression must be all on a single line +next-word-or-expression: # line : (address stream byte), out : (address slice) + # . prolog + 55/push-EBP + 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP + # . save registers +$next-word-or-expression:end: + # . restore registers + # . epilog + 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP + 5d/pop-to-EBP + c3/return + +# Grammar: +# *reg -> 0/mod reg/rm32 +# *(reg) -> 0/mod reg/rm32 +# *(reg+disp) -> 2/mod reg/rm32 +# *(reg1+reg2< 2/mod 4/rm32 reg1/base reg2/index s/scale 0/disp32 +# *(reg1+reg2< 2/mod 4/rm32 reg1/base reg2/index s/scale disp/disp32 +# Intermediate structure: base, index, scale, disp +# Default values: base: 0, index: 4 (none), scale: 0, disp: 0 # beware: modifies 'word' +parse-effective-address: # word : (address slice) -> base/EAX, index/ECX, scale/EDX, disp/EBX + # . prolog + 55/push-EBP + 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP + # . save registers + 56/push-ESI + # ESI = word + 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 0/r32/EAX 8/disp8 . # copy *(EBP+8) to ESI + # ++word->start + ff 0/subop/increment 0/mod/indirect 0/rm32/EAX . . . . . . # increment *ESI + # initialize defaults + b8/copy-to-EAX 0/imm32 + b9/copy-to-ECX 4/imm32/no-index + ba/copy-to-EDX 0/imm32/.scale + bb/copy-to-EBX 0/imm32/disp +$parse-effective-address:end: + # . restore registers + 5e/pop-to-ESI + # . epilog + 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP + 5d/pop-to-EBP + c3/return + +# Code generation: +# if index is none and disp is 0, then mod = 0 and rm32 = base +# if index is none, then mod = 2 and rm32 = base and disp32 = disp +# if index is not none, then mod = 2 and rm32 = 4 and base = base and index = index and disp32 = disp emit-indirect-mode: # word : (address slice), out : (address buffered-file) # . prolog 55/push-EBP -- cgit 1.4.1-2-gfad0