Hi forum, I just need help on my code. I am trying to find all the Armstrong numbers from 100-999(i.e. when the cubes of three digits added together equal the number - 1^3 + 5^3 + 3^3 = 153.) My code works until it gets to line 93, then it proceeds with some bizarre information as Debug.exe showed me. Help would be greatly appreciated, here is my C++ algorithm:
#include <iostream>
using namespace std;
int main()
{
// No inputs.
// Start here.
for(int digit1 = 1; digit1 < 10; digit1++)
{
for(int digit2 = 0; digit2 < 10; digit2++)
{
for(int digit3 = 0; digit3 < 10; digit3++)
{
if((digit1*digit1*digit1)+(digit2*digit2*digit2)+(digit3*digit3*digit3) == (digit1*100+digit2*10+digit3))
{
cout << digit1 << digit2 << digit3 << " is armstrong.";
system("pause");
}
}
}
}
system("pause");
return 0;
}// End here. ;
; DILLON SHEFFIELD
;
PAGE 55,132
TITLE LAB3-PROGRAM TO FIND ARMSTRONG NUMBERS FROM 100-999
;
STACKSG SEGMENT PARA STACK
DW 32 DUP(?)
STACKSG ENDS
;
DATASG SEGMENT PARA
DIGIT1 DB 1
DIGIT2 DB 0
DIGIT3 DB 0
TEMP1 DW ?
TEMP2 DW ?
TEMP3 DW ?
OUTVAL DB 10 DUP(' ')
OUTLEN DB ?
BINFLD DW ?
DATASG ENDS
;
CODESG SEGMENT PARA
BEGIN PROC FAR ;Start main procedure
ASSUME CS:CODESG,DS:DATASG,SS:STACKSG,ES:DATASG
MOV AX,DATASG ;Set up ds to point to beginning of
MOV DS,AX ;data segment
MOV ES,AX ;Likewise ES for any I/O calls
;
START:
MOV BL,DIGIT1 ;Store DIGIT1 in the BL register.
MOV AL,DIGIT1 ;Store DIGIT1 in the AL register.
MUL BL ;Then multiply [DIGIT1 * DIGIT1] and store in AX.
MOV TEMP1,AX ;Move product to TEMPORARY1 storage.
MOV BX,TEMP1 ;Copy the product to the BX register.
MUL BX ;Then multiply [(DIGIT2 * DIGIT2) * DIGIT2].
MOV TEMP1,AX ;Then store DIGIT1 CUBED in TEMP1.
;
MOV BL,DIGIT2 ;Store DIGIT2 in the BL register.
MOV AL,DIGIT2 ;Store DIGIT2 in the AL register.
MUL BL ;Then multiply [DIGIT2 * DIGIT2] and store in AX.
MOV TEMP2,AX ;Move product to TEMPORARY2 storage.
MOV BX,TEMP2 ;Copy the product to the BX register.
MUL BX ;Then multiply [(DIGIT2 * DIGIT2) * DIGIT2].
MOV TEMP2,AX ;Then store DIGIT2 CUBED in TEMP2.
MOV AX,TEMP1 ;Copy DIGIT1 CUBED in the AX register.
MOV BX,TEMP2 ;Copy DIGIT2 CUBED in the BX register.
ADD AX,BX ;Add [DIGIT1^3 + DIGIT2^3] and store in AX.
MOV TEMP1,AX ;Then store the sum in TEMP1, overwriting DIGIT1 CUBED.
;
MOV BL,DIGIT3 ;Store DIGIT3 in the BL register.
MOV AL,DIGIT3 ;Store DIGIT3 in the AL register.
MUL BL ;Then multiply [DIGIT3 * DIGIT3] and store in AX.
MOV TEMP3,AX ;Move product to TEMPORARY3 storage.
MOV BX,TEMP3 ;Copy the product to the BX register.
MUL BX ;Then multiply [(DIGIT3 * DIGIT3) * DIGIT3].
MOV TEMP3,AX ;Then store DIGIT3 CUBED in TEMP3.
MOV AX,TEMP1 ;Copy [DIGIT1^3 + DIGIT2^3] in the AX register.
MOV BX,TEMP3 ;Copy DIGIT3 CUBED in the BX register.
ADD AX,BX ;Add [(DIGIT1^3 + DIGIT2^3) + DIGIT3^3] and store in AX.
MOV TEMP1,AX ;Then store the sum in TEMP1, overwriting [DIGIT1^3 + DIGIT2^3].
; TEMP1 only matters now and contains [DIGIT1^3 + DIGIT2^3 + DIGIT3^3].
MOV BL,DIGIT1 ;Store the current value of DIGIT1 in the BL register.
MOV AL,100 ;Load AL with 100.
MUL BL ;Then multiply [DIGIT1 * 100].
MOV TEMP2,AX ;Then store the product in TEMP2.
MOV BL,DIGIT2 ;Store the current value of DIGIT2 in the BL register.
MOV AL,10 ;Load AL with 10 this time.
MUL BL ;The multiply [DIGIT2 * 10].
ADD AX,TEMP2 ;Now add [(DIGIT1 * 100) + (DIGIT2 * 10)].
MOV BL,DIGIT3 ;Move DIGIT3's value to the BL register.
MOV BH,0 ;Move leading 0s in to BH register
ADD AX,BX ;Finally add [(DIGIT1 * 100) + (DIGIT2 * 10) +
;DIGIT3] and store in the AX register.
MOV TEMP2,AX ;Now move the sum all of cubes in TEMP2.
;
MOV AX,TEMP1
MOV BX,TEMP2
CMP AX,BX ;Test to see if the number is armstrong.
JE ARMSTRONG ;Jump to ARMSTRONG if test is true.
CMP DIGIT1,10
JB INCDIG1
JMP STOP ;Stop if DIGIT1 was equal or greater than 10.
ARMSTRONG:
MOV CX,0
MOV CL,OUTLEN
LEA SI,OUTVAL
CLOUT:
MOV BYTE PTR[SI],020H
INC SI
LOOP CLOUT
;
MOV AL,OUTLEN
MOV AH,0
LEA SI,OUTVAL
ADD SI,AX
MOV BYTE PTR[SI],024H
DEC SI
MOV AX,BINFLD
NXTDIGIT:
CMP AX,10
JB LASTDIGIT
MOV DX,0
DIV CX
OR DL,030H
MOV [SI],DL
DEC SI
JMP NXTDIGIT
LASTDIGIT:
OR AL,030H
MOV [SI],AL
MOV AH,9
LEA DX,OUTVAL
INT 21H
CMP DIGIT1,10
JB INCDIG1
JMP STOP ;Stop if DIGIT1 was equal or greater than 10.
INCDIG1:
ADD DIGIT1,1 ;Add 1 to DIGIT1 to increment the digit.
CMP DIGIT2,10
JB INCDIG2
JMP SET2TO0
INCDIG2:
ADD DIGIT2,1 ;Add 1 to DIGIT2 to increment the digit.
CMP DIGIT3,10
JB INCDIG3
JMP SET3TO0 ;If DIGIT3 was equal or greater than 10.
INCDIG3:
ADD DIGIT3,1 ;Add 1 to DIGIT3 to increment the digit.
JMP START
SET2TO0:
MOV DIGIT2,0 ;Reset DIGIT2 back to 0 if it was greater than 9.
CMP DIGIT3,10
JB INCDIG3
JMP SET3TO0 ;If DIGIT3 was equal or greater than 10.
SET3TO0:
MOV DIGIT3,0 ;Reset DIGIT3 back to 0 if it was greater than 9.
JMP START
STOP:
;
NOP ;Dummy instruction - stop DEBUG here
MOV AH,4CH ;Return to DOS
INT 21H ;via service call 4CH
BEGIN ENDP ;End procedure
CODESG ENDS ;End code segment
END BEGIN ;End source code Here is your C++ algorithm:
format PE GUI 4.0
include 'win32a.inc'
mov [digit1],1
mdigit1:
mov [digit2],1
mdigit2:
mov [digit3],1
mdigit3:
mov eax,[digit1]
mul [digit1]
mul [digit1]
mov ebx,eax
mov eax,[digit2]
mul [digit2]
mul [digit2]
add ebx,eax
mov eax,[digit3]
mul [digit3]
mul [digit3]
add ebx,eax
mov eax,100
mul [digit1]
mov ecx,eax
mov eax,10
mul [digit2]
add ecx,eax
add ecx,[digit3]
cmp ebx,ecx
jne mANSk
nop
; Here is output
mANSk:
inc [digit3]
cmp [digit3],10
jle mdigit3
inc [digit2]
cmp [digit2],10
jle mdigit2
inc [digit1]
cmp [digit1],10
jle mdigit1
invoke ExitProcess,0
digit3 dd 0
digit2 dd 0
digit1 dd 0
data import
library kernel32,'KERNEL32.DLL'
import kernel32,\
ExitProcess,'ExitProcess'
end data for FASM.
Thanks for the response, but I was looking as to why my assembly source code did not work properly. It compiles with no errors, but does not output anything. I want it to output digit1,2, and 3 if they are armstrong when the cubes are combined.
Where do you have problem after line 93? When it goes to line 95 or line 101?
Well, this comparison in line 93 and 94 does not work. It compares the AX register [DIGIT1^3 + DIGIT2^3 + DIGIT3^3] to the BX register [(DIGIT1 * 100) + (DIGIT2 * 10) + DIGIT3] and should jump to ARMSTRONG when the values of both are equal. However the first run through of the program, [1^3 + 0^3 + 0^3] does not equal [1 * 100 + (0 * 10) + 0]. 1 != 100.
CMP AX,BX ;Test to see if the number is armstrong.
JE ARMSTRONG ;Jump to ARMSTRONG if test is true. When I debug this program it performs this command...
JZ 009A I do not know what this does but it does proceed with the next line of code after I finally rewrote some code. However, it does not output properly like it should... I always have trouble with output. It just seems to run through an infinite loop... :/
;
; DILLON SHEFFIELD
;
PAGE 55,132
TITLE LAB3-PROGRAM TO FIND ARMSTRONG NUMBERS FROM 100-999
;
STACKSG SEGMENT PARA STACK
DW 32 DUP(?)
STACKSG ENDS
;
DATASG SEGMENT PARA
DIGIT1 DB 1
DIGIT2 DB 0
DIGIT3 DB 0
TEMP1 DW ?
TEMP2 DW ?
TEMP3 DW ?
OUTVAL DB 10 DUP(' ')
OUTLEN DB ?
BINFLD DW ?
DATASG ENDS
;
CODESG SEGMENT PARA
BEGIN PROC FAR ;Start main procedure
ASSUME CS:CODESG,DS:DATASG,SS:STACKSG,ES:DATASG
MOV AX,DATASG ;Set up ds to point to beginning of
MOV DS,AX ;data segment
MOV ES,AX ;Likewise ES for any I/O calls
;
START:
MOV BL,DIGIT1 ;Store DIGIT1 in the BL register.
MOV AL,DIGIT1 ;Store DIGIT1 in the AL register.
MUL BL ;Then multiply [DIGIT1 * DIGIT1] and store in AX.
MOV TEMP1,AX ;Move product to TEMPORARY1 storage.
MOV BX,TEMP1 ;Copy the product to the BX register.
MUL BX ;Then multiply [(DIGIT2 * DIGIT2) * DIGIT2].
MOV TEMP1,AX ;Then store DIGIT1 CUBED in TEMP1.
;
MOV BL,DIGIT2 ;Store DIGIT2 in the BL register.
MOV AL,DIGIT2 ;Store DIGIT2 in the AL register.
MUL BL ;Then multiply [DIGIT2 * DIGIT2] and store in AX.
MOV TEMP2,AX ;Move product to TEMPORARY2 storage.
MOV BX,TEMP2 ;Copy the product to the BX register.
MUL BX ;Then multiply [(DIGIT2 * DIGIT2) * DIGIT2].
MOV TEMP2,AX ;Then store DIGIT2 CUBED in TEMP2.
MOV AX,TEMP1 ;Copy DIGIT1 CUBED in the AX register.
MOV BX,TEMP2 ;Copy DIGIT2 CUBED in the BX register.
ADD AX,BX ;Add [DIGIT1^3 + DIGIT2^3] and store in AX.
MOV TEMP1,AX ;Then store the sum in TEMP1, overwriting DIGIT1 CUBED.
;
MOV BL,DIGIT3 ;Store DIGIT3 in the BL register.
MOV AL,DIGIT3 ;Store DIGIT3 in the AL register.
MUL BL ;Then multiply [DIGIT3 * DIGIT3] and store in AX.
MOV TEMP3,AX ;Move product to TEMPORARY3 storage.
MOV BX,TEMP3 ;Copy the product to the BX register.
MUL BX ;Then multiply [(DIGIT3 * DIGIT3) * DIGIT3].
MOV TEMP3,AX ;Then store DIGIT3 CUBED in TEMP3.
MOV AX,TEMP1 ;Copy [DIGIT1^3 + DIGIT2^3] in the AX register.
MOV BX,TEMP3 ;Copy DIGIT3 CUBED in the BX register.
ADD AX,BX ;Add [(DIGIT1^3 + DIGIT2^3) + DIGIT3^3] and store in AX.
MOV TEMP1,AX ;Then store the sum in TEMP1, overwriting [DIGIT1^3 + DIGIT2^3].
; TEMP1 only matters now and contains [DIGIT1^3 + DIGIT2^3 + DIGIT3^3].
MOV BL,DIGIT1 ;Store the current value of DIGIT1 in the BL register.
MOV AL,100 ;Load AL with 100.
MUL BL ;Then multiply [DIGIT1 * 100].
MOV TEMP2,AX ;Then store the product in TEMP2.
MOV BL,DIGIT2 ;Store the current value of DIGIT2 in the BL register.
MOV AL,10 ;Load AL with 10 this time.
MUL BL ;The multiply [DIGIT2 * 10].
ADD AX,TEMP2 ;Now add [(DIGIT1 * 100) + (DIGIT2 * 10)].
MOV BL,DIGIT3 ;Move DIGIT3's value to the BL register.
MOV BH,0 ;Move leading 0s in to BH register
ADD AX,BX ;Finally add [(DIGIT1 * 100) + (DIGIT2 * 10) +
;DIGIT3] and store in the AX register.
MOV TEMP2,AX ;Now move the sum all of cubes in TEMP2.
;
LEA AX,TEMP1
LEA BX,TEMP2
CMP AX,BX ;Test to see if the number is armstrong.
JE ARMSTRONG ;Jump to ARMSTRONG if test is true.
;MOV AH,0 ;Lead 0s.
LEA AX,DIGIT1 ;Store DIGIT1 in AX
MOV BX,10 ;Store 10 in BX
CMP AX,BX ;Compare to see if DIGIT1 is equal to 10.
JB INCDIG1
JMP STOP ;Stop if DIGIT1 was equal or greater than 10.
ARMSTRONG:
MOV CX,0
MOV CL,OUTLEN
LEA SI,OUTVAL
CLOUT:
MOV BYTE PTR[SI],020H
INC SI
LOOP CLOUT
MOV AL,OUTLEN
MOV AH,0
LEA SI,OUTVAL
ADD SI,AX
MOV BYTE PTR[SI],024H
DEC SI
MOV AX,BINFLD
NXTDIGIT:
CMP AX,10
JB LASTDIGIT
MOV DX,0
DIV CX
OR DL,030H
MOV [SI],DL
DEC SI
JMP NXTDIGIT
LASTDIGIT:
OR AL,030H
MOV [SI],AL
MOV AH,9
LEA DX,OUTVAL
INT 21H
MOV AH,0 ;Lead 0s.
MOV AL,DIGIT1 ;Store DIGIT1 in AX
MOV BX,10 ;Store 10 in BX
CMP AX,BX ;Compare to see if DIGIT1 is equal to 10.
JB INCDIG1
JMP STOP ;Stop if DIGIT1 was equal or greater than 10.
INCDIG1:
MOV BL,1 ;Move 1 into BL. DIGIT1 already in AX
ADD DIGIT1,BL ;Add 1 to DIGIT1 to increment the digit.
CMP DIGIT2,10
JB INCDIG2
JMP SET2TO0
INCDIG2:
ADD DIGIT2,1 ;Add 1 to DIGIT2 to increment the digit.
CMP DIGIT3,10
JB INCDIG3
JMP SET3TO0 ;If DIGIT3 was equal or greater than 10.
INCDIG3:
ADD DIGIT3,1 ;Add 1 to DIGIT3 to increment the digit.
JMP START
SET2TO0:
MOV DIGIT2,0 ;Reset DIGIT2 back to 0 if it was greater than 9.
CMP DIGIT3,10
JB INCDIG3
JMP SET3TO0 ;If DIGIT3 was equal or greater than 10.
SET3TO0:
MOV DIGIT3,0 ;Reset DIGIT3 back to 0 if it was greater than 9.
JMP START
STOP:
;
NOP ;Dummy instruction - stop DEBUG here
MOV AH,4CH ;Return to DOS
INT 21H ;via service call 4CH
BEGIN ENDP ;End procedure
CODESG ENDS ;End code segment
END BEGIN ;End source code JE and JZ are the same in your case. First pass of your loop is working correctly. First three digits are 1, 0, 0, command JE ARMSTRONG is comparing 1 and 100, they are not equal, so it is going to line 95. After this, you increase all three digits by 1, so the next three digits are 2, 1, 1.
For output, I recommend to print DIGIT1, DIGIT2 and DIGIT3 sequentially, but do not forget to add '0' to them before output.
For your information - my code contains two mistakes.
Let me know if you have any questions.