zoukankan      html  css  js  c++  java
  • 汇编语言输出99乘法表

    使用8086汇编,输出99乘法表

      程序运行截图如下:

      

      要用汇编输出乘法表,实现思路有以下几点:

      1.显示出等式:可以观察到乘法表的有9行,第1行有9列,第2行有8列,第3行有7列...而且每行的等式的第一个乘数都是该行所有的列数,等式的第二个乘数是该行所有的列数递减1(为第一个等式的情况下为列数)。如第一行有9列,等式的第1个乘数都为9,第1个等式的第2个乘数为列数9,第2个等式的第2个乘数为列数9-1=8,第3个等式的第2个乘数为列数9-1-1=7。

       由这些特点可以得出用两层循环,并利用汇编loop指令的特点:每次到执行loop指令的时候,cx减一。可设置一个外层循环计数为9,内层循环计数随外层计数改变而改变,如第一次循环:外层计数等于9,内层计数等于9,循环9次打印出9个等式,等式第一个乘数都为9,等式第二个乘数从9开始递减;第二次循环:外层计数等于8,内层计数等于8,打印出8个等式,等式第一个乘数都为8,等式第二个乘数从8开始递减...

      2.计算等式:计算等式的值,我们需要存下两个乘数,再用乘法指令进行计算

      3.显示计算出来的值:由于99乘法表计算出来的值为1到81。汇编中用显示数值要进行相应的转换,0-9之间的数转换比较方便,用数值加上30h转为ASCII码输出。对于不只有个位的数值,可以用除10法进行转换,把各个位上的数转换出来,再套用显示0-9的方法进行显示,如81,转为8、1,分别输出两个字符8和1,即可在屏幕上得到81的效果。(除10法在前一篇博客中有比较详细的介绍)

      个人在实现的时候有一些问题,详见注释,请高手指点,谢谢

      代码如下(是可以跑通的...)

    DATAS SEGMENT
        CRLF db 13,10,'$'
        number dw ?,?,?,?     ;存放乘数和被乘数
        buf db ?,?,?,?        ;缓存转换出来的数字
          
    DATAS ENDS
    
    CODES SEGMENT
        ASSUME CS:CODES,DS:DATAS
    START:
        MOV   AX,DATAS
        MOV   DS,AX
        
        mov   cx,9             ;外层循环9次
      s1:
        mov   [number],cx       ;存放乘数
        push  cx                ;保存外层计数
        push  cx                 ;乘数进栈
          
       s2:                      ;内层循环,循环次数由外层循环来决定
       
           ;显示乘数
           mov     dx,[number]        
           add     dx,30h            ;转换到ASCII
           mov     ah,2
           int     21h
           
           ;显示x号
           mov     dl,78h        
           mov     ah,2
           int     21h
    
           ;显示第二个乘数
           mov     [number+1],cx        
           push     cx              ;第二个乘数进栈
           mov     dx,cx
           add     dx,30h
           mov     ah,2
           int     21h
    
           ;显示=号
           mov     dl,3dh                
           mov     ah,2
           int     21h
           
           ;计算两数相乘的结果,并显示
           pop     dx              ;取出第二个乘数
           pop     ax              ;取出第一个乘数
           push     ax              ;第一个乘数再次进栈,在下次内层循环中推出再次使用
    
           ;想直接用内存单元里面放的数据来相乘,但是结果不对
           ;所以最后用栈存放乘数再取出解决了问题
           ;调试发现第二个乘数[number+1]中的值是对的,但是[number]中的值不对
           ;很疑惑的是上面打印[number]的值显示结果正确
           ;那为什么在下面的指令中使用值就不对了呢?
           ;mov   dx,[number]
           ;mov   ax,[number+1]
           
           mul     dx          ;相乘,结果在AX中
               
           mov     bx,10        ;准备除以10
           mov     si,2         ;循环2次,最大到十位 (乘法表最大为81,所以最大到十位)
       
          
      toDec:                    ;把各个位转换为数值,如ax中的81,转换为 8,1存在内存中
          mov     dx,0        
          div     bx            ;除10法得到各个位上的数值
          mov     [buf+si],dl    ;余数为该位上的值,第一次循环为个位,第二次为十位...;存到内存中
          dec     si            
          cmp     ax,0          ;商是否为0,为0算法结束
          ja toDec
      
          
      output:                   ;输出内存中存放的转换数值数
          inc     si
          mov     dl,[buf+si]
          add     dl,30h          ;转为ascii
          mov     ah,2
          int     21h
          cmp     si,2
          jb     output    
           
          
           mov     dl,20h
           mov     ah,2
           int     21h
      
       loop     s2                ;内层循环结束
               
           lea     dx,crlf        ;输出回车换行
           mov     ah,9
           int     21h
    
           pop     cx
           pop     cx             ;还原外层计数
           
      loop     s1        
        
        mov     ah,1              ;停留等待结束
        int     21h
        
        MOV     AH,4CH
        INT     21H
    CODES ENDS
        END START

      

      

  • 相关阅读:
    delphi算法
    delphi 弹出选择目录窗口
    delphi 导出xml文件
    play 源码分析
    oracle指令
    delphi 环境问题
    如何启动redis
    关于整理和工作小结
    如何强制关闭服务
    delphi之事件
  • 原文地址:https://www.cnblogs.com/Zhang-Shangyu/p/5156329.html
Copyright © 2011-2022 走看看