about summary refs log tree commit diff stats
path: root/117write-int-hex.subx
blob: 091bd87477d8d2b831d5e0c80ccb8a20ad9977de (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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# Write out the (hex) textual representation of numbers.

== code
#   instruction                     effective address                                                   register    displacement    immediate
# . op          subop               mod             rm32          base        index         scale       r32
# . 1-3 bytes   3 bits              2 bits          3 bits        3 bits      3 bits        2 bits      2 bits      0/1/2/4 bytes   0/1/2/4 bytes

# convert the lowest nibble of eax to ascii and return it in the lowest byte of eax
to-hex-char:  # in/eax: int -> out/eax: int
    # no error checking; accepts argument in eax
    # if (eax <= 9) return eax + '0'
    3d/compare-eax-with  0x9/imm32/9
    7f/jump-if->  $to-hex-char:else/disp8
    05/add-to-eax  0x30/imm32/0
    c3/return
$to-hex-char:else:
    # otherwise return eax + 'a' - 10
    05/add-to-eax  0x57/imm32/a-10
    c3/return

append-byte-hex:  # f: (addr stream byte), n: int
    # . prologue
    55/push-ebp
    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
    # . save registers
    50/push-eax
    # AL = convert upper nibble to hex
    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           0/r32/eax   0xc/disp8       .                 # copy *(ebp+12) to eax
    c1/shift    5/subop/logic-right 3/mod/direct    0/rm32/eax    .           .             .           .           .               4/imm8            # shift eax right by 4 bits, while padding zeroes
    25/and-eax  0xf/imm32
    # . AL = to-hex-char(AL)
    e8/call  to-hex-char/disp32
    # append-byte(f, AL)
    # . . push args
    50/push-eax
    ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
    # . . call
    e8/call  append-byte/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
    # AL = convert lower nibble to hex
    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           0/r32/eax   0xc/disp8       .                 # copy *(ebp+12) to eax
    25/and-eax  0xf/imm32
    # . AL = to-hex-char(AL)
    e8/call  to-hex-char/disp32
    # append-byte(f, AL)
    # . . push args
    50/push-eax
    ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
    # . . call
    e8/call  append-byte/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
$append-byte-hex:end:
    # . restore registers
    58/pop-to-eax
    # . epilogue
    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
    5d/pop-to-ebp
    c3/return

test-append-byte-hex:
    # - check that append-byte-hex adds the hex textual representation
    # setup
    # . clear-stream(_test-stream)
    # . . push args
    68/push  _test-stream/imm32
    # . . call
    e8/call  clear-stream/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
    # append-byte-hex(_test-stream, 0xa)  # exercises digit, non-digit as well as leading zero
    # . . push args
    68/push  0xa/imm32
    68/push  _test-stream/imm32
    # . . call
    e8/call  append-byte-hex/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
    # check-stream-equal(_test-stream, "0a", msg)
    # . . push args
    68/push  "F - test-append-byte-hex"/imm32
    68/push  "0a"/imm32
    68/push  _test-stream/imm32
    # . . call
    e8/call  check-stream-equal/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
    # . end
    c3/return

write-int32-hex:  # f: (addr stream byte), n: int
    # . prologue
    55/push-ebp
    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
$write-int32-hex:hex-prefix:
    # write(f, "0x")
    # . . push args
    68/push  "0x"/imm32
    ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
    # . . call
    e8/call  write/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
$write-int32-hex:rest:
    # write-int32-hex-bits(f, n, 32)
    # . . push args
    68/push  0x20/imm32
    ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0xc/disp8       .                 # push *(ebp+12)
    ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
    # . . call
    e8/call  write-int32-hex-bits/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
$write-int32-hex:end:
    # . epilogue
    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
    5d/pop-to-ebp
    c3/return

# print rightmost 'bits' of 'n'
# bits must be multiple of 4
write-int32-hex-bits:  # f: (addr stream byte), n: int, bits: int
    # pseudocode:
    #  bits -= 4
    #  while true
    #    if (bits < 0) break
    #    eax = n >> bits
    #    eax = eax & 0xf
    #    append-byte(f, AL)
    #    bits -= 4
    #
    # . prologue
    55/push-ebp
    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
    # . save registers
    50/push-eax
    51/push-ecx
    # ecx = bits-4
    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           1/r32/ecx   0x10/disp8      .                 # copy *(ebp+16) to ecx
    81          5/subop/subtract    3/mod/direct    1/rm32/ecx    .           .             .           .           .               4/imm32           # subtract from ecx
$write-int32-hex-bits:loop:
    # if (bits < 0) break
    81          7/subop/compare     3/mod/direct    1/rm32/ecx    .           .             .           .           .               0/imm32           # compare ecx
    7c/jump-if-<  $write-int32-hex-bits:end/disp8
    # eax = n >> bits
    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           0/r32/eax   0xc/disp8       .                 # copy *(ebp+12) to eax
    d3/>>ecx    5/subop/pad-zeroes  3/mod/direct    0/rm32/eax    .           .             .           .           .               .                 # shift eax right by ecx bits, padding zeroes
    # eax = to-hex-char(AL)
    25/and-eax  0xf/imm32
    e8/call  to-hex-char/disp32
    # append-byte(f, AL)
    # . . push args
    50/push-eax
    ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
    # . . call
    e8/call  append-byte/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
    # bits -= 4
    81          5/subop/subtract    3/mod/direct    1/rm32/ecx    .           .             .           .           .               4/imm32           # subtract from ecx
    eb/jump  $write-int32-hex-bits:loop/disp8
$write-int32-hex-bits:end:
    # . restore registers
    59/pop-to-ecx
    58/pop-to-eax
    # . epilogue
    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
    5d/pop-to-ebp
    c3/return

test-write-int32-hex:
    # - check that write-int32-hex prints the hex textual representation
    # setup
    # . clear-stream(_test-stream)
    # . . push args
    68/push  _test-stream/imm32
    # . . call
    e8/call  clear-stream/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
    # write-int32-hex(_test-stream, 0x8899aa)
    # . . push args
    68/push  0x8899aa/imm32
    68/push  _test-stream/imm32
    # . . call
    e8/call  write-int32-hex/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
    # check-stream-equal(_test-stream, "0x008899aa", msg)
    # . . push args
    68/push  "F - test-write-int32-hex"/imm32
    68/push  "0x008899aa"/imm32
    68/push  _test-stream/imm32
    # . . call
    e8/call  check-stream-equal/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
    # . end
    c3/return

# . . vim:nowrap:textwidth=0
k">color:#4466ff; } .LineNr { color:#444444; } .subxS1Comment { color:#2d8cff; } .CommentedCode { color: #6c6c6c; } .subxFunction { color: #af5f00; text-decoration: underline; } .subxTest { color: #5f8700; } .subxMinorFunction { color: #875f5f; } .Constant { color:#00a0a0; } .SpecialChar { color: #d70000; } --> </style> <script type='text/javascript'> <!-- /* function to open any folds containing a jumped-to line before jumping to it */ function JumpToLine() { var lineNum; lineNum = window.location.hash; lineNum = lineNum.substr(1); /* strip off '#' */ if (lineNum.indexOf('L') == -1) { lineNum = 'L'+lineNum; } lineElem = document.getElementById(lineNum); /* Always jump to new location even if the line was hidden inside a fold, or * we corrected the raw number to a line ID. */ if (lineElem) { lineElem.scrollIntoView(true); } return true; } if ('onhashchange' in window) { window.onhashchange = JumpToLine; } --> </script> </head> <body onload='JumpToLine();'> <a href='https://github.com/akkartik/mu/blob/master/subx/060write-stream.subx'>https://github.com/akkartik/mu/blob/master/subx/060write-stream.subx</a> <pre id='vimCodeElement'> <span id="L1" class="LineNr"> 1 </span><span class="subxComment"># write-stream: like write, but write streams rather than strings</span> <span id="L2" class="LineNr"> 2 </span> <span id="L3" class="LineNr"> 3 </span>== code <span id="L4" class="LineNr"> 4 </span><span class="subxComment"># instruction effective address register displacement immediate</span> <span id="L5" class="LineNr"> 5 </span><span class="subxS1Comment"># . op subop mod rm32 base index scale r32</span> <span id="L6" class="LineNr"> 6 </span><span class="subxS1Comment"># . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes</span> <span id="L7" class="LineNr"> 7 </span> <span id="L8" class="LineNr"> 8 </span><span class="subxComment"># main:</span> <span id="L9" class="LineNr"> 9 </span> <span class="subxComment"># manual test</span> <span id="L10" class="LineNr"> 10 </span><span class="CommentedCode">#? # write-stream(stdout, _test-stream2)</span> <span id="L11" class="LineNr"> 11 </span><span class="CommentedCode">#? 68/push _test-stream2/imm32</span> <span id="L12" class="LineNr"> 12 </span><span class="CommentedCode">#? 68/push 1/imm32/stdout</span> <span id="L13" class="LineNr"> 13 </span><span class="CommentedCode">#? e8/call write-stream/disp32</span> <span id="L14" class="LineNr"> 14 </span> <span class="subxComment"># automatic test</span> <span id="L15" class="LineNr"> 15 </span><span class="CommentedCode">#? e8/call test-write-stream-appends/disp32</span> <span id="L16" class="LineNr"> 16 </span> e8/call run-tests/disp32 <span class="subxComment"># 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'.</span> <span id="L17" class="LineNr"> 17 </span> <span class="subxComment"># syscall(exit, Num-test-failures)</span> <span id="L18" class="LineNr"> 18 </span> 8b/copy 0/mod/indirect 5/rm32/.disp32 <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 3/r32/EBX <span class="SpecialChar">Num-test-failures</span>/disp32 <span class="subxComment"># copy *Num-test-failures to EBX</span> <span id="L19" class="LineNr"> 19 </span> b8/copy-to-EAX 1/imm32 <span id="L20" class="LineNr"> 20 </span> cd/syscall 0x80/imm8 <span id="L21" class="LineNr"> 21 </span> <span id="L22" class="LineNr"> 22 </span><span class="subxFunction">write-stream</span>: <span class="subxComment"># f : fd or (address stream), s : (address stream) -&gt; &lt;void&gt;</span> <span id="L23" class="LineNr"> 23 </span> <span class="subxS1Comment"># . prolog</span> <span id="L24" class="LineNr"> 24 </span> 55/push-EBP <span id="L25" class="LineNr"> 25 </span> 89/copy 3/mod/direct 5/rm32/EBP <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 4/r32/ESP <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="subxComment"># copy ESP to EBP</span> <span id="L26" class="LineNr"> 26 </span> <span class="subxComment"># if (f &lt; 0x08000000) _write-stream(f, s), return # f can't be a user-mode address, so treat it as a kernel file descriptor</span> <span id="L27" class="LineNr"> 27 </span> 81 7/subop/compare 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 8/disp8 0x08000000/imm32 <span class="subxComment"># compare *(EBP+8)</span> <span id="L28" class="LineNr"> 28 </span> 7d/jump-if-greater-or-equal $write-stream:fake/disp8 <span id="L29" class="LineNr"> 29 </span> <span class="subxS2Comment"># . . push args</span> <span id="L30" class="LineNr"> 30 </span> ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 0xc/disp8 <span class="CommentedCode"> . </span> <span class="subxComment"># push *(EBP+12)</span> <span id="L31" class="LineNr"> 31 </span> ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 8/disp8 <span class="CommentedCode"> . </span> <span class="subxComment"># push *(EBP+8)</span> <span id="L32" class="LineNr"> 32 </span> <span class="subxS2Comment"># . . call</span> <span id="L33" class="LineNr"> 33 </span> e8/call _write-stream/disp32 <span id="L34" class="LineNr"> 34 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L35" class="LineNr"> 35 </span> 81 0/subop/add 3/mod/direct 4/rm32/ESP <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 8/imm32 <span class="subxComment"># add to ESP</span> <span id="L36" class="LineNr"> 36 </span> eb/jump $write-stream:end/disp8 <span id="L37" class="LineNr"> 37 </span><span class="Constant">$write-stream:fake</span>: <span id="L38" class="LineNr"> 38 </span> <span class="subxComment"># otherwise, treat 'f' as a stream to append to</span> <span id="L39" class="LineNr"> 39 </span> <span class="subxS1Comment"># . save registers</span> <span id="L40" class="LineNr"> 40 </span> 50/push-EAX <span id="L41" class="LineNr"> 41 </span> 56/push-ESI <span id="L42" class="LineNr"> 42 </span> 57/push-EDI <span id="L43" class="LineNr"> 43 </span> <span class="subxComment"># EDI = f</span> <span id="L44" class="LineNr"> 44 </span> 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none 7/r32/EDI 8/disp8 <span class="CommentedCode"> . </span> <span class="subxComment"># copy *(EBP+8) to EDI</span> <span id="L45" class="LineNr"> 45 </span> <span class="subxComment"># ESI = s</span> <span id="L46" class="LineNr"> 46 </span> 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none 6/r32/ESI 0xc/disp8 <span class="CommentedCode"> . </span> <span class="subxComment"># copy *(EBP+12) to ESI</span> <span id="L47" class="LineNr"> 47 </span> <span class="subxComment"># EAX = _append-4(&amp;f-&gt;data[f-&gt;write], &amp;f-&gt;data[f-&gt;length], &amp;s-&gt;data[s-&gt;read], &amp;s-&gt;data[s-&gt;write])</span> <span id="L48" class="LineNr"> 48 </span> <span class="subxS2Comment"># . . push &amp;s-&gt;data[s-&gt;write]</span> <span id="L49" class="LineNr"> 49 </span> 8b/copy 0/mod/indirect 6/rm32/ESI <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 0/r32/EAX <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="subxComment"># copy *ESI to EAX</span> <span id="L50" class="LineNr"> 50 </span> 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/ESI 0/index/EAX <span class="CommentedCode"> . </span> 0/r32/EAX 0xc/disp8 <span class="CommentedCode"> . </span> <span class="subxComment"># copy ESI+EAX+12 to EAX</span> <span id="L51" class="LineNr"> 51 </span> 50/push-EAX <span id="L52" class="LineNr"> 52 </span> <span class="subxS2Comment"># . . push &amp;s-&gt;data[s-&gt;read]</span> <span id="L53" class="LineNr"> 53 </span> 8b/copy 1/mod/*+disp8 6/rm32/ESI <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 0/r32/EAX 4/disp8 <span class="CommentedCode"> . </span> <span class="subxComment"># copy *(ESI+4) to EAX</span> <span id="L54" class="LineNr"> 54 </span> 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/ESI 0/index/EAX <span class="CommentedCode"> . </span> 0/r32/EAX 0xc/disp8 <span class="CommentedCode"> . </span> <span class="subxComment"># copy ESI+EAX+12 to EAX</span> <span id="L55" class="LineNr"> 55 </span> 50/push-EAX <span id="L56" class="LineNr"> 56 </span> <span class="subxS2Comment"># . . push &amp;f-&gt;data[f-&gt;length]</span> <span id="L57" class="LineNr"> 57 </span> 8b/copy 1/mod/*+disp8 7/rm32/EDI <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 0/r32/EAX 8/disp8 <span class="CommentedCode"> . </span> <span class="subxComment"># copy *(EDI+8) to EAX</span> <span id="L58" class="LineNr"> 58 </span> 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/EDI 0/index/EAX <span class="CommentedCode"> . </span> 0/r32/EAX 0xc/disp8 <span class="CommentedCode"> . </span> <span class="subxComment"># copy EDI+EAX+12 to EAX</span> <span id="L59" class="LineNr"> 59 </span> 50/push-EAX <span id="L60" class="LineNr"> 60 </span> <span class="subxS2Comment"># . . push &amp;f-&gt;data[f-&gt;write]</span> <span id="L61" class="LineNr"> 61 </span> 8b/copy 0/mod/indirect 7/rm32/EDI <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 0/r32/EAX <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="subxComment"># copy *EDI to EAX</span> <span id="L62" class="LineNr"> 62 </span> 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/EDI 0/index/EAX <span class="CommentedCode"> . </span> 0/r32/EAX 0xc/disp8 <span class="CommentedCode"> . </span> <span class="subxComment"># copy EDI+EAX+12 to EAX</span> <span id="L63" class="LineNr"> 63 </span> 50/push-EAX <span id="L64" class="LineNr"> 64 </span> <span class="subxS2Comment"># . . call</span> <span id="L65" class="LineNr"> 65 </span> e8/call _append-4/disp32 <span id="L66" class="LineNr"> 66 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L67" class="LineNr"> 67 </span> 81 0/subop/add 3/mod/direct 4/rm32/ESP <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 0x10/imm32 <span class="subxComment"># add to ESP</span> <span id="L68" class="LineNr"> 68 </span> <span class="subxComment"># f-&gt;write += EAX</span> <span id="L69" class="LineNr"> 69 </span> 01/add 0/mod/indirect 7/rm32/EDI <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 0/r32/EAX <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="subxComment"># add EAX to *EDI</span> <span id="L70" class="LineNr"> 70 </span> <span class="subxComment"># s-&gt;read += EAX</span> <span id="L71" class="LineNr"> 71 </span> 01/add 1/mod/*+disp8 6/rm32/ESI <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 0/r32/EAX 4/disp8 <span class="CommentedCode"> . </span> <span class="subxComment"># add EAX to *(ESI+4)</span> <span id="L72" class="LineNr"> 72 </span> <span class="subxS1Comment"># . restore registers</span> <span id="L73" class="LineNr"> 73 </span> 5f/pop-to-EDI <span id="L74" class="LineNr"> 74 </span> 5e/pop-to-ESI <span id="L75" class="LineNr"> 75 </span> 58/pop-to-EAX <span id="L76" class="LineNr"> 76 </span><span class="Constant">$write-stream:end</span>: <span id="L77" class="LineNr"> 77 </span> <span class="subxS1Comment"># . epilog</span> <span id="L78" class="LineNr"> 78 </span> 89/copy 3/mod/direct 4/rm32/ESP <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 5/r32/EBP <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="subxComment"># copy EBP to ESP</span> <span id="L79" class="LineNr"> 79 </span> 5d/pop-to-EBP <span id="L80" class="LineNr"> 80 </span> c3/return <span id="L81" class="LineNr"> 81 </span> <span id="L82" class="LineNr"> 82 </span><span class="subxMinorFunction">_write-stream</span>: <span class="subxComment"># fd : int, s : (address stream) -&gt; &lt;void&gt;</span> <span id="L83" class="LineNr"> 83 </span> <span class="subxS1Comment"># . prolog</span> <span id="L84" class="LineNr"> 84 </span> 55/push-EBP <span id="L85" class="LineNr"> 85 </span> 89/copy 3/mod/direct 5/rm32/EBP <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 4/r32/ESP <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="subxComment"># copy ESP to EBP</span> <span id="L86" class="LineNr"> 86 </span> <span class="subxS1Comment"># . save registers</span> <span id="L87" class="LineNr"> 87 </span> 50/push-EAX <span id="L88" class="LineNr"> 88 </span> 51/push-ECX <span id="L89" class="LineNr"> 89 </span> 52/push-EDX <span id="L90" class="LineNr"> 90 </span> 53/push-EBX <span id="L91" class="LineNr"> 91 </span> 56/push-ESI <span id="L92" class="LineNr"> 92 </span> 57/push-EDI <span id="L93" class="LineNr"> 93 </span> <span class="subxComment"># ESI = s</span> <span id="L94" class="LineNr"> 94 </span> 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none <span class="CommentedCode"> . </span> 6/r32/ESI 0xc/disp8 <span class="CommentedCode"> . </span> <span class="subxComment"># copy *(EBP+12) to ESI</span> <span id="L95" class="LineNr"> 95 </span> <span class="subxComment"># EDI = s-&gt;read</span> <span id="L96" class="LineNr"> 96 </span> 8b/copy 1/mod/*+disp8 6/rm32/ESI <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 7/r32/EDI 4/disp8 <span class="CommentedCode"> . </span> <span class="subxComment"># copy *(ESI+4) to EDI</span> <span id="L97" class="LineNr"> 97 </span> <span class="subxComment"># EDX = s-&gt;write</span> <span id="L98" class="LineNr"> 98 </span> 8b/copy 0/mod/indirect 6/rm32/ESI <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 2/r32/EDX <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="subxComment"># copy *ESI to EDX</span> <span id="L99" class="LineNr"> 99 </span> <span class="subxComment"># syscall(write, fd, &amp;s-&gt;data[s-&gt;read], s-&gt;write-s-&gt;read)</span> <span id="L100" class="LineNr">100 </span> <span class="subxS2Comment"># . . fd : EBX</span> <span id="L101" class="LineNr">101 </span> 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none <span class="CommentedCode"> . </span> 3/r32/EBX 8/disp8 <span class="CommentedCode"> . </span> <span class="subxComment"># copy *(EBP+8) to EBX</span> <span id="L102" class="LineNr">102 </span> <span class="subxS2Comment"># . . data : ECX = &amp;s-&gt;data[s-&gt;read]</span> <span id="L103" class="LineNr">103 </span> 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/ESI 7/index/EDI <span class="CommentedCode"> . </span> 1/r32/ECX 0xc/disp8 <span class="CommentedCode"> . </span> <span class="subxComment"># copy ESI+EDI+12 to ECX</span> <span id="L104" class="LineNr">104 </span> <span class="subxS2Comment"># . . size : EDX = s-&gt;write - s-&gt;read</span> <span id="L105" class="LineNr">105 </span> 29/subtract 3/mod/direct 2/rm32/EDX <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 7/r32/EDI <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="subxComment"># subtract EDI from EDX</span> <span id="L106" class="LineNr">106 </span> <span class="subxS2Comment"># . . syscall</span> <span id="L107" class="LineNr">107 </span> b8/copy-to-EAX 4/imm32/write <span id="L108" class="LineNr">108 </span> cd/syscall 0x80/imm8 <span id="L109" class="LineNr">109 </span> <span class="subxS1Comment"># . restore registers</span> <span id="L110" class="LineNr">110 </span> 5f/pop-to-EDI <span id="L111" class="LineNr">111 </span> 5e/pop-to-ESI <span id="L112" class="LineNr">112 </span> 5b/pop-to-EBX <span id="L113" class="LineNr">113 </span> 5a/pop-to-EDX <span id="L114" class="LineNr">114 </span> 59/pop-to-ECX <span id="L115" class="LineNr">115 </span> 58/pop-to-EAX <span id="L116" class="LineNr">116 </span> <span class="subxS1Comment"># . epilog</span> <span id="L117" class="LineNr">117 </span> 89/copy 3/mod/direct 4/rm32/ESP <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 5/r32/EBP <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="subxComment"># copy EBP to ESP</span> <span id="L118" class="LineNr">118 </span> 5d/pop-to-EBP <span id="L119" class="LineNr">119 </span> c3/return <span id="L120" class="LineNr">120 </span> <span id="L121" class="LineNr">121 </span><span class="subxTest">test-write-stream-single</span>: <span id="L122" class="LineNr">122 </span> <span class="subxComment"># setup</span> <span id="L123" class="LineNr">123 </span> <span class="subxS1Comment"># . clear-stream(_test-stream)</span> <span id="L124" class="LineNr">124 </span> <span class="subxS2Comment"># . . push args</span> <span id="L125" class="LineNr">125 </span> 68/push _test-stream/imm32 <span id="L126" class="LineNr">126 </span> <span class="subxS2Comment"># . . call</span> <span id="L127" class="LineNr">127 </span> e8/call clear-stream/disp32 <span id="L128" class="LineNr">128 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L129" class="LineNr">129 </span> 81 0/subop/add 3/mod/direct 4/rm32/ESP <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 4/imm32 <span class="subxComment"># add to ESP</span> <span id="L130" class="LineNr">130 </span> <span class="subxS1Comment"># . clear-stream(_test-stream2)</span> <span id="L131" class="LineNr">131 </span> <span class="subxS2Comment"># . . push args</span> <span id="L132" class="LineNr">132 </span> 68/push _test-stream2/imm32 <span id="L133" class="LineNr">133 </span> <span class="subxS2Comment"># . . call</span> <span id="L134" class="LineNr">134 </span> e8/call clear-stream/disp32 <span id="L135" class="LineNr">135 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L136" class="LineNr">136 </span> 81 0/subop/add 3/mod/direct 4/rm32/ESP <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 4/imm32 <span class="subxComment"># add to ESP</span> <span id="L137" class="LineNr">137 </span> <span class="subxS1Comment"># . write(_test-stream2, &quot;Ab&quot;)</span> <span id="L138" class="LineNr">138 </span> <span class="subxS2Comment"># . . push args</span> <span id="L139" class="LineNr">139 </span> 68/push <span class="Constant">&quot;Ab&quot;</span>/imm32 <span id="L140" class="LineNr">140 </span> 68/push _test-stream2/imm32 <span id="L141" class="LineNr">141 </span> <span class="subxS2Comment"># . . call</span> <span id="L142" class="LineNr">142 </span> e8/call write/disp32 <span id="L143" class="LineNr">143 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L144" class="LineNr">144 </span> 81 0/subop/add 3/mod/direct 4/rm32/ESP <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 8/imm32 <span class="subxComment"># add to ESP</span> <span id="L145" class="LineNr">145 </span> <span class="subxComment"># write-stream(_test-stream, _test-stream2)</span> <span id="L146" class="LineNr">146 </span> <span class="subxS2Comment"># . . push args</span> <span id="L147" class="LineNr">147 </span> 68/push _test-stream2/imm32 <span id="L148" class="LineNr">148 </span> 68/push _test-stream/imm32 <span id="L149" class="LineNr">149 </span> <span class="subxS2Comment"># . . call</span> <span id="L150" class="LineNr">150 </span> e8/call write-stream/disp32 <span id="L151" class="LineNr">151 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L152" class="LineNr">152 </span> 81 0/subop/add 3/mod/direct 4/rm32/ESP <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 8/imm32 <span class="subxComment"># add to ESP</span> <span id="L153" class="LineNr">153 </span> <span class="subxComment"># check-ints-equal(*_test-stream-&gt;data, 41/A 62/b 00 00, msg)</span> <span id="L154" class="LineNr">154 </span> <span class="subxS2Comment"># . . push args</span> <span id="L155" class="LineNr">155 </span> 68/push <span class="Constant">&quot;F - test-write-stream-single&quot;</span>/imm32 <span id="L156" class="LineNr">156 </span> 68/push 0x006241/imm32/Ab <span id="L157" class="LineNr">157 </span> <span class="subxS2Comment"># . . push *_test-stream-&gt;data</span> <span id="L158" class="LineNr">158 </span> b8/copy-to-EAX _test-stream/imm32 <span id="L159" class="LineNr">159 </span> ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 0xc/disp8 <span class="CommentedCode"> . </span> <span class="subxComment"># push *(EAX+12)</span> <span id="L160" class="LineNr">160 </span> <span class="subxS2Comment"># . . call</span> <span id="L161" class="LineNr">161 </span> e8/call check-ints-equal/disp32 <span id="L162" class="LineNr">162 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L163" class="LineNr">163 </span> 81 0/subop/add 3/mod/direct 4/rm32/ESP <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 0xc/imm32 <span class="subxComment"># add to ESP</span> <span id="L164" class="LineNr">164 </span> <span class="subxS1Comment"># . end</span> <span id="L165" class="LineNr">165 </span> c3/return <span id="L166" class="LineNr">166 </span> <span id="L167" class="LineNr">167 </span><span class="subxTest">test-write-stream-appends</span>: <span id="L168" class="LineNr">168 </span> <span class="subxComment"># setup</span> <span id="L169" class="LineNr">169 </span> <span class="subxS1Comment"># . clear-stream(_test-stream)</span> <span id="L170" class="LineNr">170 </span> <span class="subxS2Comment"># . . push args</span> <span id="L171" class="LineNr">171 </span> 68/push _test-stream/imm32 <span id="L172" class="LineNr">172 </span> <span class="subxS2Comment"># . . call</span> <span id="L173" class="LineNr">173 </span> e8/call clear-stream/disp32 <span id="L174" class="LineNr">174 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L175" class="LineNr">175 </span> 81 0/subop/add 3/mod/direct 4/rm32/ESP <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 4/imm32 <span class="subxComment"># add to ESP</span> <span id="L176" class="LineNr">176 </span> <span class="subxS1Comment"># . clear-stream(_test-stream2)</span> <span id="L177" class="LineNr">177 </span> <span class="subxS2Comment"># . . push args</span> <span id="L178" class="LineNr">178 </span> 68/push _test-stream2/imm32 <span id="L179" class="LineNr">179 </span> <span class="subxS2Comment"># . . call</span> <span id="L180" class="LineNr">180 </span> e8/call clear-stream/disp32 <span id="L181" class="LineNr">181 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L182" class="LineNr">182 </span> 81 0/subop/add 3/mod/direct 4/rm32/ESP <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 4/imm32 <span class="subxComment"># add to ESP</span> <span id="L183" class="LineNr">183 </span> <span class="subxS1Comment"># . write(_test-stream2, &quot;C&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;C&quot;</span>/imm32 <span id="L186" class="LineNr">186 </span> 68/push _test-stream2/imm32 <span id="L187" class="LineNr">187 </span> <span class="subxS2Comment"># . . call</span> <span id="L188" class="LineNr">188 </span> e8/call write/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="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 8/imm32 <span class="subxComment"># add to ESP</span> <span id="L191" class="LineNr">191 </span> <span class="subxComment"># first write</span> <span id="L192" class="LineNr">192 </span> <span class="subxS1Comment"># . write-stream(_test-stream, _test-stream2)</span> <span id="L193" class="LineNr">193 </span> <span class="subxS2Comment"># . . push args</span> <span id="L194" class="LineNr">194 </span> 68/push _test-stream2/imm32 <span id="L195" class="LineNr">195 </span> 68/push _test-stream/imm32 <span id="L196" class="LineNr">196 </span> <span class="subxS2Comment"># . . call</span> <span id="L197" class="LineNr">197 </span> e8/call write-stream/disp32 <span id="L198" class="LineNr">198 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L199" class="LineNr">199 </span> 81 0/subop/add 3/mod/direct 4/rm32/ESP <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 8/imm32 <span class="subxComment"># add to ESP</span> <span id="L200" class="LineNr">200 </span> <span class="subxComment"># second write</span> <span id="L201" class="LineNr">201 </span> <span class="subxS1Comment"># . write(_test-stream2, &quot;D&quot;)</span> <span id="L202" class="LineNr">202 </span> <span class="subxS2Comment"># . . push args</span> <span id="L203" class="LineNr">203 </span> 68/push <span class="Constant">&quot;D&quot;</span>/imm32 <span id="L204" class="LineNr">204 </span> 68/push _test-stream2/imm32 <span id="L205" class="LineNr">205 </span> <span class="subxS2Comment"># . . call</span> <span id="L206" class="LineNr">206 </span> e8/call write/disp32 <span id="L207" class="LineNr">207 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L208" class="LineNr">208 </span> 81 0/subop/add 3/mod/direct 4/rm32/ESP <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 8/imm32 <span class="subxComment"># add to ESP</span> <span id="L209" class="LineNr">209 </span> <span class="subxS1Comment"># . write-stream(_test-stream, _test-stream2)</span> <span id="L210" class="LineNr">210 </span> <span class="subxS2Comment"># . . push args</span> <span id="L211" class="LineNr">211 </span> 68/push _test-stream2/imm32 <span id="L212" class="LineNr">212 </span> 68/push _test-stream/imm32 <span id="L213" class="LineNr">213 </span> <span class="subxS2Comment"># . . call</span> <span id="L214" class="LineNr">214 </span> e8/call write-stream/disp32 <span id="L215" class="LineNr">215 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L216" class="LineNr">216 </span> 81 0/subop/add 3/mod/direct 4/rm32/ESP <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 8/imm32 <span class="subxComment"># add to ESP</span> <span id="L217" class="LineNr">217 </span> <span class="subxComment"># check-ints-equal(*_test-stream-&gt;data, 43/C 44/D 00 00, msg)</span> <span id="L218" class="LineNr">218 </span> <span class="subxS2Comment"># . . push args</span> <span id="L219" class="LineNr">219 </span> 68/push <span class="Constant">&quot;F - test-write-stream-appends&quot;</span>/imm32 <span id="L220" class="LineNr">220 </span> 68/push 0x00004443/imm32/C-D <span id="L221" class="LineNr">221 </span> <span class="subxS2Comment"># . . push *_test-stream-&gt;data</span> <span id="L222" class="LineNr">222 </span> b8/copy-to-EAX _test-stream/imm32 <span id="L223" class="LineNr">223 </span> ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 0xc/disp8 <span class="CommentedCode"> . </span> <span class="subxComment"># push *(EAX+12)</span> <span id="L224" class="LineNr">224 </span> <span class="subxS2Comment"># . . call</span> <span id="L225" class="LineNr">225 </span> e8/call check-ints-equal/disp32 <span id="L226" class="LineNr">226 </span> <span class="subxS2Comment"># . . discard args</span> <span id="L227" class="LineNr">227 </span> 81 0/subop/add 3/mod/direct 4/rm32/ESP <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> <span class="CommentedCode"> . </span> 0xc/imm32 <span class="subxComment"># add to ESP</span> <span id="L228" class="LineNr">228 </span> <span class="subxS1Comment"># . end</span> <span id="L229" class="LineNr">229 </span> c3/return <span id="L230" class="LineNr">230 </span> <span id="L231" class="LineNr">231 </span>== data <span id="L232" class="LineNr">232 </span> <span id="L233" class="LineNr">233 </span><span class="subxMinorFunction">_test-stream2</span>: <span id="L234" class="LineNr">234 </span> <span class="subxComment"># current write index</span> <span id="L235" class="LineNr">235 </span> 04 00 00 00 <span id="L236" class="LineNr">236 </span> <span class="subxComment"># current read index</span> <span id="L237" class="LineNr">237 </span> 01 00 00 00 <span id="L238" class="LineNr">238 </span> <span class="subxComment"># length (= 8)</span> <span id="L239" class="LineNr">239 </span> 08 00 00 00 <span id="L240" class="LineNr">240 </span> <span class="subxComment"># data</span> <span id="L241" class="LineNr">241 </span> 41 42 43 44 00 00 00 00 <span class="subxComment"># 8 bytes</span> <span id="L242" class="LineNr">242 </span> <span id="L243" class="LineNr">243 </span><span class="subxS2Comment"># . . vim&#0058;nowrap:textwidth=0</span> </pre> </body> </html> <!-- vim: set foldmethod=manual : -->