Division in Assembly language

Using the ulam conjecture [urgent]

Page 1 of 1

2 Replies - 18222 Views - Last Post: 05 October 2009 - 09:42 PM

#1 AMANDABEL  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 03-October 09

Division in Assembly language

Post icon  Posted 05 October 2009 - 12:10 AM

The teacher instructed us to create the Ulam conjecture in assembly language. The program is fairly simple. The user will enter a number and the program will check to see if it is even or odd. If it is even it is divided by two and if it is odd it is multiplied by 3 plus 1; until the number comes to 1. I have the program working, however, I ran into some problem. The number the teacher gave us to test out was 1,2,93,97, 9995, 9997, 38834, 38836, and 38838. I was able to get the program working for the first four numbers, but it blew up on the last 5. I'm finding that each time the number reaches into the 5 digits, it automatically terminates the program, whether it is even or odd. Am I missing something in the div command or forgot to reset a register. Thanks for the help.
DOSSEG
	.MODEL SMALL,BASIC,FARSTACK
;==============================================================================
;
	EXTRN CLEAR:FAR				;CLEAR SCREEN
		EXTRN GETDEC:FAR			   ;PROCEDURE TO 16-BIT INTEGER
	EXTRN GETDEC$:FAR	;DISPLAY 32-BIT INTEGER
		EXTRN NEWLINE:FAR			  ;DISPLAY NEWLINE
	EXTRN PUTDEC:FAR	  ;DISPLAY 16-BIT INTEGER
		EXTRN PUTDEC$:FAR			  ;DISPLAY 16-BIT INTEGER
	EXTRN PUTDC32$:FAR
		EXTRN PUTSTRNG:FAR			;DISPLAY CHARACTER STRING
		EXTRN PAUSE:FAR			  ;PAUSE SCREEN
;==============================================================================
;
; STACK SEGMENT DEFINITION
;
	.STACK 256
;==============================================================================
;
; CONSTANT SEGMENT DEFINITION
;
		.DATA
NUM		 	DW		?
CONSTANTDIV	DB		2
COUNTER		DW		0
PROMPT		DB		13,10,'PLEASE ENTER A POSITIVE NUMBER: '
LENGTHS		DB		'LENGTH OF SEQUENCE IS: '
ERROR		DB		'FLOATING POINT ERROR'
SPACE		DB		' '
;==============================================================================
;
; CODE SEGMENT DEFINITION
;
	.CODE
	ASSUME DS:NOTHING,ES:DGROUP
ULAMSEQ:	
MAIN PROC	;BEGINNING OF PROCEDURE
		  MOV	AX,DGROUP	
	MOV	ES,AX		
	MOV	DS,AX		
	CALL	CLEAR		
	LEA	DI,PROMPT	
	MOV	CX,34		
 	CALL 	PUTSTRNG	
	CALL	GETDEC$	
	CALL	NEWLINE	
START_LOOP:		;LOOP BEGIN
	SUB	DX,DX
	MOV	BH,0
	CALL	PUTDEC$		
	MOV	NUM,AX	;MAKE SURE VALUE IN AX IS NOT ALTERED
	LEA	DI,SPACE;FORMAT THE NUMBER LINE
	MOV	CX,1
	CALL	PUTSTRNG
	INC	COUNTER		
	CMP	AX,1	;MAKE SURE DECIMAL IS GREATER THAN 1
	JLE	END_LOOP;VALUE IS EQUAL OR LESS JUMPS OUT OF LOOP		
;MOV	BX,2		
	DIV	  CONSTANTDIV;MATH COMPUTATION IF EVEN OR ODD
	CMP	DX,0	;IF EVEN GOES TO START LOOP OVER
	CLI
	JE	START_LOOP			
	JMP	DOODD	;IF ODD JUMPS TO DO ODD ARITHMETIC
DOODD:			;BEGIN FOR ODD ARITHMETIC
	MOV	AX,NUM		
	MOV		BX,3		
	MUL	BX	
	INC	AX
	JC	ERROR_MESSAGE;CHECK FOR FLOATING POINT ERROR
	JMP	START_LOOP	;OTHER JUMPS BACK TO LOOP
ERROR_MESSAGE:				 ;PRINTS OUT ERROR MESSAGE
	CALL	NEWLINE;
	LEA	DI,ERROR;PROCEDURE JUMP OUT OF LOOP AND END PROGRAM
	MOV	CX,20	;IF A FLOATING POINT OCCURS
	CALL	PUTSTRNG	
	JMP	DONE			
END_LOOP:		;END LOOP
	MOV	AX,COUNTER;MOV COUNTER TO AX REGISTRY FOR PRINT
	CALL	NEWLINE				
	LEA	DI,LENGTHS;PRINTS LENGTH OF PROGRAM
	MOV	CX,23	
	CALL	PUTSTRNG	
	CALL	PUTDEC
	CALL	NEWLINE
	LEA	DI,SPACE
	MOV	CX,1
	CALL	PAUSE		
DONE:	
	MOV	AX,4C00CH;RETURN TO DOS
	INT	21H			
MAIN	ENDP
	END ULAMSEQ



** Edit ** :code:

Is This A Good Question/Topic? 0
  • +

Replies To: Division in Assembly language

#2 wildgoose  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 67
  • View blog
  • Posts: 468
  • Joined: 29-June 09

Re: Division in Assembly language

Posted 05 October 2009 - 09:18 PM

1,2,93,97, 9995, 9997, 38834, 38836, and 38838

Watch how many bits needed to store a value in 16 bits!

9995 * 3 = 29,985 7521h
38834 * 3 = 116,502 1c716h

MUL DX:AX = AX * BX
Carry is set if DX becomes non-zero

Also watch for signed versus unsigned branching!

Signed: Less - Greater
JG, JNLE, JGE, JNL, JLE, JNG, JL, JNGE
Unsigned: Above - Below
JA, JNBE, JAE, JNB, JBE, JNA, JB, JNAE

You are using JLE AX,1 which is a signed instruction. So anything > 32767 is negative! thus (<=)

Are you allowed to use a shift operation instead of a divide by 2? Divide is overkill!

Because

   SHR AX,1	; LSB now in carry bit
   JNC  Even		 ; Jump no carry if Even
	; Odd
   JZ	Done		;  if zero and carry was set then AX was (1)



CLI ; Why are you clearing the interrupts?

When do you initialize COUNTER ?

This post has been edited by wildgoose: 05 October 2009 - 09:34 PM

Was This Post Helpful? 0
  • +
  • -

#3 no2pencil  Icon User is online

  • Toubabo Koomi
  • member icon

Reputation: 5306
  • View blog
  • Posts: 27,200
  • Joined: 10-May 07

Re: Division in Assembly language

Posted 05 October 2009 - 09:42 PM

** Moved to Assembly **
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1