From c56d803cd8a0e3f28328f91aa1d457905a68641a Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Fri, 30 Nov 2018 09:43:49 -0800 Subject: 4796 --- html/subx/059read-byte.subx.html | 307 +++++++++++++++++++-------------------- 1 file changed, 152 insertions(+), 155 deletions(-) (limited to 'html/subx/059read-byte.subx.html') diff --git a/html/subx/059read-byte.subx.html b/html/subx/059read-byte.subx.html index 070d5afb..87eecd8e 100644 --- a/html/subx/059read-byte.subx.html +++ b/html/subx/059read-byte.subx.html @@ -15,14 +15,11 @@ body { font-size: 12pt; font-family: monospace; color: #aaaaaa; background-color a { color:#eeeeee; text-decoration: none; } a:hover { text-decoration: underline; } * { font-size: 12pt; font-size: 1em; } -.CommentedCode { color: #6c6c6c; } +.subxComment { color: #005fff; } .LineNr { color: #444444; } +.CommentedCode { color: #6c6c6c; } .Constant { color: #00a0a0; } -.Delimiter { color: #800080; } .Special { color: #c00000; } -.Comment { color: #9090ff; } -.Comment a { color:#0000ee; text-decoration:underline; } -.SalientComment { color: #00ffff; } --> @@ -57,253 +54,253 @@ if ('onhashchange' in window) {
-  1 # read-byte: one higher-level abstraction atop 'read'.
-  2 #
-  3 # There are many situations where 'read' is a lot to manage, and we need
-  4 # to abstract some details away. One of them is when we want to read a file
-  5 # character by character. In this situation we follow C's FILE data structure,
-  6 # which manages the underlying file descriptor together with the buffer it
-  7 # reads into. We call our version 'buffered-file'. Should be useful with other
-  8 # primitives as well, in later layers.
+  1 # read-byte: one higher-level abstraction atop 'read'.
+  2 #
+  3 # There are many situations where 'read' is a lot to manage, and we need
+  4 # to abstract some details away. One of them is when we want to read a file
+  5 # character by character. In this situation we follow C's FILE data structure,
+  6 # which manages the underlying file descriptor together with the buffer it
+  7 # reads into. We call our version 'buffered-file'. Should be useful with other
+  8 # primitives as well, in later layers.
   9 
  10 == data
  11 
- 12 # The buffered file for standard input. Also illustrates the layout for
- 13 # buffered-file.
+ 12 # The buffered file for standard input. Also illustrates the layout for
+ 13 # buffered-file.
  14 
  15 Stdin:
- 16   # file descriptor or (address stream)
- 17   00 00 00 00  # 0 = standard input
- 18   # current write index
+ 16   # file descriptor or (address stream)
+ 17   00 00 00 00  # 0 = standard input
+ 18   # current write index
  19   00 00 00 00
- 20   # current read index
+ 20   # current read index
  21   00 00 00 00
- 22   # length (8)
+ 22   # length (8)
  23   08 00 00 00
- 24   # data
- 25   00 00 00 00 00 00 00 00  # 8 bytes
+ 24   # data
+ 25   00 00 00 00 00 00 00 00  # 8 bytes
  26 
- 27 # TODO: 8 bytes is too small. We'll need to grow the buffer for efficiency.
+ 27 # TODO: 8 bytes is too small. We'll need to grow the buffer for efficiency.
  28 
  29 == code
- 30 # instruction                     effective address                                                   operand     displacement    immediate
- 31 # op          subop               mod             rm32          base        index         scale       r32
- 32 # 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
+ 30 # instruction                     effective address                                                   operand     displacement    immediate
+ 31 # op          subop               mod             rm32          base        index         scale       r32
+ 32 # 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
  33 
- 34 # main:
- 35   e8/call  run-tests/disp32  # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'.
+ 34 # main:
+ 35   e8/call  run-tests/disp32  # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'.
  36 #?   e8/call  test-read-byte-multiple/disp32
- 37   # syscall(exit, Num-test-failures)
- 38   8b/copy                         0/mod/indirect  5/rm32/.disp32            .             .           3/r32/EBX   Num-test-failures/disp32          # copy *Num-test-failures to EBX
+ 37   # syscall(exit, Num-test-failures)
+ 38   8b/copy                         0/mod/indirect  5/rm32/.disp32            .             .           3/r32/EBX   Num-test-failures/disp32          # copy *Num-test-failures to EBX
  39   b8/copy-to-EAX  1/imm32
  40   cd/syscall  0x80/imm8
  41 
- 42 # return next byte value in EAX, with top 3 bytes cleared.
- 43 # On EOF, return 0xffffffff.
- 44 read-byte:  # f : (address buffered-file) -> byte/EAX
- 45   # prolog
+ 42 # return next byte value in EAX, with top 3 bytes cleared.
+ 43 # On EOF, return 0xffffffff.
+ 44 read-byte:  # f : (address buffered-file) -> byte/EAX
+ 45   # prolog
  46   55/push-EBP
- 47   89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
- 48   # save registers
+ 47   89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+ 48   # save registers
  49   51/push-ECX
  50   56/push-ESI
- 51   # ESI = f
- 52   8b/copy                         1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           6/r32/ESI   8/disp8         .                 # copy *(EBP+8) to ESI
- 53   # ECX = f->read
- 54   8b/copy                         1/mod/*+disp8   6/rm32/ESI    .           .             .           1/r32/ECX   8/disp8         .                 # copy *(ESI+8) to ECX
- 55   ## if (f->read < f->write) read byte from stream
- 56   3b/compare                      1/mod/*+disp8   6/rm32/ESI    .           .             .           1/r32/ECX   4/disp8         .                 # compare ECX with *(ESI+4)
+ 51   # ESI = f
+ 52   8b/copy                         1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           6/r32/ESI   8/disp8         .                 # copy *(EBP+8) to ESI
+ 53   # ECX = f->read
+ 54   8b/copy                         1/mod/*+disp8   6/rm32/ESI    .           .             .           1/r32/ECX   8/disp8         .                 # copy *(ESI+8) to ECX
+ 55   ## if (f->read < f->write) read byte from stream
+ 56   3b/compare                      1/mod/*+disp8   6/rm32/ESI    .           .             .           1/r32/ECX   4/disp8         .                 # compare ECX with *(ESI+4)
  57   7c/jump-if-lesser  $read-byte:from-stream/disp8
- 58   # clear-stream(stream = f+4)
- 59     # push args
- 60   8d/copy-address                 1/mod/*+disp8   6/rm32/ESI    .           .             .           0/r32/EAX   4/disp8         .                 # copy ESI+4 to EAX
+ 58   # clear-stream(stream = f+4)
+ 59     # push args
+ 60   8d/copy-address                 1/mod/*+disp8   6/rm32/ESI    .           .             .           0/r32/EAX   4/disp8         .                 # copy ESI+4 to EAX
  61   50/push-EAX
- 62     # call
+ 62     # call
  63   e8/call  clear-stream/disp32
- 64     # discard args
- 65   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
- 66   # EAX = read(f->fd, stream = f+4)
- 67     # push args
+ 64     # discard args
+ 65   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+ 66   # EAX = read(f->fd, stream = f+4)
+ 67     # push args
  68   50/push-EAX
- 69   ff          6/subop/push        0/mod/indirect  6/rm32/ESI    .           .             .           .           .               .                 # push *ESI
- 70     # call
+ 69   ff          6/subop/push        0/mod/indirect  6/rm32/ESI    .           .             .           .           .               .                 # push *ESI
+ 70     # call
  71   e8/call  read/disp32
- 72     # discard args
- 73   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
- 74   # if EAX = 0 return 0xffffffff
- 75   81          7/subop/compare     3/mod/direct    0/rm32/EAX    .           .             .           .           .               0/imm32           # compare EAX
+ 72     # discard args
+ 73   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+ 74   # if EAX = 0 return 0xffffffff
+ 75   81          7/subop/compare     3/mod/direct    0/rm32/EAX    .           .             .           .           .               0/imm32           # compare EAX
  76   75/jump-if-not-equal  $read-byte:from-stream/disp8
  77   b8/copy-to-EAX  0xffffffff/imm32
  78   eb/jump  $read-byte:end/disp8
  79 $read-byte:from-stream:
- 80   # AL = f->data[f->read]
- 81   31/xor                          3/mod/direct    0/rm32/EAX    .           .             .           0/r32/EAX   .               .                 # clear EAX
- 82   8a/copy-byte                    1/mod/*+disp8   4/rm32/sib    6/base/ESI  1/index/ECX   .           0/r32/AL    0x10/disp8      .                 # copy *(ESI+ECX+16) to AL
- 83   # ++f->read
- 84   ff          0/subop/increment   1/mod/*+disp8   6/rm32/ESI    .           .             .           .           8/disp8         .                 # increment *(ESI+8)
+ 80   # AL = f->data[f->read]
+ 81   31/xor                          3/mod/direct    0/rm32/EAX    .           .             .           0/r32/EAX   .               .                 # clear EAX
+ 82   8a/copy-byte                    1/mod/*+disp8   4/rm32/sib    6/base/ESI  1/index/ECX   .           0/r32/AL    0x10/disp8      .                 # copy *(ESI+ECX+16) to AL
+ 83   # ++f->read
+ 84   ff          0/subop/increment   1/mod/*+disp8   6/rm32/ESI    .           .             .           .           8/disp8         .                 # increment *(ESI+8)
  85 $read-byte:end:
- 86   # restore registers
+ 86   # restore registers
  87   5e/pop-to-ESI
  88   59/pop-to-ECX
- 89   # epilog
- 90   89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+ 89   # epilog
+ 90   89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
  91   5d/pop-to-EBP
  92   c3/return
  93 
- 94 # todo: how should write-byte look? What should it do when the output has no
- 95 # space remaining? Maybe return an error code.
+ 94 # todo: how should write-byte look? What should it do when the output has no
+ 95 # space remaining? Maybe return an error code.
  96 
- 97 ## tests
+ 97 ## tests
  98 
  99 test-read-byte-single:
-100   ## check that read-byte returns first byte of 'file'
-101   # clear-stream(_test-stream)
-102     # push args
+100   ## check that read-byte returns first byte of 'file'
+101   # clear-stream(_test-stream)
+102     # push args
 103   68/push  _test-stream/imm32
-104     # call
+104     # call
 105   e8/call  clear-stream/disp32
-106     # discard args
-107   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-108   # clear-stream(_test-buffered-file+4)
-109     # push args
+106     # discard args
+107   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+108   # clear-stream(_test-buffered-file+4)
+109     # push args
 110   b8/copy-to-EAX  _test-buffered-file/imm32
 111   05/add-to-EAX  4/imm32
 112   50/push-EAX
-113     # call
+113     # call
 114   e8/call  clear-stream/disp32
-115     # discard args
-116   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-117   # write(_test-stream, "Ab")
-118     # push args
+115     # discard args
+116   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+117   # write(_test-stream, "Ab")
+118     # push args
 119   68/push  "Ab"/imm32
 120   68/push  _test-stream/imm32
-121     # call
+121     # call
 122   e8/call  write/disp32
-123     # discard args
-124   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-125   # read-byte(_test-buffered-file)
-126     # push args
+123     # discard args
+124   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+125   # read-byte(_test-buffered-file)
+126     # push args
 127   68/push  _test-buffered-file/imm32
-128     # call
+128     # call
 129   e8/call  read-byte/disp32
-130     # discard args
-131   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-132   # check-ints-equal(EAX, 'A')
-133     # push args
+130     # discard args
+131   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+132   # check-ints-equal(EAX, 'A')
+133     # push args
 134   68/push  "F - test-read-byte-single"/imm32
 135   68/push  0x41/imm32
 136   50/push-EAX
-137     # call
+137     # call
 138   e8/call  check-ints-equal/disp32
-139     # discard args
-140   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-141   # end
+139     # discard args
+140   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+141   # end
 142   c3/return
 143 
 144 test-read-byte-multiple:
-145   ## call read-byte twice, check that second call returns second byte
-146   # clear-stream(_test-stream)
-147     # push args
+145   ## call read-byte twice, check that second call returns second byte
+146   # clear-stream(_test-stream)
+147     # push args
 148   68/push  _test-stream/imm32
-149     # call
+149     # call
 150   e8/call  clear-stream/disp32
-151     # discard args
-152   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-153   # clear-stream(_test-buffered-file+4)
-154     # push args
+151     # discard args
+152   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+153   # clear-stream(_test-buffered-file+4)
+154     # push args
 155   b8/copy-to-EAX  _test-buffered-file/imm32
 156   05/add-to-EAX  4/imm32
 157   50/push-EAX
-158     # call
+158     # call
 159   e8/call  clear-stream/disp32
-160     # discard args
-161   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-162   # write(_test-stream, "Ab")
-163     # push args
+160     # discard args
+161   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+162   # write(_test-stream, "Ab")
+163     # push args
 164   68/push  "Ab"/imm32
 165   68/push  _test-stream/imm32
-166     # call
+166     # call
 167   e8/call  write/disp32
-168     # discard args
-169   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-170   # read-byte(_test-buffered-file)
-171     # push args
+168     # discard args
+169   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+170   # read-byte(_test-buffered-file)
+171     # push args
 172   68/push  _test-buffered-file/imm32
-173     # call
+173     # call
 174   e8/call  read-byte/disp32
-175     # discard args
-176   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-177   # read-byte(_test-buffered-file)
-178     # push args
+175     # discard args
+176   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+177   # read-byte(_test-buffered-file)
+178     # push args
 179   68/push  _test-buffered-file/imm32
-180     # call
+180     # call
 181   e8/call  read-byte/disp32
-182     # discard args
-183   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-184   # check-ints-equal(EAX, 'b')
-185     # push args
+182     # discard args
+183   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+184   # check-ints-equal(EAX, 'b')
+185     # push args
 186   68/push  "F - test-read-byte-multiple"/imm32
 187   68/push  0x62/imm32
 188   50/push-EAX
-189     # call
+189     # call
 190   e8/call  check-ints-equal/disp32
-191     # discard args
-192   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-193   # end
+191     # discard args
+192   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+193   # end
 194   c3/return
 195 
 196 test-read-byte-end-of-file:
-197   ## call read-byte on an empty 'file', check that it returns -1
-198   # clear-stream(_test-stream)
-199     # push args
+197   ## call read-byte on an empty 'file', check that it returns -1
+198   # clear-stream(_test-stream)
+199     # push args
 200   68/push  _test-stream/imm32
-201     # call
+201     # call
 202   e8/call  clear-stream/disp32
-203     # discard args
-204   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-205   # clear-stream(_test-buffered-file+4)
-206     # push args
+203     # discard args
+204   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+205   # clear-stream(_test-buffered-file+4)
+206     # push args
 207   b8/copy-to-EAX  _test-buffered-file/imm32
 208   05/add-to-EAX  4/imm32
 209   50/push-EAX
-210     # call
+210     # call
 211   e8/call  clear-stream/disp32
-212     # discard args
-213   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-214   # read-byte(_test-buffered-file)
-215     # push args
+212     # discard args
+213   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+214   # read-byte(_test-buffered-file)
+215     # push args
 216   68/push  _test-buffered-file/imm32
-217     # call
+217     # call
 218   e8/call  read-byte/disp32
-219     # discard args
-220   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-221   # check-ints-equal(EAX, -1)
-222     # push args
+219     # discard args
+220   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+221   # check-ints-equal(EAX, -1)
+222     # push args
 223   68/push  "F - test-read-byte-end-of-file"/imm32
 224   68/push  -1/imm32
 225   50/push-EAX
-226     # call
+226     # call
 227   e8/call  check-ints-equal/disp32
-228     # discard args
-229   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-230   # end
+228     # discard args
+229   81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+230   # end
 231   c3/return
 232 
 233 == data
 234 
 235 _test-buffered-file:
-236   # file descriptor or (address stream)
+236   # file descriptor or (address stream)
 237   _test-stream/imm32
-238   # current write index
+238   # current write index
 239   00 00 00 00
-240   # current read index
+240   # current read index
 241   00 00 00 00
-242   # length (8)
+242   # length (8)
 243   08 00 00 00
-244   # data
-245   00 00 00 00 00 00 00 00  # 8 bytes
+244   # data
+245   00 00 00 00 00 00 00 00  # 8 bytes
 246 
-247 # vim:nowrap:textwidth=0
+247 # vim:nowrap:textwidth=0
 
-- cgit 1.4.1-2-gfad0