• Please review our updated Terms and Rules here

Random Cubic Polynomial in Assembler

neilobremski

Experienced Member
Joined
Oct 9, 2016
Messages
55
Location
Seattle, USA
I finally reached back into some of my first assembler [SUP][1][/SUP] to write a routine called cubicnom() that generates a random cubic polynomial as the title implies. This pulls together several recent bits of code to seed the random number generator using a string and sprintf the results to a location in memory.


First, here's a random() function which accepts range parameters BX to CX. Thus if I pass in 1 and 9, respectively, then I'll get back a random number in the range of 1 to 9. On top of this, it also makes DS = CS which is required by rand().

Code:
a 390
; ----------------------------------------------------------------------------
; random ()							:RANDOM
;
; Calls BX + (rand() % (CX - BX + 1)) and outputs the result in AX.
;
PUSH	DS	; 390
PUSH	DX	; 391
PUSH	CS	; 392
POP	DS	; 393 DS = CS
PUSH	CX	; 394
PUSH	BX	; 395
PUSH	SI	; 396
CALL	0300	; 397 >RAND
POP	SI	; 39A
POP	BX	; 39B
POP	CX	; 39C
CWD		; 39D
PUSH	CX	; 39E
SUB	CX, BX	; 39F
INC	CX	; 3A1 (CX - BX + 1)
DIV	CX	; 3A2
POP	CX	; 3A4
XCHG	AX, DX	; 3A5
ADD	AX, BX	; 3A6
POP	DX	; 3A8
POP	DS	; 3A9
RET		; 3AA

Using that and the code from before, I present cubicnom() ...

Code:
a 590
NOP		; 590						:STRING_POLNOM

e 590 "X" FC " - %uX² + %uX - %u = (x-?)(x-?)(x-?)" 00 00
a 5C0
; ----------------------------------------------------------------------------
; cubicnom ()							:CUBICNOM
;
; Generates a cubic polynomial to ES:DI with CL, DH, and DL set to its roots.
;
; CH = X² = -(A + B + C)
; BL = X  = (A * B)(A * C)(B * C)
; AX = C  = -(A * B * C)
; 
MOV	BX, 0001; 5C0 minimum
MOV	CX, 0009; 5C3 maximum
CALL	0390	; 5C6 >RANDOM
MOV	DL, AL	; 5C9
CALL	0390	; 5CB >RANDOM
MOV	DH, AL	; 5CE
CALL	0390	; 5D0 >RANDOM
MOV	CL, AL	; 5D3
		;
MOV	CH, CL	; 5D5 CH will be X^2 coefficient / start with root A
ADD	CH, DH	; 5D7 add root B to X^2 coefficient
ADD	CH, DL	; 5D9 add root C to X^2 coefficient (finished)
MOV	AL, CL	; 5DB load root A in accumulator
MUL	DH	; 5DD (A * B)
MOV	BL, AL	; 5DF BL will be X coefficient / start with (A * B)
MOV	AL, CL	; 5E1 load root A in accumulator
MUL	DL	; 5E3 (A * C)
ADD	BL, AL	; 5E5 add (A * C) to X coefficient
MOV	AL, DH	; 5E7 load root B in accumulator
MUL	DL	; 5E9 (B * C)
ADD	BL, AL	; 5EB add (B * C) to X coefficient (finished)
XOR	AX, AX	; 5ED clear accumulator
MOV	AL, CL	; 5EF AX will be constant / start with root A
MUL	DH	; 5F1 multiply root B by constant
MUL	DL	; 5F3 multiply root C by constant (finished)
		;
PUSH	AX	; 5F5
PUSH	BX	; 5F6
PUSH	CX	; 5F7
PUSH	DX	; 5F8
PUSH	DS	; 5F9
		;
PUSH	CS	; 5FA
POP	DS	; 5FB
MOV	BP, 00F0; 5FC
MOV WORD[BP+4],AX; 5FF constant
XOR	AX, AX	; 602
MOV	AL, CH	; 604
MOV WORD[BP],AX; 606 X^2 coefficient
MOV	AL, BL	; 609
MOV WORD[BP+2],AX; 60B X coefficient
MOV	SI, 0590; 60E $STRING_POLNOM
CALL	0480	; 611 >SPRINTF
		;
POP	DS	; 614
POP	DX	; 615
POP	CX	; 616
POP	BX	; 617
POP	AX	; 618
		;
RET		; 619

This is a heavy weight that sets a bunch of registers (see screenshot above) and prints the string to ES:DI. Here's the register breakdown:

  • AX = Constant
  • BL = X Coefficient
  • CH = X^2 Coefficient
  • CL = Root A
  • DL = Root B
  • DH = Root C

Finally, the screenshot also shows that the output from this for the seed "MAGSMAZE" is identical to the first version of the game!

Footnotes:
[SUP][1][/SUP]. Generating Polynomials post from March 9th, 2017.
 
Back
Top