现在的位置: 首页 > 综合 > 正文

第三个程序:生成两个个ffH以内的随机数,并选择随机的运算符计算[但是好像非随机吧,cpu太快了]

2018年11月02日 ⁄ 综合 ⁄ 共 3743字 ⁄ 字号 评论关闭
assume cs:code, ds:data, ss:stack

data segment
	notice db 'the random expression is : $'	; the notice 
	exp db 10 dup (0)							; the memory to save calcute expression
	db ' $ '									; the finish symbol
	operand dw 3 dup (0)						; save the first operand, operator and the second operand
	tmp dw 5 dup (0)							; temp memory
	
data ends


stack segment									; stack memory
	db 128 dup (0)
	
stack ends


code segment

start:
	mov ax, data
	mov ds, ax
	mov ax, stack 
	mov ss, ax
	
	lea dx, notice					; show the notice sentence
	mov ah, 9
	int 21H
	
	call getRandomNunber			; get the first operator
	mov ds:[operand], bx
	; mov ds:[operand], 2424H
	; mov ax, 1
	; push ax
	; mov ax, 0
	; push ax
	
	mov ds:[tmp], 0000H
	mov ds:[tmp+2], 0001H			; warnning there need to be notified !!!!!!!!
	
	call calcHalfWord
	
	
	
	call getRandomNunber			; get the operator, and write it to memory
	mov ds:[tmp], 0002H
	call getOperator
	
	
	call sleep						; sleep for 1000 millis, to get the second random number
	
	
	call getRandomNunber			; get the second operand
	mov ds:[operand+4], bx
	
	mov ds:[tmp], 0003H
	mov ds:[tmp+2], 0004H
	
	call calcHalfWord
	
	
	mov ds:[exp+5], '='				; write the '=' to memory
	
	
	call getResult					; calc the result, and save to 'bx' register
	
	
	call calcOneWord
	
	; add sp, 4						; return sp to real offset

	
	; mov ds:[exp+8], '$'
	
	
	lea dx, exp 					; show the calcute expression
	mov ah, 9
	int 21H



	mov ax, 4c00H					; exit to cmd
	int 21H

	

sleep proc near 					; but this is not random number ??? the second number could be calcuted....
	push cx
	push bx
	
	mov cx, 0ffffH
	sleepStart:
		push cx
		
			mov cx, 00fffH
			sleepSecond:
				mov bx, 0001H
			loop sleepSecond
		
		pop cx
	loop sleepStart

	pop bx
	pop cx
	
	ret
	
sleep endp
	
	
getResult proc near						; get the calcute result
		push ax
	
		mov bx, ds:[operand+2]

		cmp bx, 0
		jz opePlus2
		cmp bx, 1
		jz opeSub2
		cmp bx, 2
		jz opeMul2
		cmp bx, 3
		jz opeDiv2
		

		opePlus2:
			mov bx, ds:[operand]
			add bx, ds:[operand+4]
			
		jmp getResultEnd
		
		opeSub2:
			mov bx, ds:[operand]
			sub bx, ds:[operand+4]
			
		jmp getResultEnd
		
		opeMul2:
			mov ax, ds:[operand]
			mov bx, ds:[operand+4]
			mul bl
			mov bx, ax
			
		jmp getResultEnd
		
		opeDiv2:
			mov ax, ds:[operand]
			mov bx, ds:[operand+4]
			div bl
			mov ah, 0					; clear the remained number
			mov bx, ax
			
		jmp getResultEnd
		
		
		getResultEnd:
	
		pop ax
	
		ret
	
getResult endp
	
	
getOperator proc near			; in this program, get operator could be executed at the last
		
		push di
		
		mov di, ds:[tmp]
		and bx, 3
		
		; jmp opePlus			; this is for debug
		
		cmp bx, 0
		jz opePlus
		cmp bx, 1
		jz opeSub
		cmp bx, 2
		jz opeMul
		cmp bx, 3
		jz opeDiv
		

		opePlus:
			mov ds:[operand+2], 0
			mov ds:[exp+di], '+'
			
		jmp getOperatorEnd
		
		opeSub:
			mov ds:[operand+2], 1
			mov ds:[exp+di], '-'
			
		jmp getOperatorEnd
		
		opeMul:
			mov ds:[operand+2], 2
			mov ds:[exp+di], '*'
			
		jmp getOperatorEnd
		
		opeDiv:
			mov ds:[operand+2], 3
			mov ds:[exp+di], '/'
			
		jmp getOperatorEnd
		
		
		getOperatorEnd:
		
		pop di
		
		ret

getOperator endp	
	

calcHalfByte	proc near	; calc the bl [----just judge lower four bit----]' s corresponding ascii code, save in bl
		; push bx			; bl record the data[need to be transfer]
		push cx			; record the offset to save in exp data segment
		
		cmp bl, 9
		ja abc			
						; bl not bigger than 9
		; mov [exp+cx], bl+48		; 1 ~ 8
		add bl, 48
		jmp calcHalfByteEnd
		
		abc:			; bl bigger than 9
		; mov [exp+cx], bl+87		; A ~ F	
		add bl, 87
		
	calcHalfByteEnd:		
		pop cx
		
		ret
		
calcHalfByte endp


calcHalfWord proc				; to calcute two hexadecimal number, number saved in bl, need to push two offset relative exp flag to save data
	; push bx
	; push di
	push dx
	push cx
	
	; add sp, 4					; mov stack pointer to save data offset, why there need just add 2 bit ? it just push ip in stack ?
	
	mov dx, bx
	mov cl, 4					; calc the upper 4 bit 
	shr bl, cl
	call calcHalfByte
	; pop di
	mov di, ds:[tmp]			; the segment of tmp must match the left value[cx], use dw to define data
	mov ds:[exp+di], bl
	
	mov bx, dx					; calc the lower 5 bit
	and bl, 15
	call calcHalfByte
	; pop di
	mov di, ds:[tmp+2]
	mov ds:[exp+di], bl

	; sub sp, 6					; mov stack pointer to the real stack top
								; why the value in stack changed ???		--2014.07.25
	
	; pop di
	; pop bx
	pop cx
	pop dx
	
	ret
	
calcHalfWord endp 


calcOneWord proc near			; to calcute two hexadecimal number, number saved in bx, need to push two offset relative exp flag to save data
	push dx
	
	mov dx, bx
	
	mov cl, 8					; calc the upper 8 bit of bx
	shr bx, cl
	mov ds:[tmp], 0006H
	mov ds:[tmp+2], 0007H
	call calcHalfWord
	
	mov bx, dx					; calc the lower 8 bit of bx
	mov bh, 0
	mov ds:[tmp], 0008H
	mov ds:[tmp+2], 0009H
	call calcHalfWord
	
	pop dx
	
	ret
	
calcOneWord endp


getRandomNunber proc near		; the process to get a random number, save to bl
	push ax
	push dx
	
	sti 
	mov ah, 0		
	int 1AH						; the interrupt that read the clock 'click' number while ah equal 0
	
	; mov ax, dx				; dx express the 'click count' of clock, is our random number
	and dx, 127
	
	mov bl, dl
	mov bh, 0
	
	pop dx
	pop ax
	
	ret
	
getRandomNunber endp


code ends

end start

; finished at 2014.07.26

抱歉!评论已关闭.