Βρείτε πρώτους αριθμούς – à la Assembly!
Όταν ο Dr.Kameleon έγραφε, η μέρα ήτο 25/7/2009 και η ώρα 03:16
Να είναι πρώτος – ή να μην είναι? Κοίτα να δεις κάτι ερωτηματικά που με βασανίζουν εν μέσω θέρους και δει καύσωνος! lol
Το μόνο σίγουρο είναι ότι, για να φρεσκάρω λιγουλάκι την ξεχασμένη μου assembly (a.k.a. “hard candy” lol) – η οποία και θα μού χρησιμεύσει σε ένα τρέχον ΜΕΓΑΛΟ και πολύ πολύ φιλόδοξο προγραμματιστικό project, που ως ιδέα με καταδιώκει παιδιόθεν – τελικά κατέληξα να γράφω (πάλι) κώδικες και να κάθομαι ξημερωματιάτικα ν’ ασχολούμαι καταχωρητές της CPU, σε 32-bit Protected Mode.
ΠΡΟΣΟΧΗ, ΠΡΟΣΟΧΗ :
- Αν είσαι φυσιολογικός άνθρωπος, και η μόνη νοηματική σύνδεση που κάνεις με τη λέξη “πρόγραμμα” είναι αυτό της τηλεόρασης, φύγε εγκαίρως – το παρακάτω μπορεί να αποβει μοιραίο…
- Αν είσαι κ-αρχάριος ή μέσος προγραμματιστής, συνέχισε με δική σου ευθύνη. Πού ξέρεις… μπορεί η περιέργεια και να ωφελήσει τη… γάτα :-p
- Αν είσαι γκουρού στην Assembly, + όταν μικρό σου έλεγαν “μέτρησε μέχρι το δέκα” απαντούσες “1, 10, 11, 100, 101, 110, 111, 1000, 1001, 1010″ + έχεις όρεξη να παιδευτείς μ’ ένα ενδιαφέρον project, επικοινώνησε μαζί μου! lol
Τι θα χρειαστείτε πριν ?
Υπομονή! (αστειεύομαι… lol)
Το πακετάκι με τα Utils (που περιέχει τα macros “print_string”, “print_int” και “read_int”) μπορείτε να το βρείτε εδώ. (Δε λέω… είναι απλά ΓΑΜΑΤΟ το να ξαναμανα-ανακαλύπτεις τον τροχό, αλλά και μια ελάχιστη χείρα βοηθείας είναι ευπρόσδεκτη…)
Για να το εκτελέσετε…
nasm -f elf primetest.asm
gcc -o primetest primetest.o driver.c asm_io.o
./primetest
The Code
;
; PRIMETEST.ASM
; ---------------------------
; Primality-Testing Algorithm written in NASM (Netwide Assembler)
;
; by Dr.Kameleon
;
%include "asm_io.inc"
segment .data
welcome db "PrimeTest - by Dr.Kameleon", 10, 0
line db "=====================================", 10, 10, 0
ask_for_number db "Give me a number (0 to exit) : ", 0
goodbye db 10, "This is the end, my only friend the end...", 10, 10, 0
is_prime db "** This IS a prime", 10, 10, 0
is_not_prime db "** This is NOT a prime", 10, 10, 0
segment .bss
num resd 1
x resd 1
halfnum resd 1
segment .text
global asm_main
asm_main:
pusha
mov eax, welcome
call print_string
mov eax, line
call print_string
while_not_done:
mov eax, ask_for_number
call print_string
call read_int
mov [num], eax
cmp dword [num], 0
je finish
cmp dword [num], 2 ; if num=2 ---> IS prime
je prime
mov edx, [num] ; Divide num by EBX
mov ecx, 2
mov eax, edx
shr edx, 16
div ecx
mov dword [halfnum], eax ; halfnum = num/2
mov ebx, 1 ; EBX = 1
loop_x: ; Looping for EBX = 1 to halfnum
inc ebx ; EBX = EBX + 1
mov edx, [num] ; Divide num / EBX
mov ecx, ebx
mov eax, edx
shr edx, 16
div ecx ; EDX = num % EBX
cmp edx, 0
je not_prime ; if EDX=0 ---> NOT prime
cmp ebx, [halfnum] ; if EBX < halfnum
jl loop_x ; .... keep looking!
end_loop_x:
jmp prime
not_prime:
mov eax, is_not_prime
call print_string
jmp continue
prime:
mov eax, is_prime
call print_string
continue:
jmp while_not_done
finish:
mov eax, goodbye
call print_string
popa
leave
ret
Κάνε ένα σχόλιο τώρα (όσο προλαβαίνεις...)