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) -> result/eax: (addr 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)  # => eax
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     8d/copy-address *(eax+4) 7/r32/edi
28     {
29 $kernel-string-to-string:loop:
30       # c = *src
31       8a/byte-> *esi 2/r32/edx
32       # if (c == 0) break
33       81 7/subop/compare %edx 0/imm32
34       74/jump-if-= break/disp8
35       # *dest = c
36       88/byte<- *edi 2/r32/edx
37       # ++src
38       46/increment-esi
39       # ++dest
40       47/increment-edi
41       eb/jump loop/disp8
42     }
43 $kernel-string-to-string:end:
44     # . restore registers
45     5f/pop-to-edi
46     5e/pop-to-esi
47     5b/pop-to-ebx
48     5a/pop-to-edx
49     59/pop-to-ecx
50     # . epilogue
51     89/<- %esp 5/r32/ebp
52     5d/pop-to-ebp
53     c3/return
54 
55 kernel-string-length:  # in: (addr kernel-string) -> result/eax: int
56     # . prologue
57     55/push-ebp
58     89/<- %ebp 4/r32/esp
59     # . save registers
60     51/push-ecx
61     52/push-edx
62     # result = 0
63     b8/copy-to-eax 0/imm32
64     # var c/ecx: byte = 0
65     b9/copy-to-ecx 0/imm32
66     # var curr/edx: (addr byte) = in
67     8b/-> *(ebp+8) 2/r32/edx
68     {
69 $kernel-string-length:loop:
70       # c = *curr
71       8a/byte-> *edx 1/r32/ecx
72       # if (c == 0) break
73       81 7/subop/compare %ecx 0/imm32
74       74/jump-if-= break/disp8
75       # ++curr
76       42/increment-edx
77       # ++result
78       40/increment-eax
79       #
80       eb/jump loop/disp8
81     }
82 $kernel-string-length:end:
83     # . restore registers
84     5a/pop-to-edx
85     59/pop-to-ecx
86     # . epilogue
87     89/<- %esp 5/r32/ebp
88     5d/pop-to-ebp
89     c3/return