user: 请从给定的汇编指令推导出C源代码:

```asm
<bn_mul_words>:
  endbr64
  mov    %rdi,%r8
  mov    %edx,%r9d
  mov    %rsi,%rdi
  mov    %rcx,%r10
  xor    %esi,%esi
  test   %edx,%edx
  jle    L13
  test   $0xfffffffc,%edx
  je     L36
  xchg   %ax,%ax
L25:
  sub    $0x4,%r9d
  mov    %r10,%rax
  add    $0x20,%rdi
  add    $0x20,%r8
  mulq   -0x20(%rdi)
  add    %rax,%rsi
  adc    $0x0,%rdx
  mov    %r10,%rax
  mov    %rsi,-0x20(%r8)
  mov    %rdx,%rcx
  mulq   -0x18(%rdi)
  add    %rax,%rcx
  adc    $0x0,%rdx
  mov    %r10,%rax
  mov    %rcx,-0x18(%r8)
  mov    %rdx,%rsi
  mulq   -0x10(%rdi)
  add    %rax,%rsi
  adc    $0x0,%rdx
  mov    %r10,%rax
  mov    %rsi,-0x10(%r8)
  mov    %rdx,%rcx
  mulq   -0x8(%rdi)
  add    %rax,%rcx
  adc    $0x0,%rdx
  mov    %rcx,-0x8(%r8)
  mov    %rdx,%rsi
  test   $0xfffffffc,%r9d
  jne    L25
  test   %r9d,%r9d
  jne    L36
L13:
  mov    %rsi,%rax
  ret
  nopw   0x0(%rax,%rax,1)
L36:
  mov    %r10,%rax
  mulq   (%rdi)
  add    %rax,%rsi
  adc    $0x0,%rdx
  mov    %rsi,(%r8)
  mov    %rdx,%rsi
  cmp    $0x1,%r9d
  je     L13
  mov    %r10,%rax
  mulq   0x8(%rdi)
  add    %rax,%rsi
  adc    $0x0,%rdx
  mov    %rsi,0x8(%r8)
  mov    %rdx,%rsi
  cmp    $0x2,%r9d
  je     L13
  mov    %r10,%rax
  mov    %rsi,%rcx
  mulq   0x10(%rdi)
  add    %rax,%rcx
  adc    $0x0,%rdx
  mov    %rdx,%rsi
  mov    %rcx,0x10(%r8)
  mov    %rsi,%rax
  ret
```

assistant: ```c
unsigned long bn_mul_words(unsigned long *rp, unsigned long *ap, int num, unsigned long w) {
  unsigned long c1 = 0;
  if (num <= 0)
    return (c1);
  while (num & ~3) {
    do {
      register unsigned long high, low;
      asm("mulq %3" : "=a"(low), "=d"(high) : "a"(w), "g"(ap[0]) : "cc");
      asm("addq %2,%0; adcq %3,%1" : "+r"(c1), "+d"(high) : "a"(low), "g"(0) : "cc");
      (rp[0]) = c1, c1 = high;
    } while (0);
    do {
      register unsigned long high, low;
      asm("mulq %3" : "=a"(low), "=d"(high) : "a"(w), "g"(ap[1]) : "cc");
      asm("addq %2,%0; adcq %3,%1" : "+r"(c1), "+d"(high) : "a"(low), "g"(0) : "cc");
      (rp[1]) = c1, c1 = high;
    } while (0);
    do {
      register unsigned long high, low;
      asm("mulq %3" : "=a"(low), "=d"(high) : "a"(w), "g"(ap[2]) : "cc");
      asm("addq %2,%0; adcq %3,%1" : "+r"(c1), "+d"(high) : "a"(low), "g"(0) : "cc");
      (rp[2]) = c1, c1 = high;
    } while (0);
    do {
      register unsigned long high, low;
      asm("mulq %3" : "=a"(low), "=d"(high) : "a"(w), "g"(ap[3]) : "cc");
      asm("addq %2,%0; adcq %3,%1" : "+r"(c1), "+d"(high) : "a"(low), "g"(0) : "cc");
      (rp[3]) = c1, c1 = high;
    } while (0);
    ap += 4;
    rp += 4;
    num -= 4;
  }
  if (num) {
    do {
      register unsigned long high, low;
      asm("mulq %3" : "=a"(low), "=d"(high) : "a"(w), "g"(ap[0]) : "cc");
      asm("addq %2,%0; adcq %3,%1" : "+r"(c1), "+d"(high) : "a"(low), "g"(0) : "cc");
      (rp[0]) = c1, c1 = high;
    } while (0);
    if (--num == 0)
      return c1;
    do {
      register unsigned long high, low;
      asm("mulq %3" : "=a"(low), "=d"(high) : "a"(w), "g"(ap[1]) : "cc");
      asm("addq %2,%0; adcq %3,%1" : "+r"(c1), "+d"(high) : "a"(low), "g"(0) : "cc");
      (rp[1]) = c1, c1 = high;
    } while (0);
    if (--num == 0)
      return c1;
    do {
      register unsigned long high, low;
      asm("mulq %3" : "=a"(low), "=d"(high) : "a"(w), "g"(ap[2]) : "cc");
      asm("addq %2,%0; adcq %3,%1" : "+r"(c1), "+d"(high) : "a"(low), "g"(0) : "cc");
      (rp[2]) = c1, c1 = high;
    } while (0);
  }
  return (c1);
}
```