about summary refs log tree commit diff stats
path: root/js/games/nluqo.github.io/~bh/61a-pages/Lectures/unix/index.html?C=S;O=A
blob: db52bcd3aa62ede87f99f06af2fa7991b8232770 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
 <head>
  <title>Index of /~bh/61a-pages/Lectures/unix</title>
 </head>
 <body>
<h1>Index of /~bh/61a-pages/Lectures/unix</h1>
  <table>
   <tr><th valign="top"><img src="../../../../icons/blank.gif" alt="[ICO]"></th><th><a href="index.html?C=N%3BO=A">Name</a></th><th><a href="index.html?C=M%3BO=A">Last modified</a></th><th><a href="index.html?C=S%3BO=D">Size</a></th><th><a href="index.html?C=D%3BO=A">Description</a></th></tr>
   <tr><th colspan="5"><hr></th></tr>
<tr><td valign="top"><img src="../../../../icons/back.gif" alt="[PARENTDIR]"></td><td><a href="../../Lectures">Parent Directory</a>       </td><td>&nbsp;</td><td align="right">  - </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="../../../../icons/unknown.gif" alt="[   ]"></td><td><a href="https://people.eecs.berkeley.edu/~bh/61a-pages/Lectures/unix/spell">spell</a>                  </td><td align="right">2003-02-14 11:00  </td><td align="right">102 </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="../../../../icons/unknown.gif" alt="[   ]"></td><td><a href="steps">steps</a>                  </td><td align="right">2003-02-14 11:00  </td><td align="right">215 </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="../../../../icons/unknown.gif" alt="[   ]"></td><td><a href="words">words</a>                  </td><td align="right">2003-02-14 11:00  </td><td align="right">399K</td><td>&nbsp;</td></tr>
   <tr><th colspan="5"><hr></th></tr>
</table>
</body></html>
a> 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
== 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

# read bytes from 'f' until (and including) a newline and store them into 's'
# 's' fails to grow if and only if no data found
# just abort if 's' is too small
read-line-buffered:  # f: (addr buffered-file), s: (addr stream byte)
    # pseudocode:
    #   while true
    #     if (s->write >= s->length) abort
    #     if (f->read >= f->write) populate stream from file
    #     if (f->write == 0) break
    #     AL = f->data[f->read]
    #     s->data[s->write] = AL
    #     ++f->read
    #     ++s->write
    #     if (AL == '\n') break
    # . 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
    52/push-edx
    56/push-esi
    57/push-edi
    # esi = f
    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   8/disp8         .                 # copy *(ebp+8) to esi
    # ecx = f->read
    8b/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           1/r32/ecx   8/disp8         .                 # copy *(esi+8) to ecx
    # edi = s
    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           7/r32/edi   0xc/disp8       .                 # copy *(ebp+12) to edi
    # edx = s->write
    8b/copy                         0/mod/indirect  7/rm32/edi    .           .             .           2/r32/edx   .               .                 # copy *edi to edx
