about summary refs log tree commit diff stats
path: root/apps/advent2020
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-12-04 22:27:12 -0800
committerKartik Agaram <vc@akkartik.com>2020-12-04 23:02:53 -0800
commiteea6659a40b48e23cb660276248c7310ab879613 (patch)
treeb7ff986d51bd035283b9699fa6820ad7156b486e /apps/advent2020
parent273c42c06698f3e010739923714feba780a4c9cf (diff)
downloadmu-eea6659a40b48e23cb660276248c7310ab879613.tar.gz
7331 - hacky way to convert slice to string
Diffstat (limited to 'apps/advent2020')
-rw-r--r--apps/advent2020/4b.mu20
1 files changed, 20 insertions, 0 deletions
diff --git a/apps/advent2020/4b.mu b/apps/advent2020/4b.mu
index d4a3496e..ffeddb32 100644
--- a/apps/advent2020/4b.mu
+++ b/apps/advent2020/4b.mu
@@ -157,6 +157,26 @@ fn main -> _/ebx: int {
         var pid?/eax: boolean <- slice-equal? key-slice, "pid"
         compare pid?, 0  # false
         break-if-=
+        # convert val
+        var s: (handle array byte)
+        var s2: (addr handle array byte) <- address s
+        _slice-to-string val-slice, s2
+        # check length
+        var len/eax: int <- length s2
+        compare len, 9
+        {
+          break-if-=
+          curr-passport-field-count <- copy 8
+        }
+        # check valid decimal int
+        # parse-decimal-int-from-slice currently returns 0 on invalid parse,
+        # which isn't ideal but suffices for our purposes
+        var val/eax: int <- parse-decimal-int-from-slice val-slice
+        compare val, 0
+        {
+          break-if->
+          curr-passport-field-count <- copy 8
+        }
       }
       loop
     }
