https://github.com/akkartik/mu/blob/main/linux/122read-line.subx
  1 == code
  2 #   instruction                     effective address                                                   register    displacement    immediate
  3 # . op          subop               mod             rm32          base        index         scale       r32
  4 # . 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
  5 
  6 # read bytes from 'f' until (and including) a newline and store them into 's'
  7 # 's' fails to grow if and only if no data found
  8 # just abort if 's' is too small
  9 read-line-buffered:  # f: (addr buffered-file), s: (addr stream byte)
 10     # pseudocode:
 11     #   while true
 12     #     if (s->write >= s->size) abort
 13     #     if (f->read >= f->write) populate stream from file
 14     #     if (f->write == 0) break
 15     #     AL = f->data[f->read]
 16     #     s->data[s->write] = AL
 17     #     ++f->read
 18     #     ++s->write
 19     #     if (AL == '\n') break
 20     # . prologue
 21     55/push-ebp
 22     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
 23     # . save registers
 24     50/push-eax
 25     51/push-ecx
 26     52/push-edx
 27     56/push-esi
 28     57/push-edi
 29     # esi = f
 30     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             . 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
	<head>
		<title>andrewyu.org Mailing List Guidelines</title>
		<link rel="stylesheet" href="/plain.css" />
		<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
		<meta charset="utf-8" />
	</head>
	<body class="indent">
		<h1><code>andrewyu.org</code> Mailing List Guidelines</h1>
		The following guidelines apply to most <a href="https://mail.andrewyu.org/mailman/listinfo">public mailing lists on <code>andrewyu.org</code></a>.  Different lists may have different specific guidelines.
		<ul>
			<li>
				Be considerate of other subscribers on the mailing lists.
			</li>
			<li>
				Plain text, preferrably 72 characters per line.
				<br />
				Many subscribers and maintainers read their mail on text-based mailers like mail(1), emacs, mutt, etc., and they often find HTML-formatted messages (or lines that stretch beyond 72 characters) unreadable. Many mailing lists strip messages of MIME content before sending them out to the rest of the list. If you don't use plain text, your messages will be reformatted. If they cannot be reformatted, they will be summarily rejected. Use attachments with care, they will be removed from messages on some lists.
			</li>
			<li>
				Include a useful Subject line.
				<br />
				Messages with an empty Subject will get bounced to the list manager and will take longer to show up. Including a relevant Subject in the message will ensure that more people actually read what you've written. Also, avoid Subject lines with excessive uppercase and exclamations. "Help!" or "I can't get it to work!" are not useful subject lines. Do not change the subject line while on the same topic. You may know what it is regarding, the rest of us who get several hundred messages a day will have no idea.
			</li>
			<li>
				Trim your signature.
				<br />
				Keep the signature lines at the bottom of your mail to a reasonable length. PGP signatures and those automatic address cards are merely annoying and are stripped out. Legal disclaimers and advisories are also very annoying, and inappropriate for public mailing lists.
			</li>
			<li>
				Stay on topic.
				<br />
				Please keep the subject of the post relevant to the topic of the mailing list.
			</li>
			<li>
				Include important information for questions.
				<br />
				Don't waste everyone's time with a hopelessly incomplete question. No one other than you has the information needed to resolve your problem, it is better to provide more information than needed than not enough detail.
			</li>
			<li>
				Respect differences in opinion and philosophy.
				<br />
				Intelligent people may look at the same set of facts and come to very different conclusions. Repeating the same points that didn't convince someone previously rarely changes their mind, and irritates all the other readers.
			</li>
			<li>
				No spam.
			</li>
			<li>
				Interweave quoted original messages with replies.
				<br />
				Post inline, and trim quotes. This means that your replies are interspersed with the original mail, and any irrelevant content is removed (trimmed):
				<pre>From: A
Subject: Re: S
To: B
CC: list

B wrote:
&gt; ...
&gt; Do you think that this is correct?

Yes, I believe so.

&gt; How about iterating through the items and applying the function to each of them?

Sounds good.</pre>
			</li>
			<li>
				Reply to the list.
				<br />
				For most discussions that are not going wildly off-topic and still may be of interest to those in the list, CC the list so others can follow up.  However, as it suggests, if things are going to be irrelevant to the list's topic, reply in private.
			</li>
		</ul>
		<div id="footer">
			<hr />
			<p><a href="/">Andrew Yu's Website</a></p>
		</div>
	</body>
