about summary refs log tree commit diff stats
path: root/075print-int-decimal.subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-06-29 18:31:17 -0700
committerKartik Agaram <vc@akkartik.com>2020-06-29 18:31:17 -0700
commit1afc882890399d70926a09036f4e66c33b3972cc (patch)
treec1e6638aea966b49d5d355fc55acca64e63a55b1 /075print-int-decimal.subx
parent690fa191f1533379a21ae9f0253f80068ad1a800 (diff)
downloadmu-1afc882890399d70926a09036f4e66c33b3972cc.tar.gz
6596
Diffstat (limited to '075print-int-decimal.subx')
-rw-r--r--075print-int-decimal.subx466
1 files changed, 0 insertions, 466 deletions
diff --git a/075print-int-decimal.subx b/075print-int-decimal.subx
deleted file mode 100644
index f0039cc4..00000000
--- a/075print-int-decimal.subx
+++ /dev/null
@@ -1,466 +0,0 @@
-# Helper to print an int32 in decimal.
-
-== 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
-
-print-int32-decimal:  # out: (addr stream byte), n: int32
-    # works by generating characters from lowest to highest and pushing them
-    # to the stack, before popping them one by one into the stream
-    #
-    # pseudocode:
-    #   push sentinel
-    #   eax = abs(n)
-    #   while true
-    #     sign-extend eax into edx
-    #     eax, edx = eax/10, eax%10
-    #     edx += '0'
-    #     push edx
-    #     if (eax == 0) break
-    #   if n < 0
-    #     push '-'
-    #   w = out->write
-    #   curr = &out->data[out->write]
-    #   max = &out->data[out->size]
-    #   while true
-    #     pop into eax
-    #     if (eax == sentinel) break
-    #     if (curr >= max) abort
-    #     *curr = AL
-    #     ++curr
-    #     ++w
-    #   out->write = w
-    # (based on K&R itoa: https://en.wikibooks.org/wiki/C_Programming/stdlib.h/itoa)
-    # (this pseudocode contains registers because operations like division
-    # require specific registers in x86)
-    #
-    # . 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
-    53/push-ebx
-    57/push-edi
-    # const ten/ecx = 10
-    b9/copy-to-ecx  0xa/imm32
-    # push sentinel
-    68/push  0/imm32/sentinel
-    # var eax: int = abs(n)
-    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           0/r32/eax   0xc/disp8       .                 # copy *(ebp+12) to eax
-    3d/compare-eax-with  0/imm32
-    7d/jump-if->=  $print-int32-decimal:read-loop/disp8
-$print-int32-decimal:negative:
-    f7          3/subop/negate      3/mod/direct    0/rm32/eax    .           .             .           .           .               .                 # negate eax
-$print-int32-decimal:read-loop:
-    # eax, edx = eax / 10, eax % 10
-    99/sign-extend-eax-into-edx
-    f7          7/subop/idiv        3/mod/direct    1/rm32/ecx    .           .             .           .           .               .                 # divide edx:eax by ecx, storing quotient in eax and remainder in edx
-    # edx += '0'
-    81          0/subop/add         3/mod/direct    2/rm32/edx    .           .             .           .           .               0x30/imm32        # add to edx
-    # push edx
-    52/push-edx
-    # if (eax == 0) break
-    3d/compare-eax-and  0/imm32
-    7f/jump-if->  $print-int32-decimal:read-loop/disp8
-$print-int32-decimal:read-break:
-    # if (n < 0) push('-')
-    81          7/subop/compare     1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0xc/disp8       0/imm32           # compare *(ebp+12)
-    7d/jump-if->=  $print-int32-decimal:write/disp8
-$print-int32-decimal:push-negative:
-    68/push  0x2d/imm32/-
-$print-int32-decimal:write:
-    # edi = out
-    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           7/r32/edi   8/disp8         .                 # copy *(ebp+8) to edi
-    # var w/edx: int = out->write
-    8b/copy                         0/mod/indirect  7/rm32/edi    .           .             .           2/r32/edx   .               .                 # copy *edi to edx
-    # var curr/ecx: (addr byte) = &out->data[out->write]
-    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    7/base/edi  2/index/edx   .           1/r32/ecx   0xc/disp8       .                 # copy ebx+edx+12 to ecx
-    # var max/ebx: (addr byte) = &out->data[out->size]
-    8b/copy                         1/mod/*+disp8   7/rm32/edi    .           .             .           3/r32/ebx   8/disp8         .                 # copy *(edi+8) to ebx
-    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    7/base/edi  3/index/ebx   .           3/r32/ebx   0xc/disp8       .                 # copy edi+ebx+12 to ebx
-$print-int32-decimal:write-loop:
-    # pop into eax
-    58/pop-to-eax
-    # if (eax == sentinel) break
-    3d/compare-eax-and  0/imm32/sentinel
-    74/jump-if-=  $print-int32-decimal:write-break/disp8
-    # if (curr >= max) abort
-    39/compare                      3/mod/direct    1/rm32/ecx    .           .             .           3/r32/ebx   .               .                 # compare ecx with ebx
-    73/jump-if-addr>=  $print-int32-decimal:abort/disp8
-$print-int32-decimal:write-char:
-    # *curr = AL
-    88/copy-byte                    0/mod/indirect  1/rm32/ecx    .           .             .           0/r32/AL    .               .                 # copy AL to byte at *ecx
-    # ++curr
-    41/increment-ecx
-    # ++w
-    42/increment-edx
-    eb/jump  $print-int32-decimal:write-loop/disp8
-$print-int32-decimal:write-break:
-    # out->write = w
-    89/copy                         0/mod/indirect  7/rm32/edi    .           .             .           2/r32/edx   .               .                 # copy edx to *edi
-$print-int32-decimal:end:
-    # . restore registers
-    5f/pop-to-edi
-    5b/pop-to-ebx
-    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
-
-$print-int32-decimal:abort:
-    # . _write(2/stderr, error)
-    # . . push args
-    68/push  "print-int32-decimal: out of space\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
-    e8/call  syscall_exit/disp32
-    # never gets here
-
-test-print-int32-decimal:
-    # - check that a single-digit number converts correctly
-    # 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
-    # print-int32-decimal(_test-stream, 9)
-    # . . push args
-    68/push  9/imm32
-    68/push  _test-stream/imm32
-    # . . call
-    e8/call  print-int32-decimal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # check-stream-equal(_test-stream, "9", msg)
-    # . . push args
-    68/push  "F - test-print-int32-decimal"/imm32
-    68/push  "9"/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
-
-test-print-int32-decimal-zero:
-    # - check that 0 converts correctly
-    # 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
-    # print-int32-decimal(_test-stream, 0)
-    # . . push args
-    68/push  0/imm32
-    68/push  _test-stream/imm32
-    # . . call
-    e8/call  print-int32-decimal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # check-stream-equal(_test-stream, "0", msg)
-    # . . push args
-    68/push  "F - test-print-int32-decimal-zero"/imm32
-    68/push  "0"/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
-
-test-print-int32-decimal-multiple-digits:
-    # - check that a multi-digit number converts correctly
-    # 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
-    # print-int32-decimal(_test-stream, 10)
-    # . . push args
-    68/push  0xa/imm32
-    68/push  _test-stream/imm32
-    # . . call
-    e8/call  print-int32-decimal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # check-stream-equal(_test-stream, "10", msg)
-    # . . push args
-    68/push  "F - test-print-int32-decimal-multiple-digits"/imm32
-    68/push  "10"/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
-
-test-print-int32-decimal-negative:
-    # - check that a negative single-digit number converts correctly
-    # 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
-    # print-int32-decimal(_test-stream, -9)
-    # . . push args
-    68/push  -9/imm32
-    68/push  _test-stream/imm32
-    # . . call
-    e8/call  print-int32-decimal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-#?     # dump _test-stream {{{
-#?     # . write(2/stderr, "^")
-#?     # . . push args
-#?     68/push  "^"/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
-#?     # . write-stream(2/stderr, _test-stream)
-#?     # . . push args
-#?     68/push  _test-stream/imm32
-#?     68/push  2/imm32/stderr
-#?     # . . call
-#?     e8/call  write-stream/disp32
-#?     # . . discard args
-#?     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-#?     # . write(2/stderr, "$\n")
-#?     # . . push args
-#?     68/push  "$\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
-#?     # }}}
-    # check-stream-equal(_test-stream, "-9", msg)
-    # . . push args
-    68/push  "F - test-print-int32-decimal-negative"/imm32
-    68/push  "-9"/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
-
-test-print-int32-decimal-negative-multiple-digits:
-    # - check that a multi-digit number converts correctly
-    # 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
-    # print-int32-decimal(_test-stream, -10)
-    # . . push args
-    68/push  -0xa/imm32
-    68/push  _test-stream/imm32
-    # . . call
-    e8/call  print-int32-decimal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # check-stream-equal(_test-stream, "-10", msg)
-    # . . push args
-    68/push  "F - test-print-int32-decimal-negative-multiple-digits"/imm32
-    68/push  "-10"/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
-
-is-decimal-digit?:  # c: byte -> eax: boolean
-    # . prologue
-    55/push-ebp
-    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
-    # . save registers
-    51/push-ecx
-    # ecx = c
-    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           1/r32/ecx   8/disp8         .                 # copy *(ebp+8) to ecx
-    # result = false
-    b8/copy-to-eax  0/imm32/false
-    # return false if c < '0'
-    81          7/subop/compare     3/mod/direct    1/rm32/ecx    .           .             .           .           .               0x30/imm32        # compare ecx
-    7c/jump-if-<  $is-decimal-digit?:end/disp8
-    # return (c <= '9')
-    81          7/subop/compare     3/mod/direct    1/rm32/ecx    .           .             .           .           .               0x39/imm32        # compare ecx
-    7f/jump-if->  $is-decimal-digit?:end/disp8
-$is-decimal-digit?:true:
-    b8/copy-to-eax  1/imm32/true
-$is-decimal-digit?:end:
-    # . restore registers
-    59/pop-to-ecx
-    # . epilogue
-    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
-    5d/pop-to-ebp
-    c3/return
-
-test-is-decimal-digit-below-0:
-    # eax = is-decimal-digit?(0x2f)
-    # . . push args
-    68/push  0x2f/imm32
-    # . . call
-    e8/call  is-decimal-digit?/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # check-ints-equal(eax, 0, msg)
-    # . . push args
-    68/push  "F - test-is-decimal-digit-below-0"/imm32
-    68/push  0/imm32/false
-    50/push-eax
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-    c3/return
-
-test-is-decimal-digit-0-to-9:
-    # eax = is-decimal-digit?(0x30)
-    # . . push args
-    68/push  0x30/imm32
-    # . . call
-    e8/call  is-decimal-digit?/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # check-ints-equal(eax, 1, msg)
-    # . . push args
-    68/push  "F - test-is-decimal-digit-at-0"/imm32
-    68/push  1/imm32/true
-    50/push-eax
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-    # eax = is-decimal-digit?(0x39)
-    # . . push args
-    68/push  0x39/imm32
-    # . . call
-    e8/call  is-decimal-digit?/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # check-ints-equal(eax, 1, msg)
-    # . . push args
-    68/push  "F - test-is-decimal-digit-at-9"/imm32
-    68/push  1/imm32/true
-    50/push-eax
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-    c3/return
-
-test-is-decimal-digit-above-9:
-    # eax = is-decimal-digit?(0x3a)
-    # . . push args
-    68/push  0x3a/imm32
-    # . . call
-    e8/call  is-decimal-digit?/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # check-ints-equal(eax, 0, msg)
-    # . . push args
-    68/push  "F - test-is-decimal-digit-above-9"/imm32
-    68/push  0/imm32/false
-    50/push-eax
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-    c3/return
-
-to-decimal-digit:  # in: byte -> out/eax: int
-    # . prologue
-    55/push-ebp
-    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
-    # eax = in
-    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           0/r32/eax   8/disp8         .                 # copy *(ebp+8) to eax
-$to-decimal-digit:check0:
-    # if (eax < '0') goto abort
-    3d/compare-eax-with  0x30/imm32/0
-    7c/jump-if-<  $to-decimal-digit:abort/disp8
-$to-decimal-digit:check1:
-    # if (eax > '9') goto abort
-    3d/compare-eax-with  0x39/imm32/f
-    7f/jump-if->  $to-decimal-digit:abort/disp8
-$to-decimal-digit:digit:
-    # return eax - '0'
-    2d/subtract-from-eax  0x30/imm32/0
-$to-decimal-digit:end:
-    # . epilogue
-    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
-    5d/pop-to-ebp
-    c3/return
-
-$to-decimal-digit:abort:
-    # . write-buffered(stderr, error)
-    # . . push args
-    68/push  "to-decimal-digit: not a digit character: "/imm32
-    68/push  Stderr/imm32
-    # . . call
-    e8/call  write-buffered/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # . write-byte-buffered(stderr, %eax)
-    # . . push args
-    50/push-eax
-    68/push  Stderr/imm32
-    # . . call
-#?     e8/call  write-byte-buffered/disp32
-    e8/call  write-int32-hex-buffered/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # . write-buffered(stderr, "\n")
-    # . . push args
-    68/push  Newline/imm32
-    68/push  Stderr/imm32
-    # . . call
-    e8/call  write-buffered/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # . flush(Stderr)
-    # . . push args
-    68/push  Stderr/imm32
-    # . . call
-    e8/call  flush/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # . syscall(exit, 1)
-    bb/copy-to-ebx  1/imm32
-    e8/call  syscall_exit/disp32
-    # never gets here
-
-# . . vim:nowrap:textwidth=0