summary refs log tree commit diff stats
path: root/compiler/trees.nim
blob: c878eb1bf7613b317ef904d30d523f5e69ddb7d1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#
#
#           The Nim Compiler
#        (c) Copyright 2012 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

# tree helper routines

import
  ast, astalgo, lexer, msgs, strutils, wordrecg, idents

proc cyclicTreeAux(n: PNode, visited: var seq[PNode]): bool =
  if n == nil: return
  for v in visited:
    if v == n: return true
  if not (n.kind in {nkEmpty..nkNilLit}):
    visited.add(n)
    for nSon in n.sons:
      if cyclicTreeAux(nSon, visited): return true
    discard visited.pop()

proc cyclicTree*(n: PNode): bool =
  var visited: seq[PNode] = @[]
  cyclicTreeAux(n, visited)

proc exprStructuralEquivalent*(a, b: PNode; strictSymEquality=false): bool =
  if a == b:
    result = true
  elif (a != nil) and (b != nil) and (a.kind == b.kind):
    case a.kind
    of nkSym:
      if strictSymEquality:
        result = a.sym == b.sym
      else:
        # don't go nuts here: same symbol as string is enough:
        result = a.sym.name.id == b.sym.name.id
    of nkIdent: result = a.ident.id == b.ident.id
    of nkCharLit..nkUInt64Lit: result = a.intVal == b.intVal
    of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal
    of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
    of nkCommentStmt: result = a.comment == b.comment
    of nkEmpty, nkNilLit, nkType: result = true
    else:
      if sonsLen(a) == sonsLen(b):
        for i in 0 ..< sonsLen(a):
          if not exprStructuralEquivalent(a.sons[i], b.sons[i],
                                          strictSymEquality): return
        result = true

proc sameTree*(a, b: PNode): bool =
  if a == b:
    result = true
  elif a != nil and b != nil and a.kind == b.kind:
    if a.flags != b.flags: return
    if a.info.line != b.info.line: return
    if a.info.col != b.info.col:
      return                  #if a.info.fileIndex <> b.info.fileIndex then exit;
    case a.kind
    of nkSym:
      # don't go nuts here: same symbol as string is enough:
      result = a.sym.name.id == b.sym.name.id
    of nkIdent: result = a.ident.id == b.ident.id
    of nkCharLit..nkUInt64Lit: result = a.intVal == b.intVal
    of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal
    of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
    of nkEmpty, nkNilLit, nkType: result = true
    else:
      if sonsLen(a) == sonsLen(b):
        for i in 0 ..< sonsLen(a):
          if not sameTree(a.sons[i], b.sons[i]): return
        result = true

proc getMagic*(op: PNode): TMagic =
  case op.kind
  of nkCallKinds:
    case op.sons[0].kind
    of nkSym: result = op.sons[0].sym.magic
    else: result = mNone
  else: result = mNone

proc isConstExpr*(n: PNode): bool =
  const atomKinds = {nkCharLit..nkNilLit} # Char, Int, UInt, Str, Float and Nil literals
  n.kind in atomKinds or nfAllConst in n.flags

proc isCaseObj*(n: PNode): bool =
  if n.kind == nkRecCase: return true
  for i in 0..<safeLen(n):
    if n[i].isCaseObj: return true

proc isDeepConstExpr*(n: PNode): bool =
  case n.kind
  of nkCharLit..nkNilLit:
    result = true
  of nkExprEqExpr, nkExprColonExpr, nkHiddenStdConv, nkHiddenSubConv:
    result = isDeepConstExpr(n.sons[1])
  of nkCurly, nkBracket, nkPar, nkTupleConstr, nkObjConstr, nkClosure, nkRange:
    for i in ord(n.kind == nkObjConstr) ..< n.len:
      if not isDeepConstExpr(n.sons[i]): return false
    if n.typ.isNil: result = true
    else:
      let t = n.typ.skipTypes({tyGenericInst, tyDistinct, tyAlias, tySink, tyOwned})
      if t.kind in {tyRef, tyPtr}: return false
      if t.kind != tyObject or not isCaseObj(t.n):
        result = true
  else: discard

proc isRange*(n: PNode): bool {.inline.} =
  if n.kind in nkCallKinds:
    let callee = n[0]
    if (callee.kind == nkIdent and callee.ident.id == ord(wDotDot)) or
       (callee.kind == nkSym and callee.sym.name.id == ord(wDotDot)) or
       (callee.kind in {nkClosedSymChoice, nkOpenSymChoice} and
        callee[1].sym.name.id == ord(wDotDot)):
      result = true

proc whichPragma*(n: PNode): TSpecialWord =
  let key = if n.kind in nkPragmaCallKinds and n.len > 0: n.sons[0] else: n
  if key.kind == nkIdent: result = whichKeyword(key.ident)

proc findPragma*(n: PNode, which: TSpecialWord): PNode =
  if n.kind == nkPragma:
    for son in n:
      if whichPragma(son) == which:
        return son

proc effectSpec*(n: PNode, effectType: TSpecialWord): PNode =
  for i in 0 ..< sonsLen(n):
    var it = n.sons[i]
    if it.kind == nkExprColonExpr and whichPragma(it) == effectType:
      result = it.sons[1]
      if result.kind notin {nkCurly, nkBracket}:
        result = newNodeI(nkCurly, result.info)
        result.add(it.sons[1])
      return

proc unnestStmts(n, result: PNode) =
  if n.kind == nkStmtList:
    for x in items(n): unnestStmts(x, result)
  elif n.kind notin {nkCommentStmt, nkNilLit}:
    result.add(n)

proc flattenStmts*(n: PNode): PNode =
  result = newNodeI(nkStmtList, n.info)
  unnestStmts(n, result)
  if result.len == 1:
    result = result.sons[0]

proc extractRange*(k: TNodeKind, n: PNode, a, b: int): PNode =
  result = newNodeI(k, n.info, b-a+1)
  for i in 0 .. b-a: result.sons[i] = n.sons[i+a]
