รหัสเครื่อง IA-32 ขนาด 27 ไบต์
hexdump:
60 33 db 8b f9 33 c0 92 43 50 f7 f3 85 d2 75 04
ab 93 ab 93 3b c3 5a 77 ec 61 c3
รหัสที่มา (ไวยากรณ์ MS Visual Studio):
pushad;
xor ebx, ebx;
mov edi, ecx;
myloop:
xor eax, eax;
xchg eax, edx;
inc ebx;
push eax;
div ebx;
test edx, edx;
jnz skip_output;
stosd;
xchg eax, ebx;
stosd;
xchg eax, ebx;
skip_output:
cmp eax, ebx;
pop edx;
ja myloop;
popad;
ret;
First พารามิเตอร์ ( ecx
) เป็นตัวชี้ไปยังผลลัพธ์พารามิเตอร์ที่สอง (edx
) คือตัวเลข มันไม่ได้ทำเครื่องหมายจุดสิ้นสุดของเอาต์พุตในทางใด หนึ่งควรเติมอาร์เรย์เอาต์พุตด้วยศูนย์เพื่อหาจุดสิ้นสุดของรายการ
โปรแกรม C ++ เต็มรูปแบบที่ใช้รหัสนี้:
#include <cstdint>
#include <vector>
#include <iostream>
#include <sstream>
__declspec(naked) void _fastcall doit(uint32_t* d, uint32_t n) {
_asm {
pushad;
xor ebx, ebx;
mov edi, ecx;
myloop:
xor eax, eax;
xchg eax, edx;
inc ebx;
push eax;
div ebx;
test edx, edx;
jnz skip_output;
stosd;
xchg eax, ebx;
stosd;
xchg eax, ebx;
skip_output:
cmp eax, ebx;
pop edx;
ja myloop;
popad;
ret;
}
}
int main(int argc, char* argv[]) {
uint32_t n;
std::stringstream(argv[1]) >> n;
std::vector<uint32_t> list(2 * sqrt(n) + 3); // c++ initializes with zeros
doit(list.data(), n);
for (auto i = list.begin(); *i; ++i)
std::cout << *i << '\n';
}
เอาต์พุตมีข้อบกพร่องบางอย่างแม้ว่าจะเป็นไปตามข้อมูลจำเพาะ (ไม่จำเป็นต้องเรียงลำดับ; ไม่จำเป็นต้องมีเอกลักษณ์)
อินพุต: 69
เอาท์พุท:
69
1
23
3
ตัวหารอยู่ในคู่
อินพุต: 100
เอาท์พุท:
100
1
50
2
25
4
20
5
10
10
สำหรับสี่เหลี่ยมที่สมบูรณ์แบบตัวหารสุดท้ายจะถูกส่งออกสองครั้ง (เป็นคู่กับตัวเอง)
อินพุต: 30
เอาท์พุท:
30
1
15
2
10
3
6
5
5
6
หากอินพุตอยู่ใกล้กับสี่เหลี่ยมจัตุรัสที่สมบูรณ์แบบคู่สุดท้ายจะถูกส่งออกสองครั้ง เป็นเพราะลำดับการตรวจสอบในลูป: อันดับแรกตรวจสอบ "เหลือ = 0" และเอาท์พุทและจากนั้นจะตรวจสอบ "quotient <ตัวหาร" เพื่อออกจากลูป
O(sqrt(n))
เวลา