宗德才, 王康康
(1.常熟理工學院,計算機科學與工程學院, 江蘇,常熟 215500;2.江蘇科技大學,數理學院, 江蘇,鎮江 212003)
目前,國內很多高校計算機組成原理實驗教學內容主要是基于TEC-XP16 教學機而開展的。為了使學生更好地掌握計算機各個組成部件的工作原理,理解計算機軟件系統的層次結構,系統地建立計算機整機概念,迫切需要開發一些設計性實驗,如在TEC-XP16教學機中設計一些新指令、利用TEC-XP16教學機的匯編指令設計高級語言解釋程序等。文獻[1]研究了在TEC-XP16教學機組合邏輯控制器中擴展簡單指令的方法;文獻[2]提出了TEC-XP16教學機微程序控制器中一種8 bit無符號數乘除指令的設計方法;文獻[3] 提出了一種快速設計實現 32 bit 浮點除法指令的方法;文獻[4]利用TEC-XP16教學機的匯編指令實現了BASIC語言解釋程序,BASIC語言解釋執行程序實現的語句如表1所示。為TEC-XP16教學機設計高級語言解釋程序,對理解計算機軟件系統的層次結構很有用,特別是機器語言、匯編語言和高級語言的功能和用法上的不同之處[4]。

表1 BASIC語言解釋程序實現的語句
本文利用TEC-XP16教學機的匯編指令[5]設計實現一種C語言解釋程序。
C語言解釋程序主要負責處理與用戶的接口,即循環處理執行即時命令和C語言語句。
即時命令包括new、run和system,如表2所示。即時命令直接輸入后按下回車鍵就直接開始運行。

表2 即時命令
為了與即時命令相區別,C程序語句前面加行號,如果只輸入一個行號后面沒有語句,則此行號無效,如果原來存在以此行號為標識的語句,則刪除原語句。
輸入完一個C語言程序之后,通過run命令運行C語言程序。
在C語言解釋程序啟動后,首先會初始化2000H~2600H地址范圍內的教學機內存和stack_While等堆棧,然后等待用戶輸入。
當用戶輸入一條C語言語句并按下回車鍵之后,首先將輸入的每一個字符的ASCII碼用16位二進制形式存入教學機2675H地址開始的內存緩沖區,然后檢查2675H地址開始的內存緩沖區。如果輸入的行號或數字在0~9之間,則用16位二進制表示,并加上數字標志1000H;如果輸入的行號或數字大于等于10,則用32位浮點數表示,并加上標志8000H;如果是保留字,則加上保留字標志2000H,如表3所示。將C語言語句的保留關鍵字[6]用一個4位十六進制數表示,如表4所示,WHILE用2000 H表示,=用201FH表示,IF用200BH表示,最后將所有的空格刪除,并將當前的C語句復制到上一條語句之后的內存緩沖區。

表3 數據類型與標志

表4 C語言保留關鍵字與對應的十六進制數
每一條C語言語句用16位語句長度、16位行號,C語言語句內容的格式存儲,如圖1所示。

圖1 C語言語句的存儲格式
輸入的第一條C語句最終將復制到教學機2000H地址開始的內存緩沖區,其余的C語句按照行號順序依次復制到上一條語句之后的內存緩沖區。
輸入完一個C語言程序之后,通過run命令即可運行這個程序。
1.2.1 初始化堆棧
檢查2000H地址開始的內存緩沖區。
(1) 取出第一條C語言語句。
(2) 檢查語句長度是否為0,若為0則結束,不為0則轉(3)。
(3) 如果語句內容部分的第一個存儲單元內容是2030H(main保留字),則語句種類0004H壓入堆棧Stack_ifwhl,然后轉(4);
如果語句內容部分是自定義函數定義,則語句種類0003H壓入堆棧Stack_ifwhl,然后轉(4);
如果語句內容部分的第一個存儲單元內容是if保留字、while保留字、else保留字,則分別將0000H、0001H和0002H壓入堆棧stack_ifwhl,并將其所在行號壓入堆棧stack_line,然后轉(4);
如果語句內容部分的第一個存儲單元內容是“}”,且堆棧stack_ifwhl棧頂是0003H, 則stack_ifwhl棧頂元素出棧,然后轉(4);
如果語句內容部分的第一個存儲單元內容是“}”,且堆棧stack_ifwhl棧頂是0004H,則取得“}”所在行號壓入堆棧stack_emain,stack_ifwhl棧頂元素出棧,然后轉(4);
如果語句內容部分的第一個存儲單元內容是“}”,且堆棧stack_ifwhl棧頂是0000H、0001H、0002H,則取得“}”所在行號分別壓入堆棧stack_eif、stack_eWhl、stack_eelse,并取得stack_line棧頂行號和“}”所在行號依次存入Rel_tbl,stack_line棧頂元素出棧,stack_ifwhl棧頂元素出棧,然后轉(4)。
(4) 取出下一條C語句,然后轉(2)。
程序運行時各個保留字與堆棧stack_ifwhl、stack_line等的關系如表5所示。Rel_tbl表用于存放while語句、if語句和else語句所在的行號與其對應的“}”所在的行號之間的對應關系。