und-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
Opcodes currently supported by SubX:
  01: add r32 to rm32 (add)
  03: add rm32 to r32 (add)
  05: add imm32 to EAX (add)
  09: rm32 = bitwise OR of r32 with rm32 (or)
  0b: r32 = bitwise OR of r32 with rm32 (or)
  0d: EAX = bitwise OR of imm32 with EAX (or)
  21: rm32 = bitwise AND of r32 with rm32 (and)
  23: r32 = bitwise AND of r32 with rm32 (and)
  25: EAX = bitwise AND of imm32 with EAX (and)
  29: subtract r32 from rm32 (sub)
  2b: subtract rm32 from r32 (sub)
  2d: subtract imm32 from EAX (sub)
  31: rm32 = bitwise XOR of r32 with rm32 (xor)
  33: r32 = bitwise XOR of r32 with rm32 (xor)
  35: EAX = bitwise XOR of imm32 with EAX (xor)
  39: compare: set SF if rm32 < r32 (cmp)
  3b: compare: set SF if r32 < rm32 (cmp)
  3d: compare: set SF if EAX < imm32 (cmp)
  40: increment EAX (inc)
  41: increment ECX (inc)
  42: increment EDX (inc)
  43: increment EBX (inc)
  44: increment ESP (inc)
  45: increment EBP (inc)
  46: increment ESI (inc)
  47: increment EDI (inc)
  48: decrement EAX (dec)
  49: decrement ECX (dec)
  4a: decrement EDX (dec)
  4b: decrement EBX (dec)
  4c: decrement ESP (dec)
  4d: decrement EBP (dec)
  4e: decrement ESI (dec)
  4f: decrement EDI (dec)
  50: push EAX to stack (push)
  51: push ECX to stack (push)
  52: push EDX to stack (push)
  53: push EBX to stack (push)
  54: push ESP to stack (push)
  55: push EBP to stack (push)
  56: push ESI to stack (push)
  57: push EDI to stack (push)
  58: pop top of stack to EAX (pop)
  59: pop top of stack to ECX (pop)
  5a: pop top of stack to EDX (pop)
  5b: pop top of stack to EBX (pop)
  5c: pop top of stack to ESP (pop)
  5d: pop top of stack to EBP (pop)
  5e: pop top of stack to ESI (pop)
  5f: pop top of stack to EDI (pop)
  68: push imm32 to stack (push)
  69: multiply rm32 by imm32 and store result in r32 (imul)
  70: jump disp8 bytes away if OF is set (jcc/jo)
  71: jump disp8 bytes away if OF is unset (jcc/jno)
  72: jump disp8 bytes away if lesser (addr, float), if CF is set (jcc/jb/jnae)
  73: jump disp8 bytes away if greater or equal (addr, float), if CF is unset (jcc/jae/jnb)
  74: jump disp8 bytes away if equal, if ZF is set (jcc/jz/je)
  75: jump disp8 bytes away if not equal, if ZF is not set (jcc/jnz/jne)
  76: jump disp8 bytes away if lesser or equal (addr, float), if ZF is set or CF is set (jcc/jbe/jna)
  77: jump disp8 bytes away if greater (addr, float), if ZF is unset and CF is unset (jcc/ja/jnbe)
  7c: jump disp8 bytes away if lesser, if SF != OF (jcc/jl/jnge)
  7d: jump disp8 bytes away if greater or equal, if SF == OF (jcc/jge/jnl)
  7e: jump disp8 bytes away if lesser or equal, if ZF is set or SF != OF (jcc/jle/jng)
  7f: jump disp8 bytes away if greater, if ZF is unset and SF == OF (jcc/jg/jnle)
  81: combine rm32 with imm32 based on subop (add/sub/and/or/xor/cmp)
  87: swap the contents of r32 and rm32 (xchg)
  88: copy r8 to r8/m8-at-r32
  89: copy r32 to rm32 (mov)
  8a: copy r8/m8-at-r32 to r8
  8b: copy rm32 to r32 (mov)
  8d: copy address in rm32 into r32 (lea)
  8f: pop top of stack to rm32 (pop)
  99: sign-extend EAX into EDX (cdq)
  b8: copy imm32 to EAX (mov)
  b9: copy imm32 to ECX (mov)
  ba: copy imm32 to EDX (mov)
  bb: copy imm32 to EBX (mov)
  bc: copy imm32 to ESP (mov)
  bd: copy imm32 to EBP (mov)
  be: copy imm32 to ESI (mov)
  bf: copy imm32 to EDI (mov)
  c1: shift rm32 by imm8 bits depending on subop (sal/sar/shl/shr)
  c3: return from most recent unfinished call (ret)
  c6: copy imm8 to r8/m8-at-r32 with subop 0 (mov)
  c7: copy imm32 to rm32 with subop 0 (mov)
  cd: software interrupt (int)
  d3: shift rm32 by CL bits depending on subop (sal/sar/shl/shr)
  e8: call disp32 (call)
  e9: jump disp32 bytes away (jmp)
  eb: jump disp8 bytes away (jmp)
  f4: halt (hlt)
  f7: negate/multiply/divide rm32 (with EAX and EDX if necessary) depending on subop (neg/mul/idiv)
  ff: increment/decrement/jump/push/call rm32 based on subop (inc/dec/jmp/push/call)
  0f 2f: compare: set CF if x32 < xm32 (comiss)
  0f 80: jump disp32 bytes away if OF is set (jcc/jo)
  0f 81: jump disp32 bytes away if OF is unset (jcc/jno)
  0f 82: jump disp32 bytes away if lesser (addr, float), if CF is set (jcc/jb/jnae)
  0f 83: jump disp32 bytes away if greater or equal (addr, float), if CF is unset (jcc/jae/jnb)
  0f 84: jump disp32 bytes away if equal, if ZF is set (jcc/jz/je)
  0f 85: jump disp32 bytes away if not equal, if ZF is not set (jcc/jnz/jne)
  0f 86: jump disp32 bytes away if lesser or equal (addr, float), if ZF is set or CF is set (jcc/jbe/jna)
  0f 87: jump disp32 bytes away if greater (addr, float), if ZF is unset and CF is unset (jcc/ja/jnbe)
  0f 8c: jump disp32 bytes away if lesser, if SF != OF (jcc/jl/jnge)
  0f 8d: jump disp32 bytes away if greater or equal, if SF == OF (jcc/jge/jnl)
  0f 8e: jump disp32 bytes away if lesser or equal, if ZF is set or SF != OF (jcc/jle/jng)
  0f 8f: jump disp32 bytes away if greater, if ZF is unset and SF == OF (jcc/jg/jnle)
  0f 92: set r8/m8-at-rm32 to 1 if lesser (addr, float), if CF is set, 0 otherwise (setcc/setb/setnae)
  0f 93: set r8/m8-at-rm32 to 1 if greater or equal (addr, float), if CF is unset, 0 otherwise (setcc/setae/setnb)
  0f 94: set r8/m8-at-rm32 to 1 if equal, if ZF is set, 0 otherwise (setcc/setz/sete)
  0f 95: set r8/m8-at-rm32 to 1 if not equal, if ZF is not set, 0 otherwise (setcc/setnz/setne)
  0f 96: set r8/m8-at-rm32 to 1 if lesser or equal (addr, float), if ZF is set or CF is set, 0 otherwise (setcc/setbe/setna)
  0f 97: set r8/m8-at-rm32 to 1 if greater (addr, float), if ZF is unset and CF is unset, 0 otherwise (setcc/seta/setnbe)
  0f 9c: set r8/m8-at-rm32 to 1 if lesser, if SF != OF, 0 otherwise (setcc/setl/setnge)
  0f 9d: set r8/m8-at-rm32 to 1 if greater or equal, if SF == OF, 0 otherwise (setcc/setge/setnl)
  0f 9e: set r8/m8-at-rm32 to 1 if lesser or equal, if ZF is set or SF != OF, 0 otherwise (setcc/setle/setng)
  0f 9f: set r8/m8-at-rm32 to 1 if greater, if ZF is unset and SF == OF, 0 otherwise (setcc/setg/setnle)
  0f af: multiply rm32 into r32 (imul)
  f3 0f 10: copy xm32 to x32 (movss)
  f3 0f 11: copy x32 to xm32 (movss)
  f3 0f 2a: convert integer to floating-point (cvtsi2ss)
  f3 0f 2c: truncate floating-point to int (cvttss2si)
  f3 0f 2d: convert floating-point to int (cvtss2si)
  f3 0f 51: square root of float (sqrtss)
  f3 0f 52: inverse square root of float (rsqrtss)
  f3 0f 53: reciprocal of float (rcpss)
  f3 0f 58: add floats (addss)
  f3 0f 59: multiply floats (mulss)
  f3 0f 5c: subtract floats (subss)
  f3 0f 5d: minimum of two floats (minss)
  f3 0f 5e: divide floats (divss)
  f3 0f 5f: maximum of two floats (maxss)
Run `bootstrap help instructions` for details on words like 'r32' and 'disp8'.
For complete details on these instructions, consult the IA-32 manual (volume 2).
There's various versions of it online, such as https://c9x.me/x86.
The mnemonics in brackets will help you locate each instruction.