Divisor Summation, SPOJ 74
74. Divisor Summation
Problem code: DIVSUM
Given a natural number n (1 <= n <= 500000), please output the summation of all its proper divisors.
Definition: A proper divisor of a natural number is the divisor that is strictly less than the number.
e.g. number 20 has 5 proper divisors: 1, 2, 4, 5, 10, and the divisor summation is: 1 + 2 + 4 + 5 + 10 = 22.
Input
An integer stating the number of test cases (equal to about 200000), and that many lines follow, each containing one integer between 1 and 500000 inclusive.
Output
One integer each line: the divisor summation of the integer given respectively.
Example
Sample Input:
3
2
10
20
Sample Output:
1
8
22
使用输入输出缓存,第一次使用字符串数组指令STOSD,LOOP循环命令,相对基址变址操作数。
教训:函数调用一定要注意保存寄存器。
1
; spoj74.s
2
3 % define L 500009
4 % define BL 4096
5
6 section .bss
7 bufIn : resb BL
8 pBufInI : resd 1
9 pBufInN : resd 1
10
11 bufOut : resb BL
12 pBufOutN : resd 1
13
14 ans : resd L
15
16 section .text
17 global _start
18
19 _start :
20 mov dword[pBufInI], 0x0
21 mov dword[pBufInN], 0x0
22 mov dword[pBufOutN], 0x0
23 call init
24 call inInt
25 mov ecx, eax
26 CASE :
27 push ecx
28
29 call inInt
30 mov eax, [eax * 4 + ans]
31 call outIntLn
32
33 pop ecx
34 loop CASE
35 EXIT :
36 call flushOut
37
38 mov eax, 0x1
39 mov ebx, 0x0
40 int 0x80
41
42
43 ; func
44 init :
45 xor eax, eax
46 mov edi, ans
47 mov ecx, L
48 cld
49 rep stosd
50
51 mov ecx, L
52 shr ecx, 1
53 initA :
54 mov eax, ecx
55 initC :
56 add eax, ecx
57 cmp eax, L
58 jge initB
59 mov ebx, [eax * 4 + ans]
60 add ebx, ecx
61 mov [eax * 4 + ans], ebx
62 jmp initC
63 initB :
64 loop initA
65 ret
66
67 ; func eax
68 inChar :
69 mov eax, [pBufInI]
70 cmp eax, [pBufInN]
71 jne inCharA
72 mov eax, 0x3
73 mov ebx, 0x0
74 mov ecx, bufIn
75 mov edx, BL
76 int 0x80
77 mov [pBufInN], eax
78 mov dword [pBufInI], 0x0
79 xor eax, eax
80 inCharA :
81 mov bl, [eax + bufIn]
82 inc eax
83 mov [pBufInI], eax
84 movzx eax, bl
85 ret
86
87 ; func eax
88 outChar :
89 mov ebx, [pBufOutN]
90 mov [ebx + bufOut], al
91 inc ebx
92 mov [pBufOutN], ebx
93 cmp ebx, BL
94 jne outCharA
95 call flushOut
96 outCharA :
97 ret
98
99 ; func
100 flushOut :
101 mov eax, 0x4
102 mov ebx, 0x1
103 mov ecx, bufOut
104 mov edx, [pBufOutN]
105 int 0x80
106 mov dword [pBufOutN], 0x0
107 ret
108
109 ; func eax
110 inInt :
111 inIntA :
112 call inChar
113 cmp al, ' 0 '
114 jb inIntA
115 cmp al, ' 9 '
116 ja inIntA
117 xor ebx, ebx
118 push ebx
119 inIntB :
120 mov ebx, eax
121 sub ebx, ' 0 '
122 pop eax
123 xor edx, edx
124 mov ecx, 0xA
125 mul ecx
126 add eax, ebx
127 push eax
128 call inChar
129 cmp al, ' 0 '
130 jb inIntC
131 cmp al, ' 9 '
132 ja inIntC
133 jmp inIntB
134 inIntC :
135 pop eax
136 ret
137
138 ; func eax
139 outIntLn :
140 ; eax == 0
141 test eax, eax
142 jnz outIntLnA
143 mov eax, ' 0 '
144 call outChar
145 mov eax, 0xA
146 call outChar
147 ret
148
149 ; eax != 0
150 outIntLnA :
151 push ebp
152 mov ebp, esp
153 sub esp, 0x40
154 mov ebx, ebp
155 outIntLnB :
156 test eax, eax
157 jz outIntLnC
158 xor edx, edx
159 mov ecx, 0xA
160 div ecx
161 add edx, ' 0 '
162 dec ebx
163 mov [ebx], dl
164 jmp outIntLnB
165 outIntLnC :
166 cmp ebx, ebp
167 je outIntLnD
168 movzx eax, byte [ebx]
169 push ebx ; !!!!!!!!!!!!!!!!
170 call outChar
171 pop ebx ; !!!!!!!!!!!!!!!!
172 inc ebx
173 jmp outIntLnC
174 outIntLnD :
175 mov eax, 0xA
176 call outChar
177 mov esp, ebp
178 pop ebp
179 ret
180
2
3 % define L 500009
4 % define BL 4096
5
6 section .bss
7 bufIn : resb BL
8 pBufInI : resd 1
9 pBufInN : resd 1
10
11 bufOut : resb BL
12 pBufOutN : resd 1
13
14 ans : resd L
15
16 section .text
17 global _start
18
19 _start :
20 mov dword[pBufInI], 0x0
21 mov dword[pBufInN], 0x0
22 mov dword[pBufOutN], 0x0
23 call init
24 call inInt
25 mov ecx, eax
26 CASE :
27 push ecx
28
29 call inInt
30 mov eax, [eax * 4 + ans]
31 call outIntLn
32
33 pop ecx
34 loop CASE
35 EXIT :
36 call flushOut
37
38 mov eax, 0x1
39 mov ebx, 0x0
40 int 0x80
41
42
43 ; func
44 init :
45 xor eax, eax
46 mov edi, ans
47 mov ecx, L
48 cld
49 rep stosd
50
51 mov ecx, L
52 shr ecx, 1
53 initA :
54 mov eax, ecx
55 initC :
56 add eax, ecx
57 cmp eax, L
58 jge initB
59 mov ebx, [eax * 4 + ans]
60 add ebx, ecx
61 mov [eax * 4 + ans], ebx
62 jmp initC
63 initB :
64 loop initA
65 ret
66
67 ; func eax
68 inChar :
69 mov eax, [pBufInI]
70 cmp eax, [pBufInN]
71 jne inCharA
72 mov eax, 0x3
73 mov ebx, 0x0
74 mov ecx, bufIn
75 mov edx, BL
76 int 0x80
77 mov [pBufInN], eax
78 mov dword [pBufInI], 0x0
79 xor eax, eax
80 inCharA :
81 mov bl, [eax + bufIn]
82 inc eax
83 mov [pBufInI], eax
84 movzx eax, bl
85 ret
86
87 ; func eax
88 outChar :
89 mov ebx, [pBufOutN]
90 mov [ebx + bufOut], al
91 inc ebx
92 mov [pBufOutN], ebx
93 cmp ebx, BL
94 jne outCharA
95 call flushOut
96 outCharA :
97 ret
98
99 ; func
100 flushOut :
101 mov eax, 0x4
102 mov ebx, 0x1
103 mov ecx, bufOut
104 mov edx, [pBufOutN]
105 int 0x80
106 mov dword [pBufOutN], 0x0
107 ret
108
109 ; func eax
110 inInt :
111 inIntA :
112 call inChar
113 cmp al, ' 0 '
114 jb inIntA
115 cmp al, ' 9 '
116 ja inIntA
117 xor ebx, ebx
118 push ebx
119 inIntB :
120 mov ebx, eax
121 sub ebx, ' 0 '
122 pop eax
123 xor edx, edx
124 mov ecx, 0xA
125 mul ecx
126 add eax, ebx
127 push eax
128 call inChar
129 cmp al, ' 0 '
130 jb inIntC
131 cmp al, ' 9 '
132 ja inIntC
133 jmp inIntB
134 inIntC :
135 pop eax
136 ret
137
138 ; func eax
139 outIntLn :
140 ; eax == 0
141 test eax, eax
142 jnz outIntLnA
143 mov eax, ' 0 '
144 call outChar
145 mov eax, 0xA
146 call outChar
147 ret
148
149 ; eax != 0
150 outIntLnA :
151 push ebp
152 mov ebp, esp
153 sub esp, 0x40
154 mov ebx, ebp
155 outIntLnB :
156 test eax, eax
157 jz outIntLnC
158 xor edx, edx
159 mov ecx, 0xA
160 div ecx
161 add edx, ' 0 '
162 dec ebx
163 mov [ebx], dl
164 jmp outIntLnB
165 outIntLnC :
166 cmp ebx, ebp
167 je outIntLnD
168 movzx eax, byte [ebx]
169 push ebx ; !!!!!!!!!!!!!!!!
170 call outChar
171 pop ebx ; !!!!!!!!!!!!!!!!
172 inc ebx
173 jmp outIntLnC
174 outIntLnD :
175 mov eax, 0xA
176 call outChar
177 mov esp, ebp
178 pop ebp
179 ret
180