103 lines
2.4 KiB
Plaintext
103 lines
2.4 KiB
Plaintext
MAX: equ 1000 ; Amount of Mertens numbers to generate
|
|
puts: equ 9 ; MS-DOS syscall to print a string
|
|
putch: equ 2 ; MS-DOS syscall to print a character
|
|
cpu 8086
|
|
org 100h
|
|
section .text
|
|
;;; Generate Mertens numbers
|
|
mov bx,M ; BX = pointer to start of Mertens numbers
|
|
mov si,1 ; Current Mertens number
|
|
mov [si+bx],byte 1 ; First Mertens number is 1
|
|
outer: inc si ; Next Mertens number
|
|
mov [si+bx],byte 1 ; Starts out at 1...
|
|
mov cx,2 ; CX = from 2 to current number,
|
|
inner: mov ax,si ; Divide current number,
|
|
xor dx,dx
|
|
div cx ; By CX
|
|
mov di,ax
|
|
mov al,[di+bx] ; Get value at that location
|
|
sub [si+bx],al ; Subtract from current number
|
|
inc cx
|
|
cmp cx,si
|
|
jbe inner
|
|
cmp si,MAX
|
|
jbe outer
|
|
;;; Print the table
|
|
mov dx,frst99 ; First string
|
|
call outstr
|
|
mov si,1 ; Start at index 1
|
|
mov dh,9 ; Column count
|
|
table: mov cl,[si+bx] ; Get item
|
|
test cl,cl
|
|
mov dl,' '
|
|
jns .print ; Positive?
|
|
mov dl,'-' ; Otherwise, it is negative,
|
|
neg cl ; print ' ' and negate
|
|
.print: call putc ; Print space or minus
|
|
add cl,'0' ; Add ASCII 0
|
|
mov dl,cl
|
|
call putc ; Print number
|
|
mov dl,' '
|
|
call putc ; Print space
|
|
dec dh ; One less column left
|
|
jnz .next
|
|
mov dx,nl ; Print newline
|
|
call outstr
|
|
mov dh,10
|
|
.next: inc si ; Done yet?
|
|
cmp si,100
|
|
jb table ; If not, print next item from table
|
|
;;; Calculate zeroes and crossings
|
|
xor cx,cx ; CL = zeroes, CH = crossings
|
|
mov si,1
|
|
mov al,[si+bx] ; AL = current item
|
|
zc: inc si
|
|
mov ah,al ; AH = previous item
|
|
mov al,[si+bx]
|
|
test al,al ; Zero?
|
|
jnz .next
|
|
inc cx ; Then increment zero counter
|
|
test ah,ah ; Previous one also zero?
|
|
jz .next
|
|
inc ch ; Then increment crossing counter
|
|
.next: cmp si,MAX ; Done yet?
|
|
jbe zc
|
|
;;; Print zeroes and crossings
|
|
mov dx,zero
|
|
call outstr
|
|
mov al,cl
|
|
call putal
|
|
mov dx,cross
|
|
call outstr
|
|
mov al,ch
|
|
call putal
|
|
mov dx,tms
|
|
jmp outstr
|
|
putc: mov ah,putch ; Print character
|
|
int 21h
|
|
ret
|
|
;;; Print AL in decimal format
|
|
putal: mov di,num
|
|
.loop: aam ; Extract digit
|
|
add al,'0' ; Store digit
|
|
dec di
|
|
mov [di],al
|
|
mov al,ah ; Rest of number
|
|
test al,al ; Done?
|
|
jnz .loop ; If not, get more digits
|
|
mov dx,di ; Otherwise, print string
|
|
outstr: mov ah,puts
|
|
int 21h
|
|
ret
|
|
section .data
|
|
db '***' ; Number output placeholder
|
|
num: db '$'
|
|
frst99: db 'First 99 Mertens numbers:',13,10,' $'
|
|
nl: db 13,10,'$'
|
|
zero: db 'M(N) is zero $'
|
|
cross: db ' times.',13,10,'M(N) crosses zero $'
|
|
tms: db ' times.$'
|
|
section .bss
|
|
mm: resb MAX ; Mertens numbers
|
|
M: equ mm-1 ; 1-based indexing
|