bxComment"># AL = convert upper nibble to hex</span> <span id="L28" class="LineNr"> 28 </span> 8b/copy 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0/r32/eax 0xc/disp8 <span class="Normal"> . </span> <span class="subxComment"># copy *(ebp+12) to eax</span> <span id="L29" class="LineNr"> 29 </span> c1/shift 5/subop/logic-right 3/mod/direct 0/rm32/eax <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm8 <span class="subxComment"># shift eax right by 4 bits, while padding zeroes</span> <span id="L30" class="LineNr"> 30 </span> 25/and-eax 0xf/imm32 <span id="L31" class="LineNr"> 31 </span> <span class="subxS1Comment"># . AL = to-hex-char(AL)</span> <span id="L32" class="LineNr"> 32 </span> e8/call <a href='117write-int-hex.subx.html#L9'>to-hex-char</a>/disp32 <span id="L33" class="LineNr"> 33 </span> <span class="subxComment"># append-byte(f, AL)</span> <span id="L34" class="LineNr"> 34 </span> <span class="subxS2Comment"># . . push args</span> <span id="L35" class="LineNr"> 35 </span> 50/push-eax <span id="L36" class="LineNr"> 36 </span> ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/disp8 <span class="Normal"> . </span> <span class="subxComment"># push *(ebp+8)</span> <span id="L37" class="LineNr"> 37 </span> <span class="subxS2Comment"># . . call</span> <span id="L38" class="LineNr"> 38 </span> e8/call <a href='115write-byte.subx.html#L208'>append-byte</a>/disp32 <span id="L39" class="LineNr"> 39 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L40" class="LineNr"> 40 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/imm32 <span class="subxComment"># add to esp</span> <span id="L41" class="LineNr"> 41 </span> <span class="subxComment"># AL = convert lower nibble to hex</span> <span id="L42" class="LineNr"> 42 </span> 8b/copy 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0/r32/eax 0xc/disp8 <span class="Normal"> . </span> <span class="subxComment"># copy *(ebp+12) to eax</span> <span id="L43" class="LineNr"> 43 </span> 25/and-eax 0xf/imm32 <span id="L44" class="LineNr"> 44 </span> <span class="subxS1Comment"># . AL = to-hex-char(AL)</span> <span id="L45" class="LineNr"> 45 </span> e8/call <a href='117write-int-hex.subx.html#L9'>to-hex-char</a>/disp32 <span id="L46" class="LineNr"> 46 </span> <span class="subxComment"># append-byte(f, AL)</span> <span id="L47" class="LineNr"> 47 </span> <span class="subxS2Comment"># . . push args</span> <span id="L48" class="LineNr"> 48 </span> 50/push-eax <span id="L49" class="LineNr"> 49 </span> ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/disp8 <span class="Normal"> . </span> <span class="subxComment"># push *(ebp+8)</span> <span id="L50" class="LineNr"> 50 </span> <span class="subxS2Comment"># . . call</span> <span id="L51" class="LineNr"> 51 </span> e8/call <a href='115write-byte.subx.html#L208'>append-byte</a>/disp32 <span id="L52" class="LineNr"> 52 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L53" class="LineNr"> 53 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/imm32 <span class="subxComment"># add to esp</span> <span id="L54" class="LineNr"> 54 </span><span class="Constant">$append-byte-hex:end</span>: <span id="L55" class="LineNr"> 55 </span> <span class="subxS1Comment"># . restore registers</span> <span id="L56" class="LineNr"> 56 </span> 58/pop-to-eax <span id="L57" class="LineNr"> 57 </span> <span class="subxS1Comment"># . epilogue</span> <span id="L58" class="LineNr"> 58 </span> 89/copy 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 5/r32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy ebp to esp</span> <span id="L59" class="LineNr"> 59 </span> 5d/pop-to-ebp <span id="L60" class="LineNr"> 60 </span> c3/return <span id="L61" class="LineNr"> 61 </span> <span id="L62" class="LineNr"> 62 </span><span class="subxTest">test-append-byte-hex</span>: <span id="L63" class="LineNr"> 63 </span> <span class="subxH1Comment"># - check that append-byte-hex adds the hex textual representation</span> <span id="L64" class="LineNr"> 64 </span> <span class="subxComment"># setup</span> <span id="L65" class="LineNr"> 65 </span> <span class="subxS1Comment"># . clear-stream(_test-stream)</span> <span id="L66" class="LineNr"> 66 </span> <span class="subxS2Comment"># . . push args</span> <span id="L67" class="LineNr"> 67 </span> 68/push <a href='108write.subx.html#L151'>_test-stream</a>/imm32 <span id="L68" class="LineNr"> 68 </span> <span class="subxS2Comment"># . . call</span> <span id="L69" class="LineNr"> 69 </span> e8/call <a href='106stream.subx.html#L17'>clear-stream</a>/disp32 <span id="L70" class="LineNr"> 70 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L71" class="LineNr"> 71 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm32 <span class="subxComment"># add to esp</span> <span id="L72" class="LineNr"> 72 </span> <span class="subxComment"># append-byte-hex(_test-stream, 0xa) # exercises digit, non-digit as well as leading zero</span> <span id="L73" class="LineNr"> 73 </span> <span class="subxS2Comment"># . . push args</span> <span id="L74" class="LineNr"> 74 </span> 68/push 0xa/imm32 <span id="L75" class="LineNr"> 75 </span> 68/push <a href='108write.subx.html#L151'>_test-stream</a>/imm32 <span id="L76" class="LineNr"> 76 </span> <span class="subxS2Comment"># . . call</span> <span id="L77" class="LineNr"> 77 </span> e8/call <a href='117write-int-hex.subx.html#L21'>append-byte-hex</a>/disp32 <span id="L78" class="LineNr"> 78 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L79" class="LineNr"> 79 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/imm32 <span class="subxComment"># add to esp</span> <span id="L80" class="LineNr"> 80 </span> <span class="subxComment"># check-stream-equal(_test-stream, &quot;0a&quot;, msg)</span> <span id="L81" class="LineNr"> 81 </span> <span class="subxS2Comment"># . . push args</span> <span id="L82" class="LineNr"> 82 </span> 68/push <span class="Constant">&quot;F - test-append-byte-hex&quot;</span>/imm32 <span id="L83" class="LineNr"> 83 </span> 68/push <span class="Constant">&quot;0a&quot;</span>/imm32 <span id="L84" class="LineNr"> 84 </span> 68/push <a href='108write.subx.html#L151'>_test-stream</a>/imm32 <span id="L85" class="LineNr"> 85 </span> <span class="subxS2Comment"># . . call</span> <span id="L86" class="LineNr"> 86 </span> e8/call <a href='109stream-equal.subx.html#L194'>check-stream-equal</a>/disp32 <span id="L87" class="LineNr"> 87 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L88" class="LineNr"> 88 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0xc/imm32 <span class="subxComment"># add to esp</span> <span id="L89" class="LineNr"> 89 </span> <span class="subxS1Comment"># . end</span> <span id="L90" class="LineNr"> 90 </span> c3/return <span id="L91" class="LineNr"> 91 </span> <span id="L92" class="LineNr"> 92 </span><span class="subxComment"># print the hex representation for the lowest byte of a number</span> <span id="L93" class="LineNr"> 93 </span><span class="subxFunction">write-byte-hex-buffered</span>: <span class="subxComment"># f: (addr buffered-file), n: int</span> <span id="L94" class="LineNr"> 94 </span> <span class="subxS1Comment"># . prologue</span> <span id="L95" class="LineNr"> 95 </span> 55/push-ebp <span id="L96" class="LineNr"> 96 </span> 89/copy 3/mod/direct 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/r32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy esp to ebp</span> <span id="L97" class="LineNr"> 97 </span> <span class="subxS1Comment"># . save registers</span> <span id="L98" class="LineNr"> 98 </span> 50/push-eax <span id="L99" class="LineNr"> 99 </span> <span class="subxComment"># AL = convert upper nibble to hex</span> <span id="L100" class="LineNr">100 </span> 8b/copy 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0/r32/eax 0xc/disp8 <span class="Normal"> . </span> <span class="subxComment"># copy *(ebp+12) to eax</span> <span id="L101" class="LineNr">101 </span> c1/shift 5/subop/logic-right 3/mod/direct 0/rm32/eax <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm8 <span class="subxComment"># shift eax right by 4 bits, while padding zeroes</span> <span id="L102" class="LineNr">102 </span> 25/and-eax 0xf/imm32 <span id="L103" class="LineNr">103 </span> <span class="subxS1Comment"># . AL = to-hex-char(AL)</span> <span id="L104" class="LineNr">104 </span> e8/call <a href='117write-int-hex.subx.html#L9'>to-hex-char</a>/disp32 <span id="L105" class="LineNr">105 </span> <span class="subxComment"># write-byte-buffered(f, AL)</span> <span id="L106" class="LineNr">106 </span> <span class="subxS2Comment"># . . push args</span> <span id="L107" class="LineNr">107 </span> 50/push-eax <span id="L108" class="LineNr">108 </span> ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/disp8 <span class="Normal"> . </span> <span class="subxComment"># push *(ebp+8)</span> <span id="L109" class="LineNr">109 </span> <span class="subxS2Comment"># . . call</span> <span id="L110" class="LineNr">110 </span> e8/call <a href='115write-byte.subx.html#L33'>write-byte-buffered</a>/disp32 <span id="L111" class="LineNr">111 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L112" class="LineNr">112 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/imm32 <span class="subxComment"># add to esp</span> <span id="L113" class="LineNr">113 </span> <span class="subxComment"># AL = convert lower nibble to hex</span> <span id="L114" class="LineNr">114 </span> 8b/copy 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0/r32/eax 0xc/disp8 <span class="Normal"> . </span> <span class="subxComment"># copy *(ebp+12) to eax</span> <span id="L115" class="LineNr">115 </span> 25/and-eax 0xf/imm32 <span id="L116" class="LineNr">116 </span> <span class="subxS1Comment"># . AL = to-hex-char(AL)</span> <span id="L117" class="LineNr">117 </span> e8/call <a href='117write-int-hex.subx.html#L9'>to-hex-char</a>/disp32 <span id="L118" class="LineNr">118 </span> <span class="subxComment"># write-byte-buffered(f, AL)</span> <span id="L119" class="LineNr">119 </span> <span class="subxS2Comment"># . . push args</span> <span id="L120" class="LineNr">120 </span> 50/push-eax <span id="L121" class="LineNr">121 </span> ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/disp8 <span class="Normal"> . </span> <span class="subxComment"># push *(ebp+8)</span> <span id="L122" class="LineNr">122 </span> <span class="subxS2Comment"># . . call</span> <span id="L123" class="LineNr">123 </span> e8/call <a href='115write-byte.subx.html#L33'>write-byte-buffered</a>/disp32 <span id="L124" class="LineNr">124 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L125" class="LineNr">125 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/imm32 <span class="subxComment"># add to esp</span> <span id="L126" class="LineNr">126 </span><span class="Constant">$write-byte-hex-buffered:end</span>: <span id="L127" class="LineNr">127 </span> <span class="subxS1Comment"># . restore registers</span> <span id="L128" class="LineNr">128 </span> 58/pop-to-eax <span id="L129" class="LineNr">129 </span> <span class="subxS1Comment"># . epilogue</span> <span id="L130" class="LineNr">130 </span> 89/copy 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 5/r32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy ebp to esp</span> <span id="L131" class="LineNr">131 </span> 5d/pop-to-ebp <span id="L132" class="LineNr">132 </span> c3/return <span id="L133" class="LineNr">133 </span> <span id="L134" class="LineNr">134 </span><span class="subxTest">test-write-byte-hex-buffered</span>: <span id="L135" class="LineNr">135 </span> <span class="subxH1Comment"># - check that write-byte-hex-buffered prints the hex textual representation</span> <span id="L136" class="LineNr">136 </span> <span class="subxComment"># setup</span> <span id="L137" class="LineNr">137 </span> <span class="subxS1Comment"># . clear-stream(_test-stream)</span> <span id="L138" class="LineNr">138 </span> <span class="subxS2Comment"># . . push args</span> <span id="L139" class="LineNr">139 </span> 68/push <a href='108write.subx.html#L151'>_test-stream</a>/imm32 <span id="L140" class="LineNr">140 </span> <span class="subxS2Comment"># . . call</span> <span id="L141" class="LineNr">141 </span> e8/call <a href='106stream.subx.html#L17'>clear-stream</a>/disp32 <span id="L142" class="LineNr">142 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L143" class="LineNr">143 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm32 <span class="subxComment"># add to esp</span> <span id="L144" class="LineNr">144 </span> <span class="subxS1Comment"># . clear-stream($_test-buffered-file-&gt;buffer)</span> <span id="L145" class="LineNr">145 </span> <span class="subxS2Comment"># . . push args</span> <span id="L146" class="LineNr">146 </span> 68/push $_test-buffered-file-&gt;buffer/imm32 <span id="L147" class="LineNr">147 </span> <span class="subxS2Comment"># . . call</span> <span id="L148" class="LineNr">148 </span> e8/call <a href='106stream.subx.html#L17'>clear-stream</a>/disp32 <span id="L149" class="LineNr">149 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L150" class="LineNr">150 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm32 <span class="subxComment"># add to esp</span> <span id="L151" class="LineNr">151 </span> <span class="subxComment"># write-byte-hex-buffered(_test-buffered-file, 0xa) # exercises digit, non-digit as well as leading zero</span> <span id="L152" class="LineNr">152 </span> <span class="subxS2Comment"># . . push args</span> <span id="L153" class="LineNr">153 </span> 68/push 0xa/imm32 <span id="L154" class="LineNr">154 </span> 68/push <a href='112read-byte.subx.html#L318'>_test-buffered-file</a>/imm32 <span id="L155" class="LineNr">155 </span> <span class="subxS2Comment"># . . call</span> <span id="L156" class="LineNr">156 </span> e8/call <a href='117write-int-hex.subx.html#L93'>write-byte-hex-buffered</a>/disp32 <span id="L157" class="LineNr">157 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L158" class="LineNr">158 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/imm32 <span class="subxComment"># add to esp</span> <span id="L159" class="LineNr">159 </span> <span class="subxComment"># flush(_test-buffered-file)</span> <span id="L160" class="LineNr">160 </span> <span class="subxS2Comment"># . . push args</span> <span id="L161" class="LineNr">161 </span> 68/push <a href='112read-byte.subx.html#L318'>_test-buffered-file</a>/imm32 <span id="L162" class="LineNr">162 </span> <span class="subxS2Comment"># . . call</span> <span id="L163" class="LineNr">163 </span> e8/call <a href='115write-byte.subx.html#L81'>flush</a>/disp32 <span id="L164" class="LineNr">164 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L165" class="LineNr">165 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm32 <span class="subxComment"># add to esp</span> <span id="L166" class="LineNr">166 </span> <span class="subxComment"># check-stream-equal(_test-stream, &quot;0a&quot;, msg)</span> <span id="L167" class="LineNr">167 </span> <span class="subxS2Comment"># . . push args</span> <span id="L168" class="LineNr">168 </span> 68/push <span class="Constant">&quot;F - test-write-byte-hex-buffered&quot;</span>/imm32 <span id="L169" class="LineNr">169 </span> 68/push <span class="Constant">&quot;0a&quot;</span>/imm32 <span id="L170" class="LineNr">170 </span> 68/push <a href='108write.subx.html#L151'>_test-stream</a>/imm32 <span id="L171" class="LineNr">171 </span> <span class="subxS2Comment"># . . call</span> <span id="L172" class="LineNr">172 </span> e8/call <a href='109stream-equal.subx.html#L194'>check-stream-equal</a>/disp32 <span id="L173" class="LineNr">173 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L174" class="LineNr">174 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0xc/imm32 <span class="subxComment"># add to esp</span> <span id="L175" class="LineNr">175 </span> <span class="subxS1Comment"># . end</span> <span id="L176" class="LineNr">176 </span> c3/return <span id="L177" class="LineNr">177 </span> <span id="L178" class="LineNr">178 </span><span class="subxFunction">write-int32-hex</span>: <span class="subxComment"># f: (addr stream byte), n: int</span> <span id="L179" class="LineNr">179 </span> <span class="subxS1Comment"># . prologue</span> <span id="L180" class="LineNr">180 </span> 55/push-ebp <span id="L181" class="LineNr">181 </span> 89/copy 3/mod/direct 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/r32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy esp to ebp</span> <span id="L182" class="LineNr">182 </span><span class="Constant">$write-int32-hex:hex-prefix</span>: <span id="L183" class="LineNr">183 </span> <span class="subxComment"># write(f, &quot;0x&quot;)</span> <span id="L184" class="LineNr">184 </span> <span class="subxS2Comment"># . . push args</span> <span id="L185" class="LineNr">185 </span> 68/push <span class="Constant">&quot;0x&quot;</span>/imm32 <span id="L186" class="LineNr">186 </span> ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/disp8 <span class="Normal"> . </span> <span class="subxComment"># push *(ebp+8)</span> <span id="L187" class="LineNr">187 </span> <span class="subxS2Comment"># . . call</span> <span id="L188" class="LineNr">188 </span> e8/call <a href='108write.subx.html#L24'>write</a>/disp32 <span id="L189" class="LineNr">189 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L190" class="LineNr">190 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/imm32 <span class="subxComment"># add to esp</span> <span id="L191" class="LineNr">191 </span><span class="Constant">$write-int32-hex:rest</span>: <span id="L192" class="LineNr">192 </span> <span class="subxComment"># write-int32-hex-bits(f, n, 32)</span> <span id="L193" class="LineNr">193 </span> <span class="subxS2Comment"># . . push args</span> <span id="L194" class="LineNr">194 </span> 68/push 0x20/imm32 <span id="L195" class="LineNr">195 </span> ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0xc/disp8 <span class="Normal"> . </span> <span class="subxComment"># push *(ebp+12)</span> <span id="L196" class="LineNr">196 </span> ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/disp8 <span class="Normal"> . </span> <span class="subxComment"># push *(ebp+8)</span> <span id="L197" class="LineNr">197 </span> <span class="subxS2Comment"># . . call</span> <span id="L198" class="LineNr">198 </span> e8/call <a href='117write-int-hex.subx.html#L209'>write-int32-hex-bits</a>/disp32 <span id="L199" class="LineNr">199 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L200" class="LineNr">200 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0xc/imm32 <span class="subxComment"># add to esp</span> <span id="L201" class="LineNr">201 </span><span class="Constant">$write-int32-hex:end</span>: <span id="L202" class="LineNr">202 </span> <span class="subxS1Comment"># . epilogue</span> <span id="L203" class="LineNr">203 </span> 89/copy 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 5/r32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy ebp to esp</span> <span id="L204" class="LineNr">204 </span> 5d/pop-to-ebp <span id="L205" class="LineNr">205 </span> c3/return <span id="L206" class="LineNr">206 </span> <span id="L207" class="LineNr">207 </span><span class="subxComment"># print rightmost 'bits' of 'n'</span> <span id="L208" class="LineNr">208 </span><span class="subxComment"># bits must be multiple of 4</span> <span id="L209" class="LineNr">209 </span><span class="subxFunction">write-int32-hex-bits</span>: <span class="subxComment"># f: (addr stream byte), n: int, bits: int</span> <span id="L210" class="LineNr">210 </span> <span class="subxComment"># pseudocode:</span> <span id="L211" class="LineNr">211 </span> <span class="subxComment"># bits -= 4</span> <span id="L212" class="LineNr">212 </span> <span class="subxComment"># while true</span> <span id="L213" class="LineNr">213 </span> <span class="subxComment"># if (bits &lt; 0) break</span> <span id="L214" class="LineNr">214 </span> <span class="subxComment"># eax = n &gt;&gt; bits</span> <span id="L215" class="LineNr">215 </span> <span class="subxComment"># eax = eax &amp; 0xf</span> <span id="L216" class="LineNr">216 </span> <span class="subxComment"># append-byte(f, AL)</span> <span id="L217" class="LineNr">217 </span> <span class="subxComment"># bits -= 4</span> <span id="L218" class="LineNr">218 </span> <span class="subxComment">#</span> <span id="L219" class="LineNr">219 </span> <span class="subxS1Comment"># . prologue</span> <span id="L220" class="LineNr">220 </span> 55/push-ebp <span id="L221" class="LineNr">221 </span> 89/copy 3/mod/direct 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/r32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy esp to ebp</span> <span id="L222" class="LineNr">222 </span> <span class="subxS1Comment"># . save registers</span> <span id="L223" class="LineNr">223 </span> 50/push-eax <span id="L224" class="LineNr">224 </span> 51/push-ecx <span id="L225" class="LineNr">225 </span> <span class="subxComment"># ecx = bits-4</span> <span id="L226" class="LineNr">226 </span> 8b/copy 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 1/r32/ecx 0x10/disp8 <span class="Normal"> . </span> <span class="subxComment"># copy *(ebp+16) to ecx</span> <span id="L227" class="LineNr">227 </span> 81 5/subop/subtract 3/mod/direct 1/rm32/ecx <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm32 <span class="subxComment"># subtract from ecx</span> <span id="L228" class="LineNr">228 </span><span class="Constant">$write-int32-hex-bits:loop</span>: <span id="L229" class="LineNr">229 </span> <span class="subxComment"># if (bits &lt; 0) break</span> <span id="L230" class="LineNr">230 </span> 81 7/subop/compare 3/mod/direct 1/rm32/ecx <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0/imm32 <span class="subxComment"># compare ecx</span> <span id="L231" class="LineNr">231 </span> 7c/jump-if-&lt; $write-int32-hex-bits:end/disp8 <span id="L232" class="LineNr">232 </span> <span class="subxComment"># eax = n &gt;&gt; bits</span> <span id="L233" class="LineNr">233 </span> 8b/copy 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0/r32/eax 0xc/disp8 <span class="Normal"> . </span> <span class="subxComment"># copy *(ebp+12) to eax</span> <span id="L234" class="LineNr">234 </span> d3/&gt;&gt;ecx 5/subop/pad-zeroes 3/mod/direct 0/rm32/eax <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># shift eax right by ecx bits, padding zeroes</span> <span id="L235" class="LineNr">235 </span> <span class="subxComment"># eax = to-hex-char(AL)</span> <span id="L236" class="LineNr">236 </span> 25/and-eax 0xf/imm32 <span id="L237" class="LineNr">237 </span> e8/call <a href='117write-int-hex.subx.html#L9'>to-hex-char</a>/disp32 <span id="L238" class="LineNr">238 </span> <span class="subxComment"># append-byte(f, AL)</span> <span id="L239" class="LineNr">239 </span> <span class="subxS2Comment"># . . push args</span> <span id="L240" class="LineNr">240 </span> 50/push-eax <span id="L241" class="LineNr">241 </span> ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/disp8 <span class="Normal"> . </span> <span class="subxComment"># push *(ebp+8)</span> <span id="L242" class="LineNr">242 </span> <span class="subxS2Comment"># . . call</span> <span id="L243" class="LineNr">243 </span> e8/call <a href='115write-byte.subx.html#L208'>append-byte</a>/disp32 <span id="L244" class="LineNr">244 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L245" class="LineNr">245 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/imm32 <span class="subxComment"># add to esp</span> <span id="L246" class="LineNr">246 </span> <span class="subxComment"># bits -= 4</span> <span id="L247" class="LineNr">247 </span> 81 5/subop/subtract 3/mod/direct 1/rm32/ecx <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm32 <span class="subxComment"># subtract from ecx</span> <span id="L248" class="LineNr">248 </span> eb/jump $write-int32-hex-bits:<span class="Constant">loop</span>/disp8 <span id="L249" class="LineNr">249 </span><span class="Constant">$write-int32-hex-bits:end</span>: <span id="L250" class="LineNr">250 </span> <span class="subxS1Comment"># . restore registers</span> <span id="L251" class="LineNr">251 </span> 59/pop-to-ecx <span id="L252" class="LineNr">252 </span> 58/pop-to-eax <span id="L253" class="LineNr">253 </span> <span class="subxS1Comment"># . epilogue</span> <span id="L254" class="LineNr">254 </span> 89/copy 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 5/r32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy ebp to esp</span> <span id="L255" class="LineNr">255 </span> 5d/pop-to-ebp <span id="L256" class="LineNr">256 </span> c3/return <span id="L257" class="LineNr">257 </span> <span id="L258" class="LineNr">258 </span><span class="subxTest">test-write-int32-hex</span>: <span id="L259" class="LineNr">259 </span> <span class="subxH1Comment"># - check that write-int32-hex prints the hex textual representation</span> <span id="L260" class="LineNr">260 </span> <span class="subxComment"># setup</span> <span id="L261" class="LineNr">261 </span> <span class="subxS1Comment"># . clear-stream(_test-stream)</span> <span id="L262" class="LineNr">262 </span> <span class="subxS2Comment"># . . push args</span> <span id="L263" class="LineNr">263 </span> 68/push <a href='108write.subx.html#L151'>_test-stream</a>/imm32 <span id="L264" class="LineNr">264 </span> <span class="subxS2Comment"># . . call</span> <span id="L265" class="LineNr">265 </span> e8/call <a href='106stream.subx.html#L17'>clear-stream</a>/disp32 <span id="L266" class="LineNr">266 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L267" class="LineNr">267 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm32 <span class="subxComment"># add to esp</span> <span id="L268" class="LineNr">268 </span> <span class="subxComment"># write-int32-hex(_test-stream, 0x8899aa)</span> <span id="L269" class="LineNr">269 </span> <span class="subxS2Comment"># . . push args</span> <span id="L270" class="LineNr">270 </span> 68/push 0x8899aa/imm32 <span id="L271" class="LineNr">271 </span> 68/push <a href='108write.subx.html#L151'>_test-stream</a>/imm32 <span id="L272" class="LineNr">272 </span> <span class="subxS2Comment"># . . call</span> <span id="L273" class="LineNr">273 </span> e8/call <a href='117write-int-hex.subx.html#L178'>write-int32-hex</a>/disp32 <span id="L274" class="LineNr">274 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L275" class="LineNr">275 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/imm32 <span class="subxComment"># add to esp</span> <span id="L276" class="LineNr">276 </span> <span class="subxComment"># check-stream-equal(_test-stream, &quot;0x008899aa&quot;, msg)</span> <span id="L277" class="LineNr">277 </span> <span class="subxS2Comment"># . . push args</span> <span id="L278" class="LineNr">278 </span> 68/push <span class="Constant">&quot;F - test-write-int32-hex&quot;</span>/imm32 <span id="L279" class="LineNr">279 </span> 68/push <span class="Constant">&quot;0x008899aa&quot;</span>/imm32 <span id="L280" class="LineNr">280 </span> 68/push <a href='108write.subx.html#L151'>_test-stream</a>/imm32 <span id="L281" class="LineNr">281 </span> <span class="subxS2Comment"># . . call</span> <span id="L282" class="LineNr">282 </span> e8/call <a href='109stream-equal.subx.html#L194'>check-stream-equal</a>/disp32 <span id="L283" class="LineNr">283 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L284" class="LineNr">284 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0xc/imm32 <span class="subxComment"># add to esp</span> <span id="L285" class="LineNr">285 </span> <span class="subxS1Comment"># . end</span> <span id="L286" class="LineNr">286 </span> c3/return <span id="L287" class="LineNr">287 </span> <span id="L288" class="LineNr">288 </span><span class="subxFunction">write-int32-hex-buffered</span>: <span class="subxComment"># f: (addr buffered-file), n: int</span> <span id="L289" class="LineNr">289 </span> <span class="subxS1Comment"># . prologue</span> <span id="L290" class="LineNr">290 </span> 55/push-ebp <span id="L291" class="LineNr">291 </span> 89/copy 3/mod/direct 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/r32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy esp to ebp</span> <span id="L292" class="LineNr">292 </span><span class="Constant">$write-int32-hex-buffered:hex-prefix</span>: <span id="L293" class="LineNr">293 </span> <span class="subxComment"># write-buffered(f, &quot;0x&quot;)</span> <span id="L294" class="LineNr">294 </span> <span class="subxS2Comment"># . . push args</span> <span id="L295" class="LineNr">295 </span> 68/push <span class="Constant">&quot;0x&quot;</span>/imm32 <span id="L296" class="LineNr">296 </span> ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/disp8 <span class="Normal"> . </span> <span class="subxComment"># push *(ebp+8)</span> <span id="L297" class="LineNr">297 </span> <span class="subxS2Comment"># . . call</span> <span id="L298" class="LineNr">298 </span> e8/call <a href='116write-buffered.subx.html#L8'>write-buffered</a>/disp32 <span id="L299" class="LineNr">299 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L300" class="LineNr">300 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/imm32 <span class="subxComment"># add to esp</span> <span id="L301" class="LineNr">301 </span><span class="Constant">$write-int32-hex-buffered:rest</span>: <span id="L302" class="LineNr">302 </span> <span class="subxComment"># write-int32-hex-bits-buffered(f, n, 32)</span> <span id="L303" class="LineNr">303 </span> <span class="subxS2Comment"># . . push args</span> <span id="L304" class="LineNr">304 </span> 68/push 0x20/imm32 <span id="L305" class="LineNr">305 </span> ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0xc/disp8 <span class="Normal"> . </span> <span class="subxComment"># push *(ebp+12)</span> <span id="L306" class="LineNr">306 </span> ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/disp8 <span class="Normal"> . </span> <span class="subxComment"># push *(ebp+8)</span> <span id="L307" class="LineNr">307 </span> <span class="subxS2Comment"># . . call</span> <span id="L308" class="LineNr">308 </span> e8/call <a href='117write-int-hex.subx.html#L319'>write-int32-hex-bits-buffered</a>/disp32 <span id="L309" class="LineNr">309 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L310" class="LineNr">310 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0xc/imm32 <span class="subxComment"># add to esp</span> <span id="L311" class="LineNr">311 </span><span class="Constant">$write-int32-hex-buffered:end</span>: <span id="L312" class="LineNr">312 </span> <span class="subxS1Comment"># . epilogue</span> <span id="L313" class="LineNr">313 </span> 89/copy 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 5/r32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy ebp to esp</span> <span id="L314" class="LineNr">314 </span> 5d/pop-to-ebp <span id="L315" class="LineNr">315 </span> c3/return <span id="L316" class="LineNr">316 </span> <span id="L317" class="LineNr">317 </span><span class="subxComment"># print rightmost 'bits' of 'n'</span> <span id="L318" class="LineNr">318 </span><span class="subxComment"># bits must be multiple of 4</span> <span id="L319" class="LineNr">319 </span><span class="subxFunction">write-int32-hex-bits-buffered</span>: <span class="subxComment"># f: (addr buffered-file), n: int, bits: int</span> <span id="L320" class="LineNr">320 </span> <span class="subxComment"># pseudocode:</span> <span id="L321" class="LineNr">321 </span> <span class="subxComment"># bits -= 4</span> <span id="L322" class="LineNr">322 </span> <span class="subxComment"># while true</span> <span id="L323" class="LineNr">323 </span> <span class="subxComment"># if (bits &lt; 0) break</span> <span id="L324" class="LineNr">324 </span> <span class="subxComment"># eax = n &gt;&gt; bits</span> <span id="L325" class="LineNr">325 </span> <span class="subxComment"># eax = eax &amp; 0xf</span> <span id="L326" class="LineNr">326 </span> <span class="subxComment"># write-byte-buffered(f, AL)</span> <span id="L327" class="LineNr">327 </span> <span class="subxComment"># bits -= 4</span> <span id="L328" class="LineNr">328 </span> <span class="subxComment">#</span> <span id="L329" class="LineNr">329 </span> <span class="subxS1Comment"># . prologue</span> <span id="L330" class="LineNr">330 </span> 55/push-ebp <span id="L331" class="LineNr">331 </span> 89/copy 3/mod/direct 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/r32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy esp to ebp</span> <span id="L332" class="LineNr">332 </span> <span class="subxS1Comment"># . save registers</span> <span id="L333" class="LineNr">333 </span> 50/push-eax <span id="L334" class="LineNr">334 </span> 51/push-ecx <span id="L335" class="LineNr">335 </span> <span class="subxComment"># ecx = bits-4</span> <span id="L336" class="LineNr">336 </span> 8b/copy 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 1/r32/ecx 0x10/disp8 <span class="Normal"> . </span> <span class="subxComment"># copy *(ebp+16) to ecx</span> <span id="L337" class="LineNr">337 </span> 81 5/subop/subtract 3/mod/direct 1/rm32/ecx <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm32 <span class="subxComment"># subtract from ecx</span> <span id="L338" class="LineNr">338 </span><span class="Constant">$write-int32-hex-bits-buffered:loop</span>: <span id="L339" class="LineNr">339 </span> <span class="subxComment"># if (bits &lt; 0) break</span> <span id="L340" class="LineNr">340 </span> 81 7/subop/compare 3/mod/direct 1/rm32/ecx <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0/imm32 <span class="subxComment"># compare ecx</span> <span id="L341" class="LineNr">341 </span> 7c/jump-if-&lt; $write-int32-hex-bits-buffered:end/disp8 <span id="L342" class="LineNr">342 </span> <span class="subxComment"># eax = n &gt;&gt; bits</span> <span id="L343" class="LineNr">343 </span> 8b/copy 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0/r32/eax 0xc/disp8 <span class="Normal"> . </span> <span class="subxComment"># copy *(ebp+12) to eax</span> <span id="L344" class="LineNr">344 </span> d3/&gt;&gt;ecx 5/subop/pad-zeroes 3/mod/direct 0/rm32/eax <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># shift eax right by ecx bits, padding zeroes</span> <span id="L345" class="LineNr">345 </span> <span class="subxComment"># eax = to-hex-char(AL)</span> <span id="L346" class="LineNr">346 </span> 25/and-eax 0xf/imm32 <span id="L347" class="LineNr">347 </span> e8/call <a href='117write-int-hex.subx.html#L9'>to-hex-char</a>/disp32 <span id="L348" class="LineNr">348 </span> <span class="subxComment"># write-byte-buffered(f, AL)</span> <span id="L349" class="LineNr">349 </span> <span class="subxS2Comment"># . . push args</span> <span id="L350" class="LineNr">350 </span> 50/push-eax <span id="L351" class="LineNr">351 </span> ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/disp8 <span class="Normal"> . </span> <span class="subxComment"># push *(ebp+8)</span> <span id="L352" class="LineNr">352 </span> <span class="subxS2Comment"># . . call</span> <span id="L353" class="LineNr">353 </span> e8/call <a href='115write-byte.subx.html#L33'>write-byte-buffered</a>/disp32 <span id="L354" class="LineNr">354 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L355" class="LineNr">355 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/imm32 <span class="subxComment"># add to esp</span> <span id="L356" class="LineNr">356 </span> <span class="subxComment"># bits -= 4</span> <span id="L357" class="LineNr">357 </span> 81 5/subop/subtract 3/mod/direct 1/rm32/ecx <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm32 <span class="subxComment"># subtract from ecx</span> <span id="L358" class="LineNr">358 </span> eb/jump $write-int32-hex-bits-buffered:<span class="Constant">loop</span>/disp8 <span id="L359" class="LineNr">359 </span><span class="Constant">$write-int32-hex-bits-buffered:end</span>: <span id="L360" class="LineNr">360 </span> <span class="subxS1Comment"># . restore registers</span> <span id="L361" class="LineNr">361 </span> 59/pop-to-ecx <span id="L362" class="LineNr">362 </span> 58/pop-to-eax <span id="L363" class="LineNr">363 </span> <span class="subxS1Comment"># . epilogue</span> <span id="L364" class="LineNr">364 </span> 89/copy 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 5/r32/ebp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="subxComment"># copy ebp to esp</span> <span id="L365" class="LineNr">365 </span> 5d/pop-to-ebp <span id="L366" class="LineNr">366 </span> c3/return <span id="L367" class="LineNr">367 </span> <span id="L368" class="LineNr">368 </span><span class="subxTest">test-write-int32-hex-buffered</span>: <span id="L369" class="LineNr">369 </span> <span class="subxH1Comment"># - check that write-int32-hex-buffered prints the hex textual representation</span> <span id="L370" class="LineNr">370 </span> <span class="subxComment"># setup</span> <span id="L371" class="LineNr">371 </span> <span class="subxS1Comment"># . clear-stream(_test-stream)</span> <span id="L372" class="LineNr">372 </span> <span class="subxS2Comment"># . . push args</span> <span id="L373" class="LineNr">373 </span> 68/push <a href='108write.subx.html#L151'>_test-stream</a>/imm32 <span id="L374" class="LineNr">374 </span> <span class="subxS2Comment"># . . call</span> <span id="L375" class="LineNr">375 </span> e8/call <a href='106stream.subx.html#L17'>clear-stream</a>/disp32 <span id="L376" class="LineNr">376 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L377" class="LineNr">377 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm32 <span class="subxComment"># add to esp</span> <span id="L378" class="LineNr">378 </span> <span class="subxS1Comment"># . clear-stream($_test-buffered-file-&gt;buffer)</span> <span id="L379" class="LineNr">379 </span> <span class="subxS2Comment"># . . push args</span> <span id="L380" class="LineNr">380 </span> 68/push $_test-buffered-file-&gt;buffer/imm32 <span id="L381" class="LineNr">381 </span> <span class="subxS2Comment"># . . call</span> <span id="L382" class="LineNr">382 </span> e8/call <a href='106stream.subx.html#L17'>clear-stream</a>/disp32 <span id="L383" class="LineNr">383 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L384" class="LineNr">384 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm32 <span class="subxComment"># add to esp</span> <span id="L385" class="LineNr">385 </span> <span class="subxComment"># write-int32-hex-buffered(_test-buffered-file, 0x8899aa)</span> <span id="L386" class="LineNr">386 </span> <span class="subxS2Comment"># . . push args</span> <span id="L387" class="LineNr">387 </span> 68/push 0x8899aa/imm32 <span id="L388" class="LineNr">388 </span> 68/push <a href='112read-byte.subx.html#L318'>_test-buffered-file</a>/imm32 <span id="L389" class="LineNr">389 </span> <span class="subxS2Comment"># . . call</span> <span id="L390" class="LineNr">390 </span> e8/call <a href='117write-int-hex.subx.html#L288'>write-int32-hex-buffered</a>/disp32 <span id="L391" class="LineNr">391 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L392" class="LineNr">392 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 8/imm32 <span class="subxComment"># add to esp</span> <span id="L393" class="LineNr">393 </span> <span class="subxComment"># flush(_test-buffered-file)</span> <span id="L394" class="LineNr">394 </span> <span class="subxS2Comment"># . . push args</span> <span id="L395" class="LineNr">395 </span> 68/push <a href='112read-byte.subx.html#L318'>_test-buffered-file</a>/imm32 <span id="L396" class="LineNr">396 </span> <span class="subxS2Comment"># . . call</span> <span id="L397" class="LineNr">397 </span> e8/call <a href='115write-byte.subx.html#L81'>flush</a>/disp32 <span id="L398" class="LineNr">398 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L399" class="LineNr">399 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 4/imm32 <span class="subxComment"># add to esp</span> <span id="L400" class="Folded">400 </span><span class="Folded">+-- 18 lines: #? # dump line --------------------------------------------------------------------------------------------------------------------------------------------------------</span> <span id="L418" class="LineNr">418 </span> <span class="subxComment"># check-stream-equal(_test-stream, &quot;0x008899aa&quot;, msg)</span> <span id="L419" class="LineNr">419 </span> <span class="subxS2Comment"># . . push args</span> <span id="L420" class="LineNr">420 </span> 68/push <span class="Constant">&quot;F - test-write-int32-hex-buffered&quot;</span>/imm32 <span id="L421" class="LineNr">421 </span> 68/push <span class="Constant">&quot;0x008899aa&quot;</span>/imm32 <span id="L422" class="LineNr">422 </span> 68/push <a href='108write.subx.html#L151'>_test-stream</a>/imm32 <span id="L423" class="LineNr">423 </span> <span class="subxS2Comment"># . . call</span> <span id="L424" class="LineNr">424 </span> e8/call <a href='109stream-equal.subx.html#L194'>check-stream-equal</a>/disp32 <span id="L425" class="LineNr">425 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L426" class="LineNr">426 </span> 81 0/subop/add 3/mod/direct 4/rm32/esp <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> <span class="Normal"> . </span> 0xc/imm32 <span class="subxComment"># add to esp</span> <span id="L427" class="LineNr">427 </span> <span class="subxS1Comment"># . end</span> <span id="L428" class="LineNr">428 </span> c3/return <span id="L429" class="LineNr">429 </span> <span id="L430" class="LineNr">430 </span><span class="subxS2Comment"># . . vim&#0058;nowrap:textwidth=0</span> </pre> </body> </html> <!-- vim: set foldmethod=manual : -->