https://github.com/akkartik/mu/blob/master/102kernel-string.subx
 1 # We can't really do much with null-terminated kernel strings, and we don't
 2 # want to. Let's turn them into regular length-prefixed strings at the first
 3 # opportunity.
 4 
 5 == code
 6 
 7 kernel-string-to-string:  # ad: (addr allocation-descriptor), in: (addr kernel-string), out: (addr handle array byte)
 8     # . prologue
 9     55/push-ebp
10     89/<- %ebp 4/r32/esp
11     # . save registers
12     51/push-ecx
13     52/push-edx
14     53/push-ebx
15     56/push-esi
16     57/push-edi
17     # var len/ecx: int = length(in)
18     (kernel-string-length *(ebp+0xc))
19     89/<- %ecx 0/r32/eax
20     # result = allocate-array(ad, len)
21     (allocate-array *(ebp+8) %ecx *(ebp+0x10))
22     # var c/edx: byte = 0
23     ba/copy-to-edx 0/imm32
24     # var src/esi: (addr byte) = in
25     8b/-> *(ebp+0xc) 6/r32/esi
26     # var dest/edi: (addr byte) = result->data
27     8b/-> *(ebp+0x10) 7/r32/edi
28     (lookup *edi *(edi+4))  # => eax
29     8d/copy-address *(eax+4) 7/r32/edi
30     {
31 $kernel-string-to-string:loop:
32       # c = *src
33       8a/byte-> *esi 2/r32/dl
34       # if (c == 0) break
35       81 7/subop/compare %edx 0/imm32
36       74/jump-if-= break/disp8
37       # *dest = c
38       88/byte<- *edi 2/r32/dl
39       # ++src
40       46/increment-esi
41       # ++dest
42       47/increment-edi
43       eb/jump loop/disp8
44     }
45 $kernel-string-to-string:end:
46     # . restore registers
47     5f/pop-to-edi
48     5e/pop-to-esi
49     5b/pop-to-ebx
50     5a/pop-to-edx
51     59/pop-to-ecx
52     # . epilogue
53     89/<- %esp 5/r32/ebp
54     5d/pop-to-ebp
55     c3/return
56 
57 kernel-string-length:  # in: (addr kernel-string) -> result/eax: int
58     # . prologue
59     55/push-ebp
60     89/<- %ebp 4/r32/esp
61     # . save registers
62     51/push-ecx
63     52/push-edx
64     # result = 0
65     b8/copy-to-eax 0/imm32
66     # var c/ecx: byte = 0
67     b9/copy-to-ecx 0/imm32
68     # var curr/edx: (addr byte) = in
69     8b/-> *(ebp+8) 2/r32/edx
70     {
71 $kernel-string-length:loop:
72       # c = *curr
73       8a/byte-> *edx 1/r32/ecx
74       # if (c == 0) break
75       81 7/subop/compare %ecx 0/imm32
76       74/jump-if-= break/disp8
77       # ++curr
78       42/increment-edx
79       # ++result
80       40/increment-eax
81       #
82       eb/jump loop/disp8
83     }
84 $kernel-string-length:end:
85     # . restore registers
86     5a/pop-to-edx
87     59/pop-to-ecx
88     # . epilogue
89     89/<- %esp 5/r32/ebp
90     5d/pop-to-ebp
91     c3/return