3
3
; Initialize constants.
4
4
mov r12 , 65537 ; Exponent to modular-exponentiate with
5
5
mov rbx , 235 ; Modulus to modular-exponentiate with
6
- mov r15 , NPROCS ; Number of processes to fork.
6
+ mov r15 , NPROCS ; Number of worker processes to fork.
7
7
mov r14 , (SIZE + 1 ) * 8 ; Size of shared memory; reserving first
8
8
; 64 bits for bookkeeping
9
9
13
13
14
14
open_file:
15
15
; We have a file specified on the command line, so open() it.
16
- mov rax , SYSCALL_OPEN
17
- mov rdi , [ rsp + 2 * 8 ]
18
- mov rsi , O_RDWR|O_CRE AT ; read/write mode; create if necessary
19
- mov rdx , 0o660 ; `chmod`-mode of file to create (octal)
20
- syscall
16
+ mov rax , SYSCALL_OPEN ; set up open()
17
+ mov rdi , [ rsp + 2 * 8 ] ; filename from command line
18
+ mov rsi , O_RDWR|O_CRE AT ; read/write mode; create if necessary
19
+ mov rdx , 660o ; `chmod`-mode of file to create (octal)
20
+ syscall ; do open() system call
21
21
mov r13 , rax ; preserve file descriptor in r13
22
- mov rax , SYSCALL_PWRITE ; adjust file size by writing to "end"
23
- mov rdi , r13
24
- mov rsi , null_byte ; write a null byte
25
- mov rdx , 1 ; just one byte
26
- mov r10 , r14 ; at offset of our desired file size
27
- dec r10 ; minus one
28
- syscall
22
+ mov rax , SYSCALL_FTRUNCATE ; set up ftruncate() to adjust file size
23
+ mov rdi , r13 ; file descriptor
24
+ mov rsi , r14 ; desired file size
25
+ syscall ; do ftruncate() system call
29
26
mov r8 , r13
30
27
mov r10 , MAP_SHARED
31
28
jmp mmap
32
29
30
+ ; Ask the kernel for a shared memory mapping.
33
31
map_anon:
34
- mov r10 , MAP_SHARED|MAP_ANON ; MAP_ANON means not backed by a file
35
- mov r8 , - 1 ; thus our file descriptor is -1
32
+ mov r10 , MAP_SHARED|MAP_ANON ; MAP_ANON means not backed by a file
33
+ mov r8 , - 1 ; thus our file descriptor is -1
36
34
mmap:
37
- mov r9 , 0 ; ...and there's no file offset in either case.
38
- ; Ask the kernel for a shared memory mapping.
39
- mov eax , SYSCALL_MMAP
40
- mov rdx , PROT_READ|PROT_WRITE ; We'd like a read/write mapping
41
- mov rdi , 0 ; at no pre-specified memory location.
42
- mov rsi , r14 ; Length of the mapping in bytes.
43
- syscall ; Do system call.
35
+ mov r9 , 0 ; and there's no file offset in either case.
36
+ mov rax , SYSCALL_MMAP ; set up mmap()
37
+ mov rdx , PROT_READ|PROT_WRITE ; We'd like a read/write mapping
38
+ mov rdi , 0 ; at no pre-specified memory location.
39
+ mov rsi , r14 ; Length of the mapping in bytes.
40
+ syscall ; do mmap() system call.
44
41
test rax , rax ; Return value will be in rax.
45
42
js error ; If it's negative, that's trouble.
46
43
mov rbp , rax ; Otherwise, we have our memory region [rbp].
47
44
48
- lock add [ rbp ], r15 ; Initialize the first machine word to NPROCS .
45
+ lock add [ rbp ], r15 ; Add NPROCS to the file's first machine word.
49
46
; We'll use it to track the # of still-running
50
- ; processes.
47
+ ; worker processes.
51
48
52
49
; Next, fork NPROCS processes.
53
50
fork:
54
51
mov eax , SYSCALL_FORK
55
52
syscall
56
- %ifidn __OUTPUT_FORMAT__ , elf64
53
+ %ifidn __OUTPUT_FORMAT__ , elf64 ; (This means we're running on Linux)
57
54
test rax , rax ; We're a child iff return value of fork()==0.
58
55
jz child
59
- %elifidn __OUTPUT_FORMAT__ , macho64
56
+ %elifidn __OUTPUT_FORMAT__ , macho64 ; (This means we're running on OSX)
60
57
test rdx , rdx ; Apple...you're not supposed to touch rdx here
61
58
jnz child ; Apple, what
62
59
%endif
66
63
parent:
67
64
pause
68
65
cmp qword [ rbp ], 0
69
- jnz parent ; Wait for [rbp] to be zero
66
+ jnz parent ; Wait for [rbp], the worker count, to be zero
70
67
%ifndef NOPRINT
71
68
mov rbx , rbp
72
69
add rbx , r14 ; rbx marks the end of the [rbp] region
@@ -84,7 +81,7 @@ print_loop:
84
81
jne print_loop
85
82
%endif
86
83
87
- success :
84
+ exit_success :
88
85
mov eax , SYSCALL_EXIT ; Normal exit
89
86
mov edi , 0
90
87
syscall
@@ -102,17 +99,17 @@ find_work: ; and try to find a piece of work to claim
102
99
jz found_work ; If successful, zero flag is set
103
100
.moveon:
104
101
add rdi , 8 ; Otherwise, try a different piece.
105
- .next:
102
+ find_work .next:
106
103
cmp rdi , rsi ; Make sure we haven't hit the end.
107
104
jne find_work
108
105
109
106
child_exit: ; If we have hit the end, we're done.
110
107
lock dec qword [ rbp ] ; Atomic-decrement the # of active processes.
111
- jmp success
108
+ jmp exit_success
112
109
113
110
found_work:
114
- mov r8 , 8 ; There are 8 tasks per piece .
115
- do_task : ; This part does the actual work of mod-exp.
111
+ mov r8 , 8 ; There are 8 pieces per task .
112
+ do_piece : ; This part does the actual work of mod-exp.
116
113
mov r13 , r12 ; Copy exponent to r13.
117
114
mov rax , rdi ; The actual value to mod-exp should start
118
115
sub eax , 0x7 ; at 1 for the first byte after the bookkeeping
@@ -137,9 +134,9 @@ do_task: ; This part does the actual work of mod-exp.
137
134
jnz .modexploop ; If the exponent isn't zero, keep working
138
135
mov byte [ rbp + rdi ], al ; Else, store result byte.
139
136
inc rdi ; Move forward
140
- dec r8 ; Decrement task counter
141
- jnz do_task ; Do the next task if there is one.
142
- jmp find_work.next ; Else, find the next piece of work .
137
+ dec r8 ; Decrement piece counter
138
+ jnz do_piece ; Do the next piece if there is one.
139
+ jmp find_work.next ; Else, find the next task .
143
140
144
141
error:
145
142
mov rdi , rax ; In case of error, return code is -errno...
@@ -152,10 +149,4 @@ error:
152
149
section .data
153
150
unsigned_int:
154
151
db `%u\n`
155
- null_byte:
156
- db 0
157
- %else
158
- section .data
159
- null_byte:
160
- db 0
161
152
%endif
0 commit comments