📄 biggest_32bit_unsigned_prime_number_asm8086.asm
字号:
; Find the biggest 32 bit Prime Number.
; The prime number is a number that cannot be
; devided without a reminder by any number less
; than itself and one.
; The calculation time takes a lot of time,
; even if you run this program in DOS prompt.
; Truly, I wasn't able to see the results,
; because probably it would take a day or two
; to find that number, using my algorithm :)
; I higly reccomend using Freeware Tweak Utitity
; from Microsoft, called "DOS HERE", by
; right clicking "MyBuild" folder under
; "Emu8086" installation dir, to see how it runs
; on real CPU.
; When you find this "Magic Number",
; you can make it to be the fastest program ever,
; by just replacing all useless code with one
; PRINT macro from "Emu8086.inc" ;)
; This example, was kindly developed by Emu8086
; users, to support the foundation of our
; new software library: http://www.ziplib.com
; if you love Assembly, please vote for us!
; Devoted to the memory of Yuri Margolin,
; developer and co-founder of the original
; Emu8086 systems, ZipLib library and
; Freethinkers Emu86 forum:
;
; http://www.emu8086.com
; http://www.ziplib.com
; http://www.emu86.com
; Have fun!
; "Herein you will find working code - and cosmetic bugs.
; Each is necessary for the other to exist;
; but each must be recognized for what it is.
; What you see may not always please you; but you WILL SEE! :)"
; --- Yuri Margolin 2004 (C).
; Standard header:
#make_COM# ; optional, used only for Emu8086.com
ORG 100H
; Jump to start:
JMP START
; Data:
msg1 DB 'Finding the biggest 32 bit Prime Number', 13, 10, '...', 13, 10, '$'
msg2 DB ' <-- not prime.', 13, 10, '$'
msg3 DB ' <-- prime number found !', 13, 10, '$'
; Define 32 bit number,
; from two 16 bit values:
wordH DW 0FFFEh
wordL DW 00001h
; instead of "0FFFFFFFFh",
; we start with "0FFFE0001h",
; becaise DIV instruction does
; not support greater numbers :)
; Program's entry point:
START:
; Print "welcome message"
LEA DX, msg1
MOV AH, 9
INT 21h
; Since we need the biggest number, we start checking
; from "FFFFFFFF", for this is the biggest number that
; 32 bit can hold... however, this number is not prime,
; because it can be divided by "5" and other numbers that
; are made out of "5".
; We store our 32 bit number in DX:AX pair,
; to make DIV operation easier.
NEXT_NUM:
;-----------------------------
; ACTUAL PRIME CHECK OF DX:AX number.
; number can never be divided by anything larger
; than half of itself, therefore, we can easily
; start checking only from "0FFFFh".
; (can be wrong theoretically, but unfortunately,
; there is no other way to make DIV operation:)
MOV BX, 0FFFFh
next_div:
; put 32 bit value into DX:AX
MOV DX, wordH
MOV AX, wordL
; AX = (DX AX) / BX.
; DX = remainder.
DIV BX
CMP DX, 0
JMP not_prime
DEC BX
CMP BX, 1
JZ found_prime
JMP next_div ; try with next divider.
found_prime:
CALL PRINT_32BIT
; Print "<---- prime number found!"
LEA DX, msg3
MOV AH, 9
INT 21h
JMP stop_it ; we found it!
not_prime:
CALL PRINT_32BIT
; Print "<---- not prime!"
LEA DX, msg2
MOV AH, 9
INT 21h
;-----------------------------
CMP wordL, 0
JZ L_0
DEC wordL
JMP NEXT_NUM
L_0:
DEC wordL ; "0FFFF0000h" - 1 = "0FFFEFFFFh".
CMP wordH, 0
JZ end_of_numbers ; should never jump, unless DX:AX is 0 on start.
DEC wordH
JMP NEXT_NUM
end_of_numbers:
stop_it:
; Exit to DOS operating system:
MOV AH, 4Ch
INT 21h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;; PRINTING PROCEDURE ;;;;;;;;;;;;;;;;;;;;;;;
; this procedure is not related to Prime Number calculation ;
; it is used only to print out the 32 bit HEX value. ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRINT_32BIT PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
; we need to print the total of 8
; hex digits from 00 to 07.
; we could make a better loop,
; but I prefer cut & paste.
; and it's faster :)
; first we print wordH, then wordL.
MOV DX, wordH
; loop init:
MOV CX, 2 ; we jump back once only when DX := wordL
print_next_word:
; --- print nibble 00 / 04 ----
MOV BX, DX
AND BX, 1111000000000000b ; we need only 1 neeble.
SHR BX, 12 ; move nibble to leftmost position.
; print char using DOS interrupt:
MOV AL, hexstr[BX]
MOV AH, 0Eh
INT 10h
; --- print nibble 01 / 05 ----
MOV BX, DX
AND BX, 0000111100000000b ; we need only 1 neeble.
SHR BX, 8 ; move nibble to leftmost position.
; print char using DOS interrupt:
MOV AL, hexstr[BX]
MOV AH, 0Eh
INT 10h
; --- print nibble 02 / 06 ----
MOV BX, DX
AND BX, 0000000011110000b ; we need only 1 neeble.
SHR BX, 4 ; move nibble to leftmost position.
; print char using DOS interrupt:
MOV AL, hexstr[BX]
MOV AH, 0Eh
INT 10h
; --- print nibble 03 /07 ----
MOV BX, DX
AND BX, 0000000000001111b ; we need only 1 neeble.
; no need to move the nibble,
; it is at leftmost position already.
; print char using DOS interrupt:
MOV AL, hexstr[BX]
MOV AH, 0Eh
INT 10h
; ------------------------
MOV DX, wordL ; wordH, printed, now print wordL.
LOOP print_next_word
POP DX
POP CX
POP BX
POP AX
RET
hexstr db '0123456789ABCDEF'
PRINT_32BIT ENDP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -