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