$read-line-buffered:loop:
    # if (s->write >= s->length) abort
    3b/compare                      1/mod/*+disp8   7/rm32/edi    .           .             .           2/r32/edx   8/disp8         .                 # compare edx with *(edi+8)
    7d/jump-if->=  $read-line-buffered:abort/disp8
    # if (f->read >= f->write) populate stream from file
    3b/compare                      1/mod/*+disp8   6/rm32/esi    .           .             .           1/r32/ecx   4/disp8         .                 # compare ecx with *(esi+4)
    7c/jump-if-<  $read-line-buffered:from-stream/disp8
    # . clear-stream(stream = f+4)
    # . . push args
    8d/copy-address                 1/mod/*+disp8   6/rm32/esi    .           .             .           0/r32/eax   4/disp8         .                 # copy esi+4 to eax
    50/push-eax
    # . . call
    e8/call  clear-stream/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
    # . f->read must now be 0; update its cache at ecx
    31/xor                          3/mod/direct    1/rm32/ecx    .           .             .           1/r32/ecx   .               .                 # clear ecx
    # . eax = read(f->fd, stream = f+4)
    # . . push args
    50/push-eax
    ff          6/subop/push        0/mod/indirect  6/rm32/esi    .           .             .           .           .               .                 # push *esi
    # . . call
    e8/call  read/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
    # if (f->write == 0) break
    # since f->read was initially 0, eax is the same as f->write
    # . if (eax == 0) return true
    3d/compare-eax-and  0/imm32
    74/jump-if-=  $read-line-buffered:end/disp8
$read-line-buffered:from-stream:
    # AL = f->data[f->read]
    31/xor                          3/mod/direct    0/rm32/eax    .           .             .           0/r32/eax   .               .                 # clear eax
    8a/copy-byte                    1/mod/*+disp8   4/rm32/sib    6/base/esi  1/index/ecx   .           0/r32/AL    0x10/disp8      .                 # copy byte at *(esi+ecx+16) to AL
    # s->data[s->write] = AL
    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)
    # ++f->read
    41/increment-ecx
    # ++s->write
    42/increment-edx
    # if (AL == '\n') return
    3d/compare-eax-and  0xa/imm32/newline
    75/jump-if-!=  $read-line-buffered:loop/disp8
$read-line-buffered:end:
    # save f->read
    89/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           1/r32/ecx   8/disp8         .                 # copy ecx to *(esi+8)
    # save s->write
    89/copy                         0/mod/indirect  7/rm32/edi    .           .             .           2/r32/edx   .               .                 # copy edx to *edi
    # . restore registers
    5f/pop-to-edi
    5e/pop-to-esi
    5a/pop-to-edx
    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

$read-line-buffered:abort:
    # . _write(2/stderr, error)
    # . . push args
    68/push  "read-line-buffered: line too long\n"/imm32
    68/push  2/imm32/stderr
    # . . call
    e8/call  _write/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
    # . syscall(exit, 1)
    bb/copy-to-ebx  1/imm32
    b8/copy-to-eax  1/imm32/exit
    cd/syscall  0x80/imm8
    # never gets here

test-read-line-buffered:
    # - check that read-line-buffered stops at a newline
    # 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
    # . clear-stream($_test-buffered-file->buffer)
    # . . push args
    68/push  $_test-buffered-file->buffer/imm32
    # . . call
    e8/call  clear-stream/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
    # . clear-stream(_test-tmp-stream)
    # . . push args
    68/push  _test-tmp-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(_test-stream, "ab\ncd")
    # . . push args
    68/push  "ab\ncd"/imm32
    68/push  _test-stream/imm32
    # . . call
    e8/call  write/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
    # read a line from _test-stream (buffered by _test-buffered-file) into _test-tmp-stream
    # . eax = read-line-buffered(_test-buffered-file, _test-tmp-stream)
    # . . push args
    68/push  _test-tmp-stream/imm32
    68/push  _test-buffered-file/imm32
    # . . call
    e8/call  read-line-buffered/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
    # check-next-stream-line-equal(_test-tmp-stream, "ab", msg)
    # . . push args
    68/push  "F - test-read-line-buffered"/imm32
    68/push  "ab"/imm32
    68/push  _test-tmp-stream/imm32
    # . . call
    e8/call  check-next-stream-line-equal/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
    # end
    c3/return

test-read-line-buffered-reads-final-line-until-Eof:
    # 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
    # . clear-stream($_test-buffered-file->buffer)
    # . . push args
    68/push  $_test-buffered-file->buffer/imm32
    # . . call
    e8/call  clear-stream/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
    # . clear-stream(_test-tmp-stream)
    # . . push args
    68/push  _test-tmp-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(_test-stream, "cd")
    # . . push args
    68/push  "cd"/imm32
    68/push  _test-stream/imm32
    # . . call
    e8/call  write/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
    # read a line from _test-stream (buffered by _test-buffered-file) into _test-tmp-stream
    # . eax = read-line-buffered(_test-buffered-file, _test-tmp-stream)
    # . . push args
    68/push  _test-tmp-stream/imm32
    68/push  _test-buffered-file/imm32
    # . . call
    e8/call  read-line-buffered/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
    # check-stream-equal(_test-tmp-stream, "cd", msg)
    # . . push args
    68/push  "F - test-read-line-buffered-reads-final-line-until-Eof"/imm32
    68/push  "cd"/imm32
    68/push  _test-tmp-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

# read bytes from 'f' until (and including) a newline and store them into 's'
# 's' fails to grow if and only if no data found
# just abort if 's' is too small
read-line:  # f: (addr stream byte), s: (addr stream byte)
    # pseudocode:
    #   while true
    #     if (s->write >= s->length) abort
    #     if (f->read >= f->write) break
    #     AL = f->data[f->read]
    #     s->data[s->write] = AL
    #     ++f->read
    #     ++s->write
    #     if (AL == '\n') break
    # . 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
    52/push-edx
    56/push-esi
    57/push-edi
    # esi = f
    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   8/disp8         .                 # copy *(ebp+8) to esi
    # ecx = f->read
    8b/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           1/r32/ecx   4/disp8         .                 # copy *(esi+4) to ecx
    # edi = s
    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           7/r32/edi   0xc/disp8       .                 # copy *(ebp+12) to edi
    # edx = s->write
    8b/copy                         0/mod/indirect  7/rm32/edi    .           .             .           2/r32/edx   .               .                 # copy *edi to edx
$read-line:loop:
    # if (s->write >= s->length) abort
    3b/compare                      1/mod/*+disp8   7/rm32/edi    .           .             .           2/r32/edx   8/disp8         .                 # compare edx with *(edi+8)
    0f 8d/jump-if->=  $read-line:abort/disp32
    # if (f->read >= f->write) break
    3b/compare                      0/mod/indirect  6/rm32/esi    .           .             .           1/r32/ecx   .               .                 # compare ecx with *esi
    7d/jump-if->=  $read-line:end/disp8
    # AL = f->data[f->read]
    31/xor                          3/mod/direct    0/rm32/eax    .           .             .           0/r32/eax   .               .                 # clear eax
    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
    # s->data[s->write] = AL
    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)
    # ++f->read
    41/increment-ecx
    # ++s->write
    42/increment-edx
    # if (AL == '\n') return
    3d/compare-eax-and  0xa/imm32/newline
    0f 85/jump-if-!=  $read-line:loop/disp32
$read-line:end:
    # save f->read
    89/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           1/r32/ecx   4/disp8         .                 # copy ecx to *(esi+4)
    # save s->write
    89/copy                         0/mod/indirect  7/rm32/edi    .           .             .           2/r32/edx   .               .                 # copy edx to *edi
    # . restore registers
    5f/pop-to-edi
    5e/pop-to-esi
    5a/pop-to-edx
    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

$read-line:abort:
    # . _write(2/stderr, error)
    # . . push args
    68/push  "read-line: line too long\n"/imm32
    68/push  2/imm32/stderr
    # . . call
    e8/call  _write/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
    # . syscall(exit, 1)
    bb/copy-to-ebx  1/imm32
    b8/copy-to-eax  1/imm32/exit
    cd/syscall  0x80/imm8
    # never gets here

test-read-line:
    # - check that read-line stops at a newline
    # 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
    # . clear-stream(_test-tmp-stream)
    # . . push args
    68/push  _test-tmp-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(_test-stream, "ab\ncd")
    # . . push args
    68/push  "ab\ncd"/imm32
    68/push  _test-stream/imm32
    # . . call
    e8/call  write/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
    # read a line from _test-stream into _test-tmp-stream
    # . eax = read-line(_test-stream, _test-tmp-stream)
    # . . push args
    68/push  _test-tmp-stream/imm32
    68/push  _test-stream/imm32
    # . . call
    e8/call  read-line/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
    # check-next-stream-line-equal(_test-tmp-stream, "ab", msg)
    # . . push args
    68/push  "F - test-read-line"/imm32
    68/push  "ab"/imm32
    68/push  _test-tmp-stream/imm32
    # . . call
    e8/call  check-next-stream-line-equal/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
    # end
    c3/return

test-read-line-reads-final-line-until-Eof:
    # 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
    # . clear-stream(_test-tmp-stream)
    # . . push args
    68/push  _test-tmp-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(_test-stream, "cd")
    # . . push args
    68/push  "cd"/imm32
    68/push  _test-stream/imm32
    # . . call
    e8/call  write/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
    # read a line from _test-stream into _test-tmp-stream
    # . eax = read-line(_test-stream, _test-tmp-stream)
    # . . push args
    68/push  _test-tmp-stream/imm32
    68/push  _test-stream/imm32
    # . . call
    e8/call  read-line/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
    # check-stream-equal(_test-tmp-stream, "cd", msg)
    # . . push args
    68/push  "F - test-read-line-reads-final-line-until-Eof"/imm32
    68/push  "cd"/imm32
    68/push  _test-tmp-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