匯編語言輸出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

 

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM