user: 请将这段汇编代码片段转换成等效的C代码：

```asm
<sad4_one_macroblock>:
  endbr64
  push   %r15
  movslq %r8d,%rax
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x2d8,%rsp
  mov    %rdi,0x88(%rsp)
  lea    0xc0(%rsp),%r8
  mov    %rdx,0x28(%rsp)
  mov    %fs:0x28,%rdx
  mov    %rdx,0x2c8(%rsp)
  mov    %r9d,%edx
  lea    0x2c0(%rsp),%r9
  shl    $0x4,%edx
  lea    -0x11(%rdx),%ebx
  movslq %edx,%rdi
  mov    %edx,0x20(%rsp)
  mov    %rsi,%rdx
  mov    %ebx,0xa4(%rsp)
  add    %rdi,%rdi
  mov    %r8,%rsi
  mov    0x310(%rsp),%ebx
  shl    $0x4,%ebx
  mov    %ebx,0x54(%rsp)
  sub    $0x11,%ebx
  mov    %ebx,0xa0(%rsp)
L29:
  movdqu (%rdx),%xmm0
  add    $0x20,%rsi
  movups %xmm0,-0x20(%rsi)
  movdqu 0x10(%rdx),%xmm1
  add    %rdi,%rdx
  movups %xmm1,-0x10(%rsi)
  cmp    %r9,%rsi
  jne    L29
  movl   $0x1,0x84(%rsp)
  cmp    $0xf,%eax
  jle    L72
  mov    0x20(%rsp),%edx
  sub    $0x20,%edx
  cmp    %eax,%edx
  jle    L47
  cmp    $0xf,%ecx
  jg     L58
L47:
  movl   $0x1,0x84(%rsp)
L72:
  mov    0x20(%rsp),%edx
  sub    $0x10,%ecx
  movq   $0x0,0xa8(%rsp)
  mov    %ecx,0x80(%rsp)
  imul   %edx,%ecx
  mov    %rax,0xb0(%rsp)
  movl   $0x0,0xb8(%rsp)
  mov    %ecx,0x90(%rsp)
  lea    0x0(,%rdx,4),%ecx
  mov    %ecx,0x70(%rsp)
  lea    0x140(%rsp),%rcx
  mov    %rcx,0x98(%rsp)
  lea    0x280(%r8),%rcx
  mov    %rcx,0x78(%rsp)
  lea    -0x10(%rax),%ecx
  mov    %ecx,0xbc(%rsp)
L1:
  mov    0xbc(%rsp),%eax
  mov    %eax,0x50(%rsp)
  mov    0xb0(%rsp),%rax
  sub    $0x10,%rax
  mov    %rax,0x30(%rsp)
  mov    0xb8(%rsp),%eax
  lea    0x448(%rax),%ecx
  add    $0x469,%eax
  mov    %ecx,0x74(%rsp)
  mov    0xa8(%rsp),%rcx
  mov    %eax,0x94(%rsp)
  mov    %rcx,0x48(%rsp)
  nopl   0x0(%rax,%rax,1)
L127:
  mov    0x84(%rsp),%eax
  movl   $0x0,0x24(%rsp)
  test   %eax,%eax
  je     L93
  mov    %eax,0x24(%rsp)
  mov    0x80(%rsp),%ecx
  cmp    %ecx,0xa0(%rsp)
  jl     L93
  mov    0x50(%rsp),%edx
  mov    %edx,%eax
  or     %ecx,%eax
  shr    $0x1f,%eax
  cmp    %edx,0xa4(%rsp)
  setl   %dl
  movzbl %dl,%edx
  or     %eax,%edx
  mov    %edx,0x24(%rsp)
L93:
  movslq 0x74(%rsp),%rax
  mov    %rax,%rsi
  add    %rax,%rax
  mov    %rax,0x58(%rsp)
  lea    0x448(%rsi),%eax
  cltq
  add    %rax,%rax
  mov    %rax,0x60(%rsp)
  lea    0x890(%rsi),%eax
  cltq
  add    %rax,%rax
  mov    %rax,0x68(%rsp)
  mov    0x98(%rsp),%rax
  mov    %rax,0x18(%rsp)
  mov    0x88(%rsp),%rax
  add    0x48(%rsp),%rax
  mov    %rax,0x38(%rsp)
  mov    0x90(%rsp),%eax
  mov    %eax,0x40(%rsp)
  mov    0x80(%rsp),%eax
  mov    %eax,0x44(%rsp)
L76:
  mov    0x18(%rsp),%rax
  mov    0x40(%rsp),%r15d
  xor    %r13d,%r13d
  xor    %r12d,%r12d
  movl   $0x0,0x10(%rsp)
  lea    -0x80(%rax),%rbx
  mov    0x44(%rsp),%eax
  movl   $0x0,0xc(%rsp)
  mov    %eax,0x14(%rsp)
L56:
  mov    0x24(%rsp),%eax
  test   %eax,%eax
  jne    L26
  mov    0x28(%rsp),%rcx
  movslq %r15d,%rax
  add    0x30(%rsp),%rax
  lea    (%rcx,%rax,2),%rbp
L108:
  movswl (%rbx),%eax
  movswl 0x0(%rbp),%edi
  addl   $0x1,0x14(%rsp)
  sub    %eax,%edi
  call   <abs@plt>
  movswl 0x2(%rbp),%edi
  mov    %rax,%r14
  movswl 0x2(%rbx),%eax
  sub    %eax,%edi
  call   <abs@plt>
  movswl 0x4(%rbp),%edi
  add    %eax,%r14d
  movswl 0x4(%rbx),%eax
  add    %r14d,%r12d
  sub    %eax,%edi
  call   <abs@plt>
  movswl 0x6(%rbp),%edi
  add    %eax,%r12d
  movswl 0x6(%rbx),%eax
  sub    %eax,%edi
  call   <abs@plt>
  movswl 0x8(%rbp),%edi
  add    %eax,%r12d
  movswl 0x8(%rbx),%eax
  sub    %eax,%edi
  call   <abs@plt>
  movswl 0xa(%rbp),%edi
  mov    %rax,%r14
  movswl 0xa(%rbx),%eax
  sub    %eax,%edi
  call   <abs@plt>
  movswl 0xc(%rbp),%edi
  add    %eax,%r14d
  movswl 0xc(%rbx),%eax
  add    0xc(%rsp),%r14d
  sub    %eax,%edi
  call   <abs@plt>
  movswl 0xe(%rbp),%edi
  add    %eax,%r14d
  movswl 0xe(%rbx),%eax
  sub    %eax,%edi
  call   <abs@plt>
  movswl 0x10(%rbp),%edi
  add    %r14d,%eax
  mov    %eax,0xc(%rsp)
  movswl 0x10(%rbx),%eax
  sub    %eax,%edi
  call   <abs@plt>
  movswl 0x12(%rbp),%edi
  mov    %rax,%r14
  movswl 0x12(%rbx),%eax
  sub    %eax,%edi
  call   <abs@plt>
  movswl 0x14(%rbp),%edi
  add    %eax,%r14d
  movswl 0x14(%rbx),%eax
  add    0x10(%rsp),%r14d
  sub    %eax,%edi
  call   <abs@plt>
  movswl 0x16(%rbp),%edi
  add    $0x20,%rbx
  add    %eax,%r14d
  movswl -0xa(%rbx),%eax
  sub    %eax,%edi
  call   <abs@plt>
  movswl 0x18(%rbp),%edi
  add    %r14d,%eax
  mov    %eax,0x10(%rsp)
  movswl -0x8(%rbx),%eax
  sub    %eax,%edi
  call   <abs@plt>
  movswl 0x1a(%rbp),%edi
  mov    %rax,%r14
  movswl -0x6(%rbx),%eax
  sub    %eax,%edi
  call   <abs@plt>
  movswl 0x1c(%rbp),%edi
  add    %eax,%r14d
  movswl -0x4(%rbx),%eax
  add    %r14d,%r13d
  sub    %eax,%edi
  call   <abs@plt>
  movswl 0x1e(%rbp),%edi
  add    %eax,%r13d
  movswl -0x2(%rbx),%eax
  sub    %eax,%edi
  call   <abs@plt>
  add    0x20(%rsp),%r15d
  add    %eax,%r13d
  cmp    0x18(%rsp),%rbx
  jne    L56
  mov    0x38(%rsp),%rsi
  mov    0x58(%rsp),%rdx
  movzwl 0xc(%rsp),%ecx
  addl   $0x4,0x44(%rsp)
  mov    %rsi,%rax
  sub    0x48(%rsp),%rax
  mov    %r12w,(%rsi)
  add    $0x2240,%rsi
  mov    %cx,(%rax,%rdx,1)
  mov    0x60(%rsp),%rdx
  movzwl 0x10(%rsp),%ecx
  mov    %rsi,0x38(%rsp)
  mov    %cx,(%rax,%rdx,1)
  mov    0x68(%rsp),%rdx
  mov    0x70(%rsp),%ecx
  add    %ecx,0x40(%rsp)
  mov    %r13w,(%rax,%rdx,1)
  lea    0x80(%rbx),%rax
  mov    %rax,0x18(%rsp)
  cmp    %rax,0x78(%rsp)
  jne    L76
  addl   $0x1,0x74(%rsp)
  mov    0x74(%rsp),%eax
  addq   $0x2,0x48(%rsp)
  addl   $0x1,0x50(%rsp)
  addq   $0x1,0x30(%rsp)
  cmp    0x94(%rsp),%eax
  jne    L127
  addq   $0x42,0xa8(%rsp)
  mov    0xa8(%rsp),%rax
  mov    0x20(%rsp),%ecx
  addl   $0x21,0xb8(%rsp)
  addl   $0x1,0x80(%rsp)
  add    %ecx,0x90(%rsp)
  cmp    $0x882,%rax
  jne    L1
  mov    0x2c8(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L4
  add    $0x2d8,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  xchg   %ax,%ax
L26:
  mov    0x20(%rsp),%r8d
  mov    0x54(%rsp),%ecx
  mov    0x50(%rsp),%edx
  mov    0x14(%rsp),%esi
  mov    0x28(%rsp),%rdi
  call   <create_padded_row@plt>
  mov    %rax,%rbp
  jmp    L108
L58:
  mov    0x54(%rsp),%edx
  sub    $0x20,%edx
  cmp    %ecx,%edx
  setle  %dl
  movzbl %dl,%edx
  mov    %edx,0x84(%rsp)
  jmp    L72
L4:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
void sad4_one_macroblock(unsigned short *macroblock_sad, unsigned short *frame, unsigned short *ref, int frame_y, int frame_x, int mb_width, int mb_height) {
  unsigned short frame_mb[256];
  int pos_x, pos_y;
  int blky, pixy;
  int width = mb_width * 16;
  int max_width = width - 17;
  int height = mb_height * 16;
  int max_height = height - 17;
  int range_partly_outside;
  int pos;
  {
    int x, y;
    for (y = 0; y < 16; y++)
      for (x = 0; x < 16; x++)
        frame_mb[16 * y + x] = frame[width * y + x];
  }
  if ((frame_x >= 16) && (frame_x <= width - 16 - 17) && (frame_y >= 16) && (frame_y <= height - 16 - 17))
    range_partly_outside = 0;
  else
    range_partly_outside = 1;
  pos = 0;
  for (pos_y = -16; pos_y <= 16; pos_y++) {
    for (pos_x = -16; pos_x <= 16; pos_x++, pos++) {
      int y;
      int abs_x, abs_y;
      int do_bounds_check;
      short *curptr = frame_mb;
      short *refptr;
      unsigned short *sad_line = macroblock_sad;
      abs_y = frame_y + pos_y;
      abs_x = frame_x + pos_x;
      do_bounds_check = range_partly_outside && !(abs_y >= 0 && abs_y <= max_height && abs_x >= 0 && abs_x <= max_width);
      for (blky = 0; blky < 4; blky++) {
        int sad0 = 0, sad1 = 0, sad2 = 0, sad3 = 0;
        for (y = 0; y < 4; y++) {
          refptr = do_bounds_check ? create_padded_row(ref, abs_y, abs_x, height, width) : (short *)(ref + abs_y * width + abs_x);
          abs_y++;
          sad0 += abs(*refptr++ - *curptr++);
          sad0 += abs(*refptr++ - *curptr++);
          sad0 += abs(*refptr++ - *curptr++);
          sad0 += abs(*refptr++ - *curptr++);
          sad1 += abs(*refptr++ - *curptr++);
          sad1 += abs(*refptr++ - *curptr++);
          sad1 += abs(*refptr++ - *curptr++);
          sad1 += abs(*refptr++ - *curptr++);
          sad2 += abs(*refptr++ - *curptr++);
          sad2 += abs(*refptr++ - *curptr++);
          sad2 += abs(*refptr++ - *curptr++);
          sad2 += abs(*refptr++ - *curptr++);
          sad3 += abs(*refptr++ - *curptr++);
          sad3 += abs(*refptr++ - *curptr++);
          sad3 += abs(*refptr++ - *curptr++);
          sad3 += abs(*refptr++ - *curptr++);
        }
        sad_line[pos] = sad0;
        sad_line[1096 + pos] = sad1;
        sad_line[1096 * 2 + pos] = sad2;
        sad_line[1096 * 3 + pos] = sad3;
        sad_line += 1096 * 4;
      }
    }
  }
}
```