user: 请显示与下面列出的汇编代码相匹配的C语言实现：

```asm
<do_printf_ui>:
  endbr64
  push   %rbp
  push   %rbx
  sub    $0x38,%rsp
  mov    %fs:0x28,%rax
  mov    %rax,0x28(%rsp)
  xor    %eax,%eax
L252:
  pxor   %xmm0,%xmm0
  movslq %ebp,%rbx
  movaps %xmm0,(%rsp)
  jmp    L331
  nopw   0x0(%rax,%rax,1)
L240:
  cmp    $0x3,%ebx
  jg     L372
  cmp    $0x3,%eax
  je     L199
  mov    %eax,(%rsp,%rbx,4)
  add    $0x1,%rbx
L331:
  xor    %eax,%eax
  mov    %ebx,%ebp
  call   <getchar@plt>
  test   %eax,%eax
  jne    L240
L372:
  mov    %rsp,%rdi
  lea    0x10(%rsp),%rsi
  call   <usbtiny_spi@plt>
  mov    0x10(%rsp),%edi
  test   %edi,%edi
  jne    L8
L110:
  mov    0x14(%rsp),%edi
  test   %edi,%edi
  jne    L475
L488:
  mov    0x18(%rsp),%edi
  test   %edi,%edi
  jne    L126
L4:
  mov    0x1c(%rsp),%edi
  test   %edi,%edi
  jne    L370
L276:
  mov    0x20(%rsp),%edi
  test   %edi,%edi
  jne    L467
L294:
  mov    0x24(%rsp),%edi
  test   %edi,%edi
  jne    L321
L178:
  mov    0x28(%rsp),%edi
  test   %edi,%edi
  jne    L472
L499:
  mov    0x2c(%rsp),%edi
  test   %edi,%edi
  jne    L507
L40:
  mov    0x30(%rsp),%edi
  test   %edi,%edi
  jne    L251
L6:
  mov    0x34(%rsp),%edi
  test   %edi,%edi
  jne    L254
L58:
  mov    0x38(%rsp),%edi
  test   %edi,%edi
  jne    L78
L85:
  mov    0x3c(%rsp),%edi
  test   %edi,%edi
  jne    L339
L299:
  mov    0x40(%rsp),%edi
  test   %edi,%edi
  jne    L535
L444:
  mov    0x44(%rsp),%edi
  test   %edi,%edi
  jne    L474
L375:
  mov    0x48(%rsp),%edi
  test   %edi,%edi
  jne    L393
L7:
  mov    0x4c(%rsp),%edi
  test   %edi,%edi
  jne    L94
L290:
  mov    $0x3e8,%edi
  call   <usleep@plt>
  jmp    L252
  nopw   0x0(%rax,%rax,1)
L199:
  mov    0x28(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L54
  add    $0x38,%rsp
  pop    %rbx
  pop    %rbp
  ret
  nopl   0x0(%rax,%rax,1)
L94:
  call   <isascii@plt>
  test   %rax,%rax
  je     L290
  mov    0x4c(%rsp),%edi
  call   <putchar@plt>
  jmp    L290
  nopl   (%rax)
L393:
  call   <isascii@plt>
  test   %rax,%rax
  je     L7
  mov    0x48(%rsp),%edi
  call   <putchar@plt>
  jmp    L7
  nopl   (%rax)
L474:
  call   <isascii@plt>
  test   %rax,%rax
  je     L375
  mov    0x44(%rsp),%edi
  call   <putchar@plt>
  jmp    L375
L535:
  call   <isascii@plt>
  test   %rax,%rax
  je     L444
  mov    0x40(%rsp),%edi
  call   <putchar@plt>
  jmp    L444
  nopl   0x0(%rax)
L339:
  call   <isascii@plt>
  test   %rax,%rax
  je     L299
  mov    0x3c(%rsp),%edi
  call   <putchar@plt>
  jmp    L299
  nopl   0x0(%rax)
L78:
  call   <isascii@plt>
  test   %rax,%rax
  je     L85
  mov    0x38(%rsp),%edi
  call   <putchar@plt>
  jmp    L85
  nopl   0x0(%rax)
L254:
  call   <isascii@plt>
  test   %rax,%rax
  je     L58
  mov    0x34(%rsp),%edi
  call   <putchar@plt>
  jmp    L58
  nopl   0x0(%rax)
L251:
  call   <isascii@plt>
  test   %rax,%rax
  je     L6
  mov    0x30(%rsp),%edi
  call   <putchar@plt>
  jmp    L6
  nopl   0x0(%rax)
L507:
  call   <isascii@plt>
  test   %rax,%rax
  je     L40
  mov    0x2c(%rsp),%edi
  call   <putchar@plt>
  jmp    L40
  nopl   0x0(%rax)
L472:
  call   <isascii@plt>
  test   %rax,%rax
  je     L499
  mov    0x28(%rsp),%edi
  call   <putchar@plt>
  jmp    L499
  nopl   0x0(%rax)
L321:
  call   <isascii@plt>
  test   %rax,%rax
  je     L178
  mov    0x24(%rsp),%edi
  call   <putchar@plt>
  jmp    L178
  nopl   0x0(%rax)
L467:
  call   <isascii@plt>
  test   %rax,%rax
  je     L294
  mov    0x20(%rsp),%edi
  call   <putchar@plt>
  jmp    L294
  nopl   0x0(%rax)
L370:
  call   <isascii@plt>
  test   %rax,%rax
  je     L276
  mov    0x1c(%rsp),%edi
  call   <putchar@plt>
  jmp    L276
  nopl   0x0(%rax)
L126:
  call   <isascii@plt>
  test   %rax,%rax
  je     L4
  mov    0x18(%rsp),%edi
  call   <putchar@plt>
  jmp    L4
  nopl   0x0(%rax)
L475:
  call   <isascii@plt>
  test   %rax,%rax
  je     L488
  mov    0x14(%rsp),%edi
  call   <putchar@plt>
  jmp    L488
  nopl   0x0(%rax)
L8:
  call   <isascii@plt>
  test   %rax,%rax
  je     L110
  mov    0x10(%rsp),%edi
  call   <putchar@plt>
  jmp    L110
L54:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
void do_printf_ui(void) {
  for (;;) {
    uint8_t input[4] = {0, 0, 0, 0};
    uint8_t output[4];
    {
      uint8_t c;
      uint8_t i;
      while ((c = getchar()) && i < 4) {
        if (c == '\003')
          goto end;
        input[i] = c;
        i++;
      }
    }
    usbtiny_spi(input, output);
    for (uint8_t i = 0; i < sizeof(input); i++) {
      if (output[i] && isascii(output[i]))
        putchar(output[i]);
    }
    usleep(1000);
  }
end:
  return;
}
```