Can someone adapt this "sum of the cubes of the digits" program so
that it searches the 3-digit numbers from 100 to 999 and prints only
those which are PRIME.
.MODEL SMALL
.STACK 100h
.DATA
first_digit DW 1 ;initial values allow the three digit number
second_digit DW 0 ;to begin at 100 and cycle through to 999
third_digit DW 0 ;using the increment mechanism based on a car odometer
crlf DB 10d,13d,'$'
welcome DB 10d,13d,'Program to identify all 3-digit integers which
equal the sum of the$'
Welcome2 DB 10d,13d,'cubes of their own digits. By wily-Q
',10d,10d,10d,13d,'$'
signoff DB 10d,10d,13d,'Program terminated',10d,13d,'$'
.CODE
mov ax,@data ;establish access to variables and constants by setting
mov ds,ax ;the ds register, the data segment pointer.
mov ah,9h ;BIOs code for print a dollar-delimited string
mov dx, offset welcome
int 21h ;pointer to string must be in dx in above statement
mov ah,9h ;BIOs code for print a dollar-delimited string
mov dx, offset welcome2
int 21h ;pointer to string must be in dx in above statement
;first get the sum of the cubes of the actual digits, accumulate in bx
New_number:
mov ax, first_digit
mov cx,ax
mul cx ;in mul, the second operand is ax, therefore this squares the digit
mul cx ;second mul cubes the digit
;note that the result goes into combination of DX:AX, but worst case analysis shows
;that the content of DX will always be zero -- 9*9*9 fits into AX
alone, therefore DX
;will be leading zeros and can be neglected. The magniture of the
cube is in AX alone.
mov bx,ax ;save the result
mov ax, second_digit
mov cx,ax
mul cx ;in mul, the second operand is ax, therefore this squares the digit
mul cx ;second mul cubes the digit
;note that the result goes into combination of DX:AX, but worst case analysis shows
;that the content of DX will always be zero -- 9*9*9 fits into AX
alone, therefore DX
;will be leading zeros and can be neglected. The magniture of the
cube is in AX alone.
add bx,ax ;accumulate the result
mov ax, third_digit
mov cx,ax
mul cx ;in mul, the second operand is ax, therefore this squares the digit
mul cx ;second mul cubes the digit
;note that the result goes into combination of DX:AX, but worst case analysis shows
;that the content of DX will always be zero -- 9*9*9 fits into AX
alone, therefore DX
;will be leading zeros and can be neglected. The magniture of the
cube is in AX alone.
add bx,ax ;accumulate the result
;Sum of cubes of digits safely in bx -- make sure that the bx register is not used.
;now get the actual number as a plain integer. Save/acumulate in AX
mov ax, first_digit
mov cx, 10d
mul cx ;second argument is AX, result is DX:AX
add ax, second_digit ;worst case analysis for the MUL is that the maximum number
mul cx ;will be 1000, which fits into AX alone so that DX will be
add ax, third_digit ;leading zeros. We shall therefore ignore DX.
;ready to compare
cmp ax, bx
jnz inc_number
;Display the digits -- they may be overwritten if the equality we are
looking for is not met
mov dx, first_digit ;DH will be zeros, but had to use DX here to keep
arguments same length
add dl, 30h ;ignoring DH and converting to ASCII
mov ah, 2h ;BIOS code for print a character
int 21h
mov dx, second_digit ;DH will be zeros, but had to use DX here to
keep arguments same length
add dl, 30h ;ignoring DH and converting to ASCII
mov ah, 2h ;BIOS code for print a character
int 21h
mov dx, third_digit ;DH will be zeros, but had to use DX here to keep
arguments same length
add dl, 30h ;ignoring DH and converting to ASCII
mov ah, 2h ;BIOS code for print a character
int 21h
mov ah, 9h ;new line needed
mov dx, offset crlf
int 21h
;this is the part where the digits are incremented in the same way as
a car's milage meter.
inc_number:
inc third_digit ;16-bit increment -- digits are declared as words
cmp third_digit, 10d ;see if we have reached the limit
jz reset1
jmp new_number ;digit still in range to text the next number
reset1:
;If here, third_digit has reached 10, so reset to zero and increment next digit
mov third_digit, 0d
inc second_digit
cmp second_digit, 10d
jz reset2
jmp new_number ;digit still in range, so test the next number
reset2:
;If here, third_digit has reached 10, so reset to zero and increment next digit
mov second_digit, 0d
inc first_digit
cmp first_digit, 10d
jz finished
jmp new_number ;digit still in range, so test the next number
finished:
;if here, the first digit has reached 10, so we have searched and
tested 100 thru' 999
mov ah, 9h ;BIOS code for print a string, say bye-bye
mov dx, offset signoff
int 21h
mov ah, 4ch ;quit to command prompt.
int 21h
end |