前一節我們示範了如何用 test larger 和 goto 來實現 if-else 之流程控制, 現在進一步示範迭代。While, for 和 do-until 都是迭代的形式, 我們已經知道這三個形式在程式語言的層次都可以互換, 要分成三個形式的原因,只是為了方便而已。 因此我們在此只考慮 while 形式。只要知道機器碼怎樣實現 while 迴圈, 其他種類的迭代也就都沒有問題了。
寫一個程式,輸出 0 1 2 3 4 5 6 7 8 9 這十個數目字。 這道題目不能作弊:不能先在資料段,利用十個記憶體寫入 0, 1, ..., 9, 然後不用迴圈的方法而一一 load R0 然後再 print R0。 因為這裡有十個數,如果要靠蠻力一一 load R0 然後再 print R0, 需要 20 個機器碼,但是 BCC16VM 只有 16 個位址來儲存機器碼。 因此,我們必須使用迴圈。用 C 來寫,應該像是這樣:
n=0; while (n<=9) { printf("%d ", n); n = n+1; }如果要翻譯成機器碼,我們需要一個記憶體來儲存 n, 一個儲存 9,一個儲存 1。還好,只要儲存三個數 (不管是常數還是變數), 因此,用 R0, R1, R2 就夠了,不必用到資料段記憶體。
在上述觀察之下,我們設計機器碼程式之流程如下:
上述流程不難實現,而且我們假設完全不去動用記憶體。如下。
指令位址 | 記號 | 機器碼 |
---|---|---|
0000 | generate 0 | 01010000 |
0001 | copy R0 R2 | 10010010 |
0010 | generate 1 | 01010001 |
0011 | copy R1 R2 | 10010110 |
0100 | generate 9 | 01011001 |
0101 | test larger R0 R2 | 01100010 |
0110 | stop | 00000000 |
0111 | print R0 | 00001010 |
1000 | print ' ' | 00000010 |
1001 | add R0 R1 | 00010001 |
1010 | goto 4 | 10000100 |
【注意】BCC16VM 有錯,test larger 變成了測試 >= 我們將會修改
習題
8 7 6 5 4 3 2 1