about summary refs log tree commit diff stats
path: root/053new-segment.subx
blob: 51f321fdadc909ca630d47928d7f02f4e5830932 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { colo
# Create a new segment (pool of memory for allocating chunks from) in the form
# of an *allocation descriptor* that can be passed to the memory allocator
# (defined in a later layer).
#
# Currently an allocation descriptor consists of just the bounds of the pool of
# available memory:
#
#   curr : address
#   end : address
#
# This isn't enough information to reclaim individual allocations. We can't
# support arbitrary reclamation yet.

== 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

Entry:   # manual test
    # var ad/ecx : (address allocation-descriptor) = {0, 0}
    68/push  0/imm32/limit
    68/push  0/imm32/curr
    89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
    # new-segment(0x1000, ad)
    # . . push args
    51/push-ecx
    68/push  0x1000/imm32
    # . . call
    e8/call  new-segment/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
    # eax = ad->curr
    8b/copy                         0/mod/indirect  1/rm32/ecx    .           .             .           0/r32/eax   .               .                 # copy *ecx to eax
    # write to *eax to check that we have access to the newly-allocated segment
    c7          0/subop/copy        0/mod/direct    0/rm32/eax    .           .             .           .           .               0x34/imm32        # copy to *eax
    # syscall(exit, eax)
    89/copy                         3/mod/direct    3/rm32/ebx    .           .             .           0/r32/eax   .               .                 # copy eax to ebx
    b8/copy-to-eax  1/imm32/exit
    cd/syscall  0x80/imm8

new-segment:  # len : int, ad : (address allocation-descriptor)
    # . prologue
    55/push-ebp
    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
    # . save registers
    50/push-eax
    53/push-ebx
    # copy len to _mmap-new-segment->len
    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           0/r32/eax   8/disp8         .                 # copy *(ebp+8) to eax
    89/copy                         0/mod/indirect  5/rm32/.disp32            .             .           0/r32/eax   _mmap-new-segment:len/disp32      # copy eax to *_mmap-new-segment:len
    # mmap(_mmap-new-segment)
    bb/copy-to-ebx  _mmap-new-segment/imm32
    b8/copy-to-eax  0x5a/imm32/mmap
    cd/syscall  0x80/imm8
    # copy {eax, eax+len} to *ad
    # . ebx = ad
    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           3/r32/ebx   0xc/disp8       .                 # copy *(ebp+12) to ebx
    # . *ebx = eax
    89/copy                         0/mod/indirect  3/rm32/ebx    .           .             .           0/r32/eax   .               .                 # copy eax to *ebx
    # . *(ebx+4) = eax+len
    03/add                          1/mod/*+disp8   5/rm32/ebp    .           .             .           0/r32/eax   8/disp8         .                 # add *(ebp+8) to eax
    89/copy                         1/mod/*+disp8   3/rm32/ebx    .           .             .           0/r32/eax   4/disp8         .                 # copy eax to *(ebx+4)
$new-segment:end:
    # . restore registers
    5b/pop-to-ebx
    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

== data

# various constants used here were found in the Linux sources (search for file mman-common.h)
_mmap-new-segment:  # type mmap_arg_struct
    # addr
    0/imm32
_mmap-new-segment:len:
    # len
    0/imm32
    # protection flags
    3/imm32  # PROT_READ | PROT_WRITE
    # sharing flags
    0x22/imm32  # MAP_PRIVATE | MAP_ANONYMOUS
    # fd
    -1/imm32  # since MAP_ANONYMOUS is specified
    # offset
    0/imm32  # since MAP_ANONYMOUS is specified

# . . vim:nowrap:textwidth=0
/span>; } .muRecipe { color: #ff8700; } .Conceal { color: #4e4e4e; } .Comment { color: #9090ff; } .Comment a { color:#0000ee; text-decoration:underline; } .Delimiter { color: #800080; } .LineNr { color: #444444; } .Constant { color: #00a0a0; } .muControl { color: #c0a020; } --> </style> <script type='text/javascript'> <!-- /* function to open any folds containing a jumped-to line before jumping to it */ function JumpToLine() { var lineNum; lineNum = window.location.hash; lineNum = lineNum.substr(1); /* strip off '#' */ if (lineNum.indexOf('L') == -1) { lineNum = 'L'+lineNum; } lineElem = document.getElementById(lineNum); /* Always jump to new location even if the line was hidden inside a fold, or * we corrected the raw number to a line ID. */ if (lineElem) { lineElem.scrollIntoView(true); } return true; } if ('onhashchange' in window) { window.onhashchange = JumpToLine; } --> </script> </head> <body onload='JumpToLine();'> <pre id='vimCodeElement'> <span id="L1" class="LineNr"> 1 </span><span class="Comment"># example program: running multiple routines</span> <span id="L2" class="LineNr"> 2 </span> <span id="L3" class="LineNr"> 3 </span><span class="muRecipe">def</span> <a href='fork.mu.html#L3'>main</a> [ <span id="L4" class="LineNr"> 4 </span> start-running <a href='fork.mu.html#L11'>thread2</a> <span id="L5" class="LineNr"> 5 </span> <span class="Delimiter">{</span> <span id="L6" class="LineNr"> 6 </span> <span class="Conceal">¦</span> $print<span class="Constant"> 34</span> <span id="L7" class="LineNr"> 7 </span> <span class="Conceal">¦</span> <span class="muControl">loop</span> <span id="L8" class="LineNr"> 8 </span> <span class="Delimiter">}</span> <span id="L9" class="LineNr"> 9 </span>] <span id="L10" class="LineNr">10 </span> <span id="L11" class="LineNr">11 </span><span class="muRecipe">def</span> <a href='fork.mu.html#L11'>thread2</a> [ <span id="L12" class="LineNr">12 </span> <span class="Delimiter">{</span> <span id="L13" class="LineNr">13 </span> <span class="Conceal">¦</span> $print<span class="Constant"> 35</span> <span id="L14" class="LineNr">14 </span> <span class="Conceal">¦</span> <span class="muControl">loop</span> <span id="L15" class="LineNr">15 </span> <span class="Delimiter">}</span> <span id="L16" class="LineNr">16 </span>] </pre> </body> </html> <!-- vim: set foldmethod=manual : -->