From 4254408a385f90ffe212e85a7b405054f4e73f5e Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sat, 23 Jan 2021 11:14:07 -0800 Subject: 7549 --- html/baremetal/115write-byte.subx.html | 118 ++++++++++++++++++++++----------- 1 file changed, 81 insertions(+), 37 deletions(-) (limited to 'html/baremetal/115write-byte.subx.html') diff --git a/html/baremetal/115write-byte.subx.html b/html/baremetal/115write-byte.subx.html index 1a23343f..463ddc4d 100644 --- a/html/baremetal/115write-byte.subx.html +++ b/html/baremetal/115write-byte.subx.html @@ -14,11 +14,13 @@ pre { font-family: monospace; color: #000000; background-color: #c6c6c6; } body { font-size:12pt; font-family: monospace; color: #000000; background-color: #c6c6c6; } a { color:inherit; } * { font-size:12pt; font-size: 1em; } +.subxH1Comment { color: #005faf; text-decoration: underline; } .subxComment { color: #005faf; } .subxS1Comment { color: #0000af; } .subxS2Comment { color: #8a8a8a; } .LineNr { } .Constant { color: #008787; } +.subxTest { color: #5f8700; } .subxFunction { color: #af5f00; text-decoration: underline; } .Normal { color: #000000; background-color: #c6c6c6; padding-bottom: 1px; } --> @@ -56,44 +58,86 @@ if ('onhashchange' in window) { https://github.com/akkartik/mu/blob/main/baremetal/115write-byte.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
+ 1 # Write a single byte to a stream.
+ 2 #
+ 3 # We need to do this in machine code because streams need to be opaque types,
+ 4 # and we don't yet support opaque types in Mu.
  5 
- 6 # Write lower byte of 'n' to 'f'.
- 7 append-byte:  # f: (addr stream byte), n: int
- 8     # . prologue
- 9     55/push-ebp
-10     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
-11     # . save registers
-12     51/push-ecx
-13     57/push-edi
-14     # edi = f
-15     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           7/r32/edi   8/disp8         .                 # copy *(ebp+8) to edi
-16     # ecx = f->write
-17     8b/copy                         0/mod/indirect  7/rm32/edi    .           .             .           1/r32/ecx   .               .                 # copy *edi to ecx
-18     # if (f->write >= f->size) abort
-19     3b/compare                      1/mod/*+disp8   7/rm32/edi    .           .             .           1/r32/ecx   8/disp8         .                 # compare ecx with *(edi+8)
-20     7d/jump-if->=  $append-byte:end/disp8  # TODO: abort
-21 $append-byte:to-stream:
-22     # write to stream
-23     # f->data[f->write] = LSB(n)
-24     31/xor                          3/mod/direct    0/rm32/eax    .           .             .           0/r32/eax   .               .                 # clear eax
-25     8a/copy-byte                    1/mod/*+disp8   5/rm32/ebp    .           .             .           0/r32/AL    0xc/disp8       .                 # copy byte at *(ebp+12) to AL
-26     88/copy-byte                    1/mod/*+disp8   4/rm32/sib    7/base/edi  1/index/ecx   .           0/r32/AL    0xc/disp8       .                 # copy AL to *(edi+ecx+12)
-27     # ++f->write
-28     ff          0/subop/increment   0/mod/indirect  7/rm32/edi    .           .             .           .           .               .                 # increment *edi
-29 $append-byte:end:
-30     # . restore registers
-31     5f/pop-to-edi
-32     59/pop-to-ecx
-33     # . epilogue
-34     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
-35     5d/pop-to-ebp
-36     c3/return
-37 
-38 # . . vim:nowrap:textwidth=0
+ 6 == code
+ 7 #   instruction                     effective address                                                   register    displacement    immediate
+ 8 # . op          subop               mod             rm32          base        index         scale       r32
+ 9 # . 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
+10 
+11 # Write lower byte of 'n' to 'f'.
+12 append-byte:  # f: (addr stream byte), n: int
+13     # . prologue
+14     55/push-ebp
+15     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+16     # . save registers
+17     51/push-ecx
+18     57/push-edi
+19     # edi = f
+20     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           7/r32/edi   8/disp8         .                 # copy *(ebp+8) to edi
+21     # ecx = f->write
+22     8b/copy                         0/mod/indirect  7/rm32/edi    .           .             .           1/r32/ecx   .               .                 # copy *edi to ecx
+23     # if (f->write >= f->size) abort
+24     3b/compare                      1/mod/*+disp8   7/rm32/edi    .           .             .           1/r32/ecx   8/disp8         .                 # compare ecx with *(edi+8)
+25     7d/jump-if->=  $append-byte:abort/disp8
+26 $append-byte:to-stream:
+27     # write to stream
+28     # f->data[f->write] = LSB(n)
+29     31/xor                          3/mod/direct    0/rm32/eax    .           .             .           0/r32/eax   .               .                 # clear eax
+30     8a/copy-byte                    1/mod/*+disp8   5/rm32/ebp    .           .             .           0/r32/AL    0xc/disp8       .                 # copy byte at *(ebp+12) to AL
+31     88/copy-byte                    1/mod/*+disp8   4/rm32/sib    7/base/edi  1/index/ecx   .           0/r32/AL    0xc/disp8       .                 # copy AL to *(edi+ecx+12)
+32     # ++f->write
+33     ff          0/subop/increment   0/mod/indirect  7/rm32/edi    .           .             .           .           .               .                 # increment *edi
+34 $append-byte:end:
+35     # . restore registers
+36     5f/pop-to-edi
+37     59/pop-to-ecx
+38     # . epilogue
+39     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+40     5d/pop-to-ebp
+41     c3/return
+42 
+43 $append-byte:abort:
+44     (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "append-byte: out of space\n" 3)  # 3=cyan
+45     {
+46       eb/jump loop/disp8
+47     }
+48     # never gets here
+49 
+50 test-append-byte-single:
+51     # - check that append-byte writes to first byte of 'file'
+52     # setup
+53     # . clear-stream(_test-stream)
+54     # . . push args
+55     68/push  _test-stream/imm32
+56     # . . call
+57     e8/call  clear-stream/disp32
+58     # . . discard args
+59     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+60     # append-byte(_test-stream, 'A')
+61     # . . push args
+62     68/push  0x41/imm32
+63     68/push  _test-stream/imm32
+64     # . . call
+65     e8/call  append-byte/disp32
+66     # . . discard args
+67     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+68     # check-stream-equal(_test-stream, "A", msg)
+69     # . . push args
+70     68/push  "F - test-append-byte-single"/imm32
+71     68/push  "A"/imm32
+72     68/push  _test-stream/imm32
+73     # . . call
+74     e8/call  check-stream-equal/disp32
+75     # . . discard args
+76     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+77     # . end
+78     c3/return
+79 
+80 # . . vim:nowrap:textwidth=0
 
-- cgit 1.4.1-2-gfad0