使用8086彙編,輸出99乘法表算法
程序運行截圖以下:緩存
要用匯編輸出乘法表,實現思路有如下幾點:oop
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。spa
由這些特色能夠得出用兩層循環,並利用匯編loop指令的特色:每次到執行loop指令的時候,cx減一。可設置一個外層循環計數爲9,內層循環計數隨外層計數改變而改變,如第一次循環:外層計數等於9,內層計數等於9,循環9次打印出9個等式,等式第一個乘數都爲9,等式第二個乘數從9開始遞減;第二次循環:外層計數等於8,內層計數等於8,打印出8個等式,等式第一個乘數都爲8,等式第二個乘數從8開始遞減...3d
2.計算等式:計算等式的值,咱們須要存下兩個乘數,再用乘法指令進行計算調試
3.顯示計算出來的值:因爲99乘法表計算出來的值爲1到81。彙編中用顯示數值要進行相應的轉換,0-9之間的數轉換比較方便,用數值加上30h轉爲ASCII碼輸出。對於不僅有個位的數值,能夠用除10法進行轉換,把各個位上的數轉換出來,再套用顯示0-9的方法進行顯示,如81,轉爲八、1,分別輸出兩個字符8和1,便可在屏幕上獲得81的效果。(除10法在前一篇博客中有比較詳細的介紹)code
我的在實現的時候有一些問題,詳見註釋,請高手指點,謝謝blog
代碼以下(是能夠跑通的...)內存
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