首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 汇编语言 >

关于一个随机产生数并运算的程序,各位大大们帮帮忙!该如何解决

2012-02-17 
关于一个随机产生数并运算的程序,各位大大们帮帮忙!DATA SEGMENTCC DB +ww db -GG DB II DB 0DH,0A

关于一个随机产生数并运算的程序,各位大大们帮帮忙!
DATA SEGMENT 
  CC DB '+'
  ww db '-'
  GG DB '='
  II DB 0DH,0AH,'$'
  AA DB 5 DUP(?)
  www dw 0
  ghh db '0',0dh,0ah,'$'
  bnm dw 0
DATA ENDS

STACK SEGMENT
  DB 200 DUP(0)
STACK ENDS

CODE SEGMENT
  ASSUME CS:CODE,DS:DATA,SS:STACK

START: MOV AX,DATA
  MOV DS,AX
  MOV CX,20
  CALL RAND ;产生一随机数
  CALL MCAT ;将随机数转换为16进制表示的ASCII码字符
  MOV AX,BX
  PUSH AX
  CMP www,0 ;WWW=0?
  JE A1 ;执行'+'
  CMP www,1 ;www=1?
  JE A2 ;执行'-' 
  A1: MOV DL,CC ;显示'+'
  MOV AH,2
  INT 21H
  CALL RAND ;产生另一随机数
  add bx,0fh
  CALL MCAT ;将随机数转换为16进制表示的ASCII码字符
  MOV DL,GG ;显示'='
  MOV AH,2
  INT 21H
  POP AX
  ADD AX,BX
  cmp ax,0
  jne yjw1
  lea dx,ghh
  mov ah,9
  int 21h
  jmp qq1
 yjw1: JMP B1
  A2: MOV DL,WW ;显示'-'
  MOV AH,2
  INT 21H
  mov cx,65535
 mai1: loop mai1
  CALL RAND1 
  CALL MCAT
  MOV DL,GG
  MOV AH,2
  INT 21H
  POP AX
  Sbb AX,BX
  cmp ax,0
  jne yjw2
  lea dx,ghh
  mov ah,9
  int 21h
  jmp qq1  
 yjw2: JMP B1
  B1: MOV BX,AX
  CALL MCAT
  lea DX,II
  MOV AH,9
  INT 21H
  QQ1: MOV AH,4CH
  INT 21H

MCAT PROC ;将随机数转换为16进制表示的ASCII码字符子程序
  PUSH AX
  push bx
  PUSH CX
  PUSH DX
  CMP BX,9
  JA S1
  PUSH AX
  PUSH BX
  PUSH CX
  PUSH DX
  mov ax,bx
  mov bl,5
  div bl
  cmp ah,3
  jae vb1
  mov www,1
  jmp vn1
 vb1:mov www,0
 vn1:pop dx
  pop cx
  pop bx
  pop ax
  ADD BL,30H
  MOV AA,BL
  MOV AA+1,'$'
  LEA DX,AA
  MOV AH,9
  INT 21H
  JMP s3
  s1:MOV CL,4
  MOV AL,0
  PUSH BX
  SHL BX,CL
  CMP BH,9
  JBE V1
  SUB BH,9
  ADD BH,40H
  JMP MM1
  V1:ADD BH,30H
 MM1:MOV AA,BH
  POP BX
  AND BL,0FH
  PUSH AX
  PUSH BX
  PUSH CX
  PUSH DX
  mov ax,bx
  mov bl,5
  div bl
  cmp ah,3
  jae vb2
  mov www,1
  jmp vn2
 vb2:mov www,0
 vn2:pop dx
  pop cx
  pop bx
  pop ax
  CMP BL,9
  JBE TT1
  SUB BL,9
  ADD BL,40H
  JMP RR1
TT1: ADD BL,30H
RR1: MOV AA+1,BL
  MOV AA+2,'$'
  LEA DX,AA
  MOV AH,9
  INT 21H
  s3:POP DX
  POP CX
  POP BX
  POP AX
  RET
MCAT ENDP



RAND PROC
  PUSH CX
  PUSH DX
  PUSH AX
  STI
  MOV AH,0 ;读时钟计数器值
  INT 1AH
  MOV AX,DX ;清高6位
  AND AH,3
  MOV DL,101 ;除101,产生0~100余数
  DIV DL
  MOV BL,AH ;余数存BX,作随机数
  POP AX
  POP DX
  POP CX
  RET
RAND ENDP

RAND1 PROC
  PUSH CX
  PUSH DX
  PUSH AX
  STI
  MOV AH,0
  INT 1AH
  MOV ax,cx
  AND AH,3
  MOV DL,101
  DIV DL
  MOV BL,AH
  POP AX
  POP DX
  POP CX
  RET
RAND1 ENDP

CODE ENDS
  END START 


 
程序是我在CSDN上下载来的, 但是在看这个程序的时候遇到很多问题
1;为什么在程序开头要往CX送20进去,似乎没有循环啊
2;在显示减号都要有一个延迟程序
3;在显示减号后要调用RAND1,也就是为什么要写2个一摸一样的子程序
4;在RAND这个子程序中,为什么有STI,难道调用时钟值一定要先中断?
5;在RAND中,直接调用时钟值就行了啊,为什么要还要除以101,取余数呢,只为了让数值具有随机性么
6;将随机数转换为16进制表示的ASCII码字符子程序,我看得逻辑混乱了,哪位大大能帮我分析下
  我感觉自己在看这个程序的时候,似乎有点钻牛角尖了,我想只有龙清楚作者的意图,才能做到真正弄懂这个程序才能举一反三


[解决办法]
1;为什么在程序开头要往CX送20进去,似乎没有循环啊
>> cx 并不是仅仅用于循环计数的,作为一个通用寄存器,在数据存取和数值计算上都可以发挥作用。不过,这个主程序里,cx 确实没用到,所以这条指令不是必要的。

2;在显示减号都要有一个延迟程序
>> 延时下,应该是为了后面的随机函数更显得随机些吧,虽然从现在的 cpu 速度上来看,这样小的循环作用也不大。

3;在显示减号后要调用RAND1,也就是为什么要写2个一摸一样的子程序
>> 两个子程不完全一样的。RAND 使用的是时钟计数器的低字 (low word):mov ax, dx,而RAND1 使用的是高字: mov ax, cx。这样直接的结果就是 RAND1 返回的随机数不那么随机,尤其是接连运行程序的时候。

4;在RAND这个子程序中,为什么有STI,难道调用时钟值一定要先中断?
>> 这里的 STI 指令应该也不是必需的。STI 是运行发生硬件中断,在程序接管控制权运行时,就是这么个状态;在硬件中断例程开始时才是 IF=0 状态。

5;在RAND中,直接调用时钟值就行了啊,为什么要还要除以101,取余数呢,只为了让数值具有随机性么
>> 除以 101 取余数,是为了限定随机数的范围吧,在 0-100 间。

6;将随机数转换为16进制表示的ASCII码字符子程序,我看得逻辑混乱了
>> 这个子程,确实是纷乱了些,没有必要这么麻烦的。可以自己试试重写个简洁些的吧。

另外,不管是来自哪里的代码,也不一定就是尽善尽美的,所以,不必太迷信。看到有好的,就吸收了;不大妥当的,就算了。


[解决办法]
如果确定算法,用汇编来写就很简单了。

建议多对照C算法,不断重构asm代码。

热点排行