</html>
133 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 134 # write(_test-stream, "ab\ncd") 135 # . . push args 136 68/push "ab\ncd"/imm32 137 68/push _test-stream/imm32 138 # . . call 139 e8/call write/disp32 140 # . . discard args 141 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 142 # read a line from _test-stream (buffered by _test-buffered-file) into _test-tmp-stream 143 # . eax = read-line-buffered(_test-buffered-file, _test-tmp-stream) 144 # . . push args 145 68/push _test-tmp-stream/imm32 146 68/push _test-buffered-file/imm32 147 # . . call 148 e8/call read-line-buffered/disp32 149 # . . discard args 150 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 151 # check-next-stream-line-equal(_test-tmp-stream, "ab", msg) 152 # . . push args 153 68/push "F - test-read-line-buffered"/imm32 154 68/push "ab"/imm32 155 68/push _test-tmp-stream/imm32 156 # . . call 157 e8/call check-next-stream-line-equal/disp32 158 # . . discard args 159 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 160 # end 161 c3/return 162 163 test-read-line-buffered-reads-final-line-until-Eof: 164 # setup 165 # . clear-stream(_test-stream) 166 # . . push args 167 68/push _test-stream/imm32 168 # . . call 169 e8/call clear-stream/disp32 170 # . . discard args 171 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 172 # . clear-stream($_test-buffered-file->buffer) 173 # . . push args 174 68/push $_test-buffered-file->buffer/imm32 175 # . . call 176 e8/call clear-stream/disp32 177 # . . discard args 178 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 179 # . clear-stream(_test-tmp-stream) 180 # . . push args 181 68/push _test-tmp-stream/imm32 182 # . . call 183 e8/call clear-stream/disp32 184 # . . discard args 185 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 186 # write(_test-stream, "cd") 187 # . . push args 188 68/push "cd"/imm32 189 68/push _test-stream/imm32 190 # . . call 191 e8/call write/disp32 192 # . . discard args 193 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 194 # read a line from _test-stream (buffered by _test-buffered-file) into _test-tmp-stream 195 # . eax = read-line-buffered(_test-buffered-file, _test-tmp-stream) 196 # . . push args 197 68/push _test-tmp-stream/imm32 198 68/push _test-buffered-file/imm32 199 # . . call 200 e8/call read-line-buffered/disp32 201 # . . discard args 202 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 203 # check-stream-equal(_test-tmp-stream, "cd", msg) 204 # . . push args 205 68/push "F - test-read-line-buffered-reads-final-line-until-Eof"/imm32 206 68/push "cd"/imm32 207 68/push _test-tmp-stream/imm32 208 # . . call 209 e8/call check-stream-equal/disp32 210 # . . discard args 211 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 212 # end 213 c3/return 214 215 # read bytes from 'f' until (and including) a newline and store them into 's' 216 # 's' fails to grow if and only if no data found 217 # just abort if 's' is too small 218 read-line: # f: (addr stream byte), s: (addr stream byte) 219 # pseudocode: 220 # while true 221 # if (s->write >= s->size) abort 222 # if (f->read >= f->write) break 223 # AL = f->data[f->read] 224 # s->data[s->write] = AL 225 # ++f->read 226 # ++s->write 227 # if (AL == '\n') break 228 # . prologue 229 55/push-ebp 230 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 231 # . save registers 232 50/push-eax 233 51/push-ecx 234 52/push-edx 235 56/push-esi 236 57/push-edi 237 # esi = f 238 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi 239 # ecx = f->read 240 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 4/disp8 . # copy *(esi+4) to ecx 241 # edi = s 242 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi 243 # edx = s->write 244 8b/copy 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # copy *edi to edx 245 $read-line:loop: 246 # if (s->write >= s->size) abort 247 3b/compare 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 . # compare edx with *(edi+8) 248 0f 8d/jump-if->= $read-line:abort/disp32 249 # if (f->read >= f->write) break 250 3b/compare 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # compare ecx with *esi 251 7d/jump-if->= $read-line:end/disp8 252 # AL = f->data[f->read] 253 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 254 8a/copy-byte 1/mod/*+disp8 4/rm32/sib 6/base/esi 1/index/ecx . 0/r32/AL 0xc/disp8 . # copy byte at *(esi+ecx+12) to AL 255 # s->data[s->write] = AL 256 88/copy-byte 1/mod/*+disp8 4/rm32/sib 7/base/edi 2/index/edx . 0/r32/AL 0xc/disp8 . # copy AL to *(edi+edx+12) 257 # ++f->read 258 41/increment-ecx 259 # ++s->write 260 42/increment-edx 261 # if (AL == '\n') return 262 3d/compare-eax-and 0xa/imm32/newline 263 0f 85/jump-if-!= $read-line:loop/disp32 264 $read-line:end: 265 # save f->read 266 89/copy 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 4/disp8 . # copy ecx to *(esi+4) 267 # save s->write 268 89/copy 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # copy edx to *edi 269 # . restore registers 270 5f/pop-to-edi 271 5e/pop-to-esi 272 5a/pop-to-edx 273 59/pop-to-ecx 274 58/pop-to-eax 275 # . epilogue 276 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 277 5d/pop-to-ebp 278 c3/return 279 280 $read-line:abort: 281 # . _write(2/stderr, error) 282 # . . push args 283 68/push "read-line: line too long\n"/imm32 284 68/push 2/imm32/stderr 285 # . . call 286 e8/call _write/disp32 287 # . . discard args 288 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 289 # . syscall_exit(1) 290 bb/copy-to-ebx 1/imm32 291 e8/call syscall_exit/disp32 292 # never gets here 293 294 test-read-line: 295 # - check that read-line stops at a newline 296 # setup 297 # . clear-stream(_test-stream) 298 # . . push args 299 68/push _test-stream/imm32 300 # . . call 301 e8/call clear-stream/disp32 302 # . . discard args 303 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 304 # . clear-stream(_test-tmp-stream) 305 # . . push args 306 68/push _test-tmp-stream/imm32 307 # . . call 308 e8/call clear-stream/disp32 309 # . . discard args 310 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 311 # write(_test-stream, "ab\ncd") 312 # . . push args 313 68/push "ab\ncd"/imm32 314 68/push _test-stream/imm32 315 # . . call 316 e8/call write/disp32 317 # . . discard args 318 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 319 # read a line from _test-stream into _test-tmp-stream 320 # . eax = read-line(_test-stream, _test-tmp-stream) 321 # . . push args 322 68/push _test-tmp-stream/imm32 323 68/push _test-stream/imm32 324 # . . call 325 e8/call read-line/disp32 326 # . . discard args 327 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 328 # check-next-stream-line-equal(_test-tmp-stream, "ab", msg) 329 # . . push args 330 68/push "F - test-read-line"/imm32 331 68/push "ab"/imm32 332 68/push _test-tmp-stream/imm32 333 # . . call 334 e8/call check-next-stream-line-equal/disp32 335 # . . discard args 336 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 337 # end 338 c3/return 339 340 test-read-line-reads-final-line-until-Eof: 341 # setup 342 # . clear-stream(_test-stream) 343 # . . push args 344 68/push _test-stream/imm32 345 # . . call 346 e8/call clear-stream/disp32 347 # . . discard args 348 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 349 # . clear-stream(_test-tmp-stream) 350 # . . push args 351 68/push _test-tmp-stream/imm32 352 # . . call 353 e8/call clear-stream/disp32 354 # . . discard args 355 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 356 # write(_test-stream, "cd") 357 # . . push args 358 68/push "cd"/imm32 359 68/push _test-stream/imm32 360 # . . call 361 e8/call write/disp32 362 # . . discard args 363 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 364 # read a line from _test-stream into _test-tmp-stream 365 # . eax = read-line(_test-stream, _test-tmp-stream) 366 # . . push args 367 68/push _test-tmp-stream/imm32 368 68/push _test-stream/imm32 369 # . . call 370 e8/call read-line/disp32 371 # . . discard args 372 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 373 # check-stream-equal(_test-tmp-stream, "cd", msg) 374 # . . push args 375 68/push "F - test-read-line-reads-final-line-until-Eof"/imm32 376 68/push "cd"/imm32 377 68/push _test-tmp-stream/imm32 378 # . . call 379 e8/call check-stream-equal/disp32 380 # . . discard args 381 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 382 # end 383 c3/return 384 385 # . . vim:nowrap:textwidth=0