1 # count for ~1 million instructions thread 1 2 # count for ~2 million instructions thread 2 3 # count for additional 500 million each before exit 4 5 .globl _start 6 _start: 7 8 ################################################# 9 # 1000 cycles in initial thread # 10 ################################################# 11 12 xor %eax,%eax 13 mov $499,%ecx # load counter 14 initial_loop: 15 dec %ecx # repeat count times 16 jnz initial_loop 17 18 19 ##################################################### 20 # Spawn a thread! # 21 ##################################################### 22 clone: 23 mov $120,%eax # clone syscall 24 25 # Note, clone syscall is different than the glibc implementation 26 27 # int clone (flags, stack_pointer,parent_tidptr,child_tidptr,tls) 28 29 30 # Flags in 31 #/usr/include/bits/sched.h 32 # CLONE_THREAD 0x10000 33 # CLONE_SIGHAND 0x800 34 # CLONE_VM 0x100 35 # above must be called together 36 # Below required for Valgrind 37 # CLONE_FS 0x200 38 # CLONE_FILES 0x400 39 40 mov $0x10f00,%ebx 41 42 43 mov $(new_stack+4096),%ecx # new stack 44 45 46 47 mov $0,%edx # args (none) 48 49 int $0x80 50 51 cmp $0,%eax # are we in new thread? 52 jz thread2 # if so, jump to thrad2 53 54 55 ############################################### 56 # thread1 # 57 ############################################### 58 59 thread1: 60 61 mov $499997,%ecx # load counter 62 thread1_loop: 63 dec %ecx # repeat count times 64 jnz thread1_loop 65 66 xor %ebx,%ebx # we return 0 67 jmp exit 68 69 thread2: 70 mov $999997,%ecx # load counter 71 thread2_loop: 72 dec %ecx # repeat count times 73 jnz thread2_loop 74 75 mov $5,%ebx # we return 5 76 77 78 #================================ 79 # Exit 80 #================================ 81 exit: 82 83 # count an additional 500 million 84 85 mov $250000,%ecx # load counter 86 exit_loop: 87 dec %ecx # repeat count times 88 jnz exit_loop 89 90 actual_exit: 91 mov $1,%eax # put exit syscall number (60) in rax 92 int $0x80 93 94 .bss 95 .lcomm new_stack,4096 96