| #include <private/bionic_asm.h> | 
 |  | 
 | // pid_t __bionic_clone(int flags, void* child_stack, pid_t* parent_tid, void* tls, pid_t* child_tid, int (*fn)(void*), void* arg); | 
 | ENTRY(__bionic_clone) | 
 |         pushl   %ebx | 
 |         pushl   %esi | 
 |         pushl   %edi | 
 |  | 
 |         # Load system call arguments into registers. | 
 |         movl    16(%esp), %ebx   # flags | 
 |         movl    20(%esp), %ecx   # child_stack | 
 |         movl    24(%esp), %edx   # parent_tid | 
 |         movl    28(%esp), %esi   # tls | 
 |         movl    32(%esp), %edi   # child_tid | 
 |  | 
 |         # Copy 'fn' and 'arg' onto the child stack | 
 |         movl    36(%esp), %eax   # Read 'fn'. | 
 |         movl    %eax, -16(%ecx)  # Write 'fn'. | 
 |         movl    40(%esp), %eax   # Read 'arg'. | 
 |         movl    %eax, -12(%ecx)  # Write 'arg'. | 
 |         subl    $16, %ecx | 
 |  | 
 |         # Make the system call. | 
 |         movl    $__NR_clone, %eax | 
 |         int     $0x80 | 
 |  | 
 |         # Check result. | 
 |         testl    %eax, %eax | 
 |         jz      .L_bc_child | 
 |         jg      .L_bc_parent | 
 |  | 
 |         # An error occurred, so set errno and return -1. | 
 |         negl    %eax | 
 |         pushl   %eax | 
 |         call    __set_errno | 
 |         addl    $4, %esp | 
 |         jmp     .L_bc_return | 
 |  | 
 | .L_bc_child: | 
 |         # We don't want anyone to unwind past this point. | 
 |         .cfi_undefined %eip | 
 |         call    __start_thread | 
 |         hlt | 
 |  | 
 | .L_bc_parent: | 
 |         # We're the parent; nothing to do. | 
 | .L_bc_return: | 
 |         popl    %edi | 
 |         popl    %esi | 
 |         popl    %ebx | 
 |         ret | 
 | END(__bionic_clone) | 
 | .hidden __bionic_clone |