表5 程序運行時保留字與堆棧的關系
1.2.2 運行C語言程序
從2000H地址開始運行代碼。
(1) 取出第一條C語言語句。
(2) 檢查語句長度是否為0,若為0則結束,不為0則轉(3)。
(3) 如果語句內容部分的第一個存儲單元內容是“{”,則直接轉(4);
如果語句內容部分的第一個存儲單元內容是“}” ,且“}”的行號在堆棧stack_emain中,則結束C程序的運行;
如果語句內容部分的第一個存儲單元內容是“}”,且“}”的行號在堆棧stack_eWhl中,則調用call_EWHILE子程序,調用返回后轉(4);
如果語句內容部分的第一個存儲單元內容是“}”,且“}”的行號在堆棧stack_eelse中,則直接轉(4);
如果語句內容部分的第一個存儲單元內容是“}”,且“}”的行號在堆棧stack_eif中,如果if后沒有else則轉(4),如果if后有else則找到else語句的結束“}”的行號,轉(4);
如果語句內容部分是自定義函數調用,則調用call_Func子程序,調用返回后轉(4);
如果語句內容部分的第一個存儲單元內容是C語言保留關鍵字,則執行過程調用,如r0中是2000h,則執行call_WHILE子程序;如r0中是200Bh,則執行call_if子程序;如r0中是200Dh,則執行call_Return子程序,調用返回后轉(4)。
(4) 取出下一條C語句,然后轉(2)。
call_While子程序的執行過程如下:
(1) 取得當前while語句所在的行號送r7寄存器;
(2) 計算while語句的條件表達式是否成立,若條件成立,則從堆棧stack_While棧頂取出行號送r1寄存器如果r7寄存器的值等于r1寄存器的值,則r14寄存器指向下一個語句行的長度位置;如果r7寄存器的值不等于r1寄存器的值,則將r7寄存器的值壓入堆棧stack_While并且r14指向下一個語句行的長度位置;
(3) 如果while語句的條件表達式不成立,則堆棧stack_While棧頂元素出棧,在Rel_tbl表中查找與當前while語句對應的“}”語句所在的行號,r14指向找到的“}”語句的下一個語句行的長度位置。
call_EWHILE子程序的執行過程如下:
從堆棧stack_While棧頂取出行號送r1寄存器,從2000H地址開始查找行號等于r1寄存器值的語句行,r14指向該語句行的語句長度位置,如果沒有找到則報錯。
call_If子程序的執行過程如下:
(1) 取得當前if語句所在的行號送r7寄存器;
(2) 計算if語句的條件表達式是否成立,如果條件成立,則r14指向下一個語句行的長度位置;
(3) 如果if語句的條件表達式不成立,則在Rel_tbl表中查找與當前if語句對應的“}”語句所在的行號,然后判斷“}”語句后面有沒有else,如有else則執行else語句,若沒有else則r14指向找到的“}”語句的下一個語句行的語句長度位置。
call_Func傳值調用時形式參數與調用函數實參的關系:
(1) 將調用函數的實參值從右往左先后壓入堆棧stack_funcPr;
(2) 將被調用函數形式參數名與調用函數實參值所在的內存地址對應關系存放到Func_Ptbl表;
(3) 令SubFun_flag=1;
(4) call_Func函數執行過程中,在Func_Ptbl表中查找與被調用函數中形參名對應的調用函數實參值地址。
call_FUNC傳地址調用時形式參數與調用函數實參的關系:
(1) 將調用函數的實參地址從右往左先后壓入堆棧Stack_funcPr;
(2) 將被調用函數形式參數名與調用函數實參地址所在的內存地址之間的對應關系存放到Func_Ptbl表;
(3) 令SubFun_flag=1;
(4) 在call_func函數執行過程中,在Func_Ptbl表中查找與被調用函數中形式參數名對應的調用函數實參地址所在的內存地址。
call_Return子程序執行后,令SubFun_flag=0,返回到函數調用語句的下一條語句處。
首先,將保存在main.asm文件中的C語言解釋程序用教學機匯編程序teca.exe匯編成MAIN.COD二進制文件。接著,啟動TEC-XP16教學機模擬軟件,然后啟動教學機監控程序,如圖2所示。

圖2 啟動監控程序成功
圖2中選擇“發送文件”按鈕,把C語言解釋程序調入模擬系統,使系統進入C語言程序的運行環境。
在監控程序中輸入g0a30啟動C語言程序的運行環境,如圖3所示。

圖3 啟動C語言程序的運行環境
為了驗證C語言解釋程序的正確性,設計了while循環語句的嵌套、while-if語句的嵌套、傳值函數調用和傳地址函數調用4個C語言程序,如圖4~圖7所示,仿真結果表明所設計的C語言解釋程序是正確的。

圖4 while循環語句嵌套

圖5 while-if語句嵌套
利用TEC-XP16教學機的匯編指令設計C語言解釋程序可以作為計算機組成原理實驗內容和課程設計內容,對學生理解掌握教學機的匯編指令很有幫助。為TEC-XP16教學機設計C語言運行環境能夠使學生更加深刻地理解機器語言、匯編語言和高級語言之間的聯系與區別。
之后將進一步完善C語言運行環境,使其能支持for語句、do-while語句、break語句、continue語句、switch語句等,并使其能夠保存輸入的C程序以及打開已有的C程序文件。

圖6 傳值函數調用

圖7 傳地址函數調用