https://github.com/akkartik/mu/blob/main/linux/303kernel-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