Βρείτε πρώτους αριθμούς – à la Assembly!


Να είναι πρώτος – ή να μην είναι? Κοίτα να δεις κάτι ερωτηματικά που με βασανίζουν εν μέσω θέρους και δει καύσωνος! 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

Σού άρεσε? Πρότεινέ το σ' έναν φίλο!

Συναφή Άρθρα

Κάνε ένα σχόλιο τώρα (όσο προλαβαίνεις...)



THOUGHT of the DAY

Always mind the pot odds, before betting.

18/01/2012