user: Translate the below assembly code into C programming language:

```asm
<fdt_get_path>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x28,%rsp
  mov    %rdi,%r15
  mov    %esi,%r14d
  mov    %rdx,%rbp
  mov    %ecx,%ebx
  mov    %ecx,0x4(%rsp)
  mov    %fs:0x28,%rax
  mov    %rax,0x18(%rsp)
  xor    %eax,%eax
  call   <fdt_check_header@plt>
  mov    %eax,(%rsp)
  test   %eax,%eax
  jne    L157
  cmp    $0x1,%ebx
  jle    L9
  movl   $0x0,0x10(%rsp)
  test   %r14d,%r14d
  js     L108
  mov    (%rsp),%r12d
  mov    %r12d,%r13d
  mov    %r12d,%edx
  mov    %r12d,%ebx
  lea    0x14(%rsp),%rax
  mov    %rax,0x8(%rsp)
  jmp    L73
L108:
  movl   $0xfffffffc,(%rsp)
  jmp    L157
L164:
  mov    0x14(%rsp),%eax
  mov    %eax,(%rsp)
  jmp    L157
L149:
  cmp    %r13d,%r14d
  je     L116
  lea    0x10(%rsp),%rdx
  mov    %r13d,%esi
  mov    %r15,%rdi
  call   <fdt_next_node@plt>
  mov    %eax,%r13d
  test   %eax,%eax
  js     L136
  cmp    %eax,%r14d
  jl     L136
  mov    0x10(%rsp),%edx
  cmp    %edx,%r12d
  jle    L73
L82:
  lea    -0x1(%rbx),%eax
  cltq
L12:
  mov    %eax,%ebx
  sub    $0x1,%rax
  cmpb   $0x2f,0x0(%rbp,%rax,1)
  jne    L12
  sub    $0x1,%r12d
  cmp    %edx,%r12d
  jne    L82
  mov    %edx,%r12d
L73:
  cmp    %r12d,%edx
  jg     L149
  mov    0x8(%rsp),%rdx
  mov    %r13d,%esi
  mov    %r15,%rdi
  call   <fdt_get_name@plt>
  mov    %rax,%rsi
  test   %rax,%rax
  je     L164
  mov    0x14(%rsp),%edx
  lea    (%rdx,%rbx,1),%eax
  cmp    0x4(%rsp),%eax
  jge    L149
  movslq %ebx,%rdi
  add    %rbp,%rdi
  call   <memcpy@plt>
  mov    %ebx,%eax
  add    0x14(%rsp),%eax
  lea    0x1(%rax),%ebx
  cltq
  movb   $0x2f,0x0(%rbp,%rax,1)
  add    $0x1,%r12d
  jmp    L149
L116:
  cmp    %r12d,0x10(%rsp)
  jge    L79
  cmp    $0x1,%ebx
  setg   %al
  movzbl %al,%eax
  sub    %eax,%ebx
  movslq %ebx,%rbx
  movb   $0x0,0x0(%rbp,%rbx,1)
  jmp    L157
L136:
  cmp    $0xffffffff,%r13d
  jge    L139
  cmp    $0xfffffffc,%r13d
  mov    $0xfffffff5,%eax
  cmovne %r13d,%eax
  mov    %eax,(%rsp)
L157:
  mov    0x18(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L145
  mov    (%rsp),%eax
  add    $0x28,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L9:
  movl   $0xfffffffd,(%rsp)
  jmp    L157
L79:
  movl   $0xfffffffd,(%rsp)
  jmp    L157
L139:
  movl   $0xfffffffc,(%rsp)
  jmp    L157
L145:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen) {
  int pdepth = 0, p = 0;
  int offset, depth, namelen;
  const char *name;
  {
    int err_;
    if ((err_ = fdt_check_header(fdt)) != 0)
      return err_;
  };
  if (buflen < 2)
    return -3;
  for (offset = 0, depth = 0; (offset >= 0) && (offset <= nodeoffset); offset = fdt_next_node(fdt, offset, &depth)) {
    while (pdepth > depth) {
      do {
        p--;
      } while (buf[p - 1] != '/');
      pdepth--;
    }
    if (pdepth >= depth) {
      name = fdt_get_name(fdt, offset, &namelen);
      if (!name)
        return namelen;
      if ((p + namelen + 1) <= buflen) {
        memcpy(buf + p, name, namelen);
        p += namelen;
        buf[p++] = '/';
        pdepth++;
      }
    }
    if (offset == nodeoffset) {
      if (pdepth < (depth + 1))
        return -3;
      if (p > 1)
        p--;
      buf[p] = '\0';
      return 0;
    }
  }
  if ((offset == -1) || (offset >= 0))
    return -4;
  else if (offset == -4)
    return -11;
  return offset;
}
```