專利名稱::用微控制器使用高級程序設(shè)計語言的制作方法本專利文件的部分內(nèi)容含有受版權(quán)保護的材料。版權(quán)所有人不反對任何人按美國專利和商標局的文件或記錄的形式原樣復(fù)制該專利文件,但是保留所有的版權(quán)權(quán)利。根據(jù)35U.S.C.§119(e),本申請要求在先的美國臨時申請系列號60/029,057(1996年10月25日提交)的權(quán)益。本發(fā)明總的來說涉及程序設(shè)計領(lǐng)域,更具體來說涉及用智能卡或微控制器來使用高級程序設(shè)計語言。用JAVA高級程序設(shè)計語言編寫的軟件應(yīng)用程序是這樣設(shè)計的,即用JAVA編寫的應(yīng)用程序能不加改變地在許多不同的計算機品牌或計算機平臺上運行。這是通過以下步驟實現(xiàn)的。在編寫JAVA應(yīng)用程序時,它被編譯成含有字節(jié)代碼的“類”文件,字節(jié)代碼是稱為JAVA虛擬機的假想計算機的指令。這個虛擬機的實現(xiàn)要為每個被支持的平臺編寫。當(dāng)某個用戶希望在選定平臺上運行特定JAVA應(yīng)用程序時,從所要求的應(yīng)用程序編譯成的類文件就被加載到選定平臺上。選定平臺的JAVA虛擬機被運行,解釋類文件中的字節(jié)代碼,這樣實際就是在運行JAVA應(yīng)用程序。以下參考文獻描述了JAVA,本文引用它們作為參考(1)Arnold、Ken和JameGosling的《TheJavaProgrammingLanguage》(Addison-Wesley出版,1996年);(2)JameGosling、BillJoy和GuySteele的《TheJavaLanguageSpecification》(SunMicorsystems出版,1996年,web網(wǎng)址http∥java.sun.com/doc/language_environment/);(3)JameGosling和HenryMcGilton的《TheJavaLanguageEnvironmentAWhitePaper》(SunMicorsystems出版,1995年,web網(wǎng)址http∥java.sun.com/doc/language_environment/);(4)TimLindholm和FrankYellin的《TheJavaVirtualMachineSpecification》(Addison-Wesley出版,1997年)。這些文章和其它文章都描述了如何用JAVA編寫程序。為了讓JAVA應(yīng)用程序能在特定平臺上運行,要編寫一個在該平臺的限制條件內(nèi)運行的JAVA虛擬機實現(xiàn),還必須提供一個用于將所要求的JAVA應(yīng)用程序加載到該平臺的機構(gòu),并且還是保持在該平臺的限制條件內(nèi)。常規(guī)的支持JAVA的平臺通常是基于微處理器的計算機,能訪問相對大量的內(nèi)存和硬盤存儲空間。這種微處理器實現(xiàn)經(jīng)常用在桌面電腦和個人電腦中。然而,在智能卡通常使用的微控制器中卻沒有常規(guī)的JAVA實現(xiàn)。微控制器與微處理器的差別有許多方面。例如,微處理器一般有一個中央處理單元,它要求一定的外部部件(例如存儲器、輸入控制和輸出控制)要功能正常。典型的微處理器可以訪問從Mb級到Gb級容量的存儲器,用一條指令就能處理16、32或64位或更大的數(shù)據(jù)。與微處理器不同,微控制器包括的中央處理單元、存儲器和其它功能單元都在一個半導(dǎo)體基片或集成電路(例如“芯片”)上。與微處理器訪問的相對較大的外部存儲器相比,典型的微控制器訪問的存儲器容量小得多。典型的微控制器能訪問1到64Kb的內(nèi)置存儲器,16Kb則非常普遍。一般來說有三種不同類型的存儲器被使用隨機存取存儲器(RAM)、只讀存儲器(ROM)、電可擦除可編程只讀存儲器(EEPROM)。在微控制器中,每一種存儲器的可用容量受到集成電路上用于每一種存儲器的空間的限制。通常,RAM占用的空間最多,處于短缺狀態(tài);ROM占用空間最少,處于充足狀態(tài);EEPROM比RAM更充足,但不及ROM。每一種存儲器適合于不同的用途。盡管ROM最價廉,但它只適用于沒有變化的數(shù)據(jù),諸如操作系統(tǒng)的代碼。EEPROM用于存儲斷電時必須保留的數(shù)據(jù),但是寫的速度極慢。RAM可以高速讀寫,但是價格高,斷電時數(shù)據(jù)丟失。微處理器系統(tǒng)通常有較小的ROM和EEPROM,有1-128Mb的RAM-這是因為不受在單個集成電路設(shè)備上要受到的約束,經(jīng)常能訪問外部磁盤存儲器系統(tǒng),后者作為大型可寫、非易失性存儲區(qū),費用比EEPROM更低。然而,微控制器通常有個0.1~2.0K的小RAM、2K~8K的EEPROM、8K~56K的ROM。由于所需的外部部件數(shù)量少,體積小,微控制器經(jīng)常用于集成電路卡,諸如智能卡。這種智能卡有各種形式,包括基于接觸的卡和無接觸的卡,前者必須插入讀卡機才能使用,后者則不必插入。事實上,以無接觸方式通訊的微控制器通常被嵌入特殊造型中,例如手表和戒指中,實際上以符合人機工程學(xué)的引人入勝方式集成了智能卡的功能。由于環(huán)境要求的限制,用于智能卡的應(yīng)用程序通常是用低級程序設(shè)計語言(例如匯編語言)編寫的,以節(jié)約存儲空間。集成電路卡是一種安全、耐用、抗干擾、便于攜帶的數(shù)據(jù)存儲設(shè)備。集成電路卡是最個人化的個人電腦,因為其體積小,因為其具有集成電路卡所獨有的硬件和軟件數(shù)據(jù)安全特點。集成電路卡和卡上的微控制器的主要任務(wù)是保護存儲在卡上的數(shù)據(jù)。因此,自1974發(fā)明以來,出于這些相同的安全原因,智能卡技術(shù)受到嚴密的保護。智能卡首先由法國的銀行作為信用卡使用。在這種應(yīng)用中,在基于信用卡的金融交易被認可之前,信用卡用戶除了擁有其持的卡外還必須表明其知道一個4位數(shù)的個人標識號(PIN)。任何可能導(dǎo)致發(fā)現(xiàn)遺失或被偷信用卡上的個人標識號的信息都被堵塞在公共傳播之外。事實上,由于在這一方面沒有人能分辨哪些信息可能有用,幾乎所有有關(guān)集成電路卡的信息都被隱瞞起來。出于保密性考慮,為集成電路卡編寫的應(yīng)用程序具有獨特的性質(zhì)。例如,每個應(yīng)用程序通常只以某特定所有人或身份來標識。由于應(yīng)用程序通常是用低級程序設(shè)計語言諸如匯編語言編寫的,所以應(yīng)用程序是為特定類型的微控制器編寫的。由于低級程序設(shè)計語言的性質(zhì),未經(jīng)認可的應(yīng)用程序可以訪問集成電路卡上的數(shù)據(jù)。為特定集成電路卡編寫的程序要用特定本體來標識,使得如果兩個本體想要執(zhí)行同一個編程功能,集成電路卡的微控制器上應(yīng)用程序的有些部分必須有兩份拷貝。集成電路卡系統(tǒng)歷史上一直是封閉的系統(tǒng)。集成電路卡含有為了與特定終端應(yīng)用共同工作而設(shè)計的專有應(yīng)用程序。集成電路卡使用時的安全檢查的內(nèi)容,主要是確認卡應(yīng)用程序與終端應(yīng)用程序是匹配的一對,卡上的數(shù)據(jù)是有效數(shù)據(jù)。隨著集成電路卡流行程度的提高,集成電路卡用戶顯然會不愿意攜帶適合各個集成電路卡應(yīng)用的不同集成電路卡。因此開始在一個提供商的集成電路卡上提供多個合作應(yīng)用。于是,例如一個自動柜員機(ATM)訪問卡和一個借方卡可以共存于單一的集成電路卡平臺上。不過,這仍然是一種封閉系統(tǒng),因為終端和卡中的所有應(yīng)用都是由一個清楚地了解其它提供商的提供商建立的。有關(guān)集成電路卡的信息—特別是有關(guān)如何與它們通訊以及如何為它們編寫程序的信息—的缺乏,已經(jīng)阻礙了集成電路卡的普遍應(yīng)用。然而,公用數(shù)字網(wǎng)絡(luò)(例如因特網(wǎng)和萬維網(wǎng))的出現(xiàn)已經(jīng)為集成電路卡的應(yīng)用開放了新的領(lǐng)域。特別地,這已經(jīng)導(dǎo)致需要在卡上裝入不是清楚地了解其它提供商的新的應(yīng)用程序,但是不可能破壞卡的保密性。然而,對于用低級程序設(shè)計語言編制的常規(guī)卡來說,這種做法是不切實際的??傊?,作為本發(fā)明特點的一個方面是一種用于終端的集成電路卡。集成電路卡包括一個存儲解釋程序和具有高級程序設(shè)計語言格式的應(yīng)用程序的存儲器??ǖ奶幚砥鞅慌渲脼橛媒忉尦绦蚪忉寛?zhí)行該應(yīng)用程序,并用卡的通信器與終端通信。以下是本發(fā)明的其中一些優(yōu)點。新的應(yīng)用程序可以下載到智能卡,而不破壞智能卡的安全性。這些應(yīng)用程序可以是由不同的公司提供的,可以用不同的終端在不同的時間加載。安全性之所以不受破壞,是因為應(yīng)用程序受到防止未授權(quán)訪問任何應(yīng)用程序代碼或數(shù)據(jù)的保護,這種保護是由JAVA虛擬機提供的安全特點決定的。智能卡應(yīng)用程序可以采用功能強大的主流程序開發(fā)工具、以諸如JAVA和Eiffel的高級語言進行編制。新的應(yīng)用程序能在數(shù)小時內(nèi)迅速成型并下載到智能卡,無須借助軟屏蔽。采用微控制器的嵌入式系統(tǒng)通過使用本發(fā)明,也能獲得許多這些優(yōu)點,來下載新的應(yīng)用程序、進行高級語言程序開發(fā)和快速成型。本發(fā)明的實現(xiàn)包括以下若干內(nèi)容。應(yīng)用程序的高級程序設(shè)計語言格式可能有類文件格式,可能有JAVA程序設(shè)計語言格式。處理器可以是微控制器。存儲器至少有一部分可能位于處理器中。該應(yīng)用程序可以是從有一個字符串的第二應(yīng)用程序已經(jīng)處理過,該字符串可以在第一應(yīng)用程序中用一個標識符(例如整數(shù))來代表。處理器也可以被配置成接收來自某請求者(例如處理器或終端)的要求訪問卡的某單元(例如存儲器中存儲的應(yīng)用程序、存儲器中存儲的數(shù)據(jù)、通信器)的請求,接收請求后,與請求者交互作用,以驗證請求者的身份,根據(jù)該身份,有選擇地授予對該單元的訪問權(quán)。存儲器也可以存儲該單元的訪問控制清單。訪問控制清單設(shè)有標志,指示要授予該身份的訪問權(quán)的類型,根據(jù)訪問控制清單,處理器選擇性地將特定類型的訪問(例如讀數(shù)據(jù)、寫數(shù)據(jù)、追加數(shù)據(jù)、創(chuàng)建數(shù)據(jù)、刪除數(shù)據(jù)或者執(zhí)行應(yīng)用程序)授予請求者。應(yīng)用程序可以是存儲器中存儲的若干應(yīng)用程序的其中之一。處理器也可以被進一步配置成接收來自某請求者的要求訪問這多個應(yīng)用程序中之一的請求;接收請求后,判斷所述多個應(yīng)用程序之一是否符合預(yù)定的規(guī)則集;根據(jù)這個判斷,選擇性地授予請求者對所述多個應(yīng)用程序之一的訪問權(quán)。預(yù)定的規(guī)則為判斷所述多個應(yīng)用程序之一是否訪問存儲器預(yù)定區(qū)域提供了指南。處理器可以被進一步配置成能驗證請求者的身份,并根據(jù)該身份,授予對所述多個應(yīng)用程序之一的訪問權(quán)。處理器也可以被配置成能通過通信器與終端進行交互作用來驗證請求者的身份;能判斷身份是否已經(jīng)驗證;能根據(jù)該判斷,選擇性地允許終端與集成電路卡之間進行通信。通信器和終端可以通過通信通道進行通信。處理器也可以被配置成能在處理器允許終端與集成電路卡之間進行通信時將通信通道之一分配給該身份。處理器也可以被配置成能將對話關(guān)鍵碼分派給所分配的通信通道并在處理器與終端通過所分配的通信通道進行通信時使用該對話關(guān)鍵碼。終端可以有一個讀卡機,通信器可以包括一個用于與讀卡機通信的觸點。終端可以包括一個無線通信設(shè)備,通信器可以包括一個用于與該無線通信設(shè)備通信的無線收發(fā)機。終端可以有一個無線通信設(shè)備,通信器可以包括一個用于與該無線通信設(shè)備通信的無線發(fā)射機。概括來說,本發(fā)明具有的特點的另一個方面是,一種用于集成電路卡和終端的方法。該方法包括在集成電路卡存儲器中存儲一個解釋程序和至少一個具有高級程序設(shè)計語言格式的應(yīng)用程序。集成電路卡的處理器用解釋程序來解釋執(zhí)行該至少一個應(yīng)用程序,當(dāng)處理器與終端之間進行通信時,處理器使用該卡的一個通信器。概括來說,本發(fā)明具有的特點的另一個方面是一種智能卡。該智能卡包括一個存儲JAVA解釋程序的存儲器和一個被配置成能用解釋程序解釋執(zhí)行JAVA應(yīng)用程序的處理器。概括來說,本發(fā)明具有的特點的另一個方面是一種具有半導(dǎo)體襯底和位于襯底的存儲器的微控制器。一個程序設(shè)計語言解釋程序存儲在存儲器中并被配置成能執(zhí)行安全檢查。一個中央處理單元位于襯底中并與存儲器相連。本發(fā)明的實現(xiàn)可以包括以下若干內(nèi)容。解釋程序可以是JAVA字節(jié)代碼解釋程序。安全檢查可以包括建立防火墻并且包括實施一個砂箱安全模型(sandboxsecuritymodel)。概括來說,本發(fā)明具有的特點的另一個方面是一種具有在卡的存儲器中存儲的程序設(shè)計語言解釋程序的智能卡。解釋程序被配置成能執(zhí)行安全檢查??ǖ闹醒胩幚韱卧c存儲器相連。概括來說,本發(fā)明具有的特點的另一個方面是一種用于終端的集成電路卡。該卡包括一個通信器和一個存儲解釋程序和第一應(yīng)用程序的第一指令的存儲器。第一應(yīng)用程序的第一指令是從第二應(yīng)用程序的第二指令轉(zhuǎn)換的。集成電路卡包括一個處理器,處理器與存儲器相連,并被配置成能利用解釋程序執(zhí)行第一指令以及通過通信器與終端進行通信。本發(fā)明的實現(xiàn)包括以下若干內(nèi)容。第一和/或第二應(yīng)用程序可以具有類文件格式。第一和/或第二應(yīng)用程序可以包括字節(jié)代碼,諸如JAVA字節(jié)代碼。第一指令可以是第二指令的綜合版本或重新編號的版本。第二指令可以包括常量引用,第一指令可以包括替代第二指令的常量引用的常量。第二指令可以包括引用,引用在第二指令向第一指令的轉(zhuǎn)換期間可以移動位置。移動之后,第一指令可以重新連接到該引用。第一指令可以包括用于第一類虛擬機的字節(jié)代碼,第二指令可以包括用于第二類虛擬機的字節(jié)代碼。第一類與第二類不同。概括來說,本發(fā)明具有的特點的另一個方面是一種用于集成電路卡的方法。該方法包括將第二應(yīng)用程序的第二指令轉(zhuǎn)換成第一應(yīng)用程序的第一指令,將第一指令存儲到集成電路卡的存儲器中,用集成電路卡的解釋程序執(zhí)行第一指令。概括來說,本發(fā)明具有的特點的另一個方面是一種用于終端的集成電路卡。該集成電路卡有一個通信器和一個存儲器,通信器被配置成能與終端通信,存儲器存儲已從具有一個字符串的第二應(yīng)用程序處理形成的第一應(yīng)用程序,該字符串在第一應(yīng)用程序中用一個標識符來代表。集成電路卡包括一個與存儲器相連的處理器。處理器被配置成用解釋程序去解釋執(zhí)行第一應(yīng)用程序,用通信器去與終端通信。概括來說,本發(fā)明具有的特點的另一個方面是一種用于集成電路卡和終端的方法。該方法包括處理第二應(yīng)用程序以創(chuàng)建第一應(yīng)用程序。第二應(yīng)用程序有一個字符串,該字符串在第一應(yīng)用程序中用一個標識符來代表。集成電路卡的存儲器中存儲一個解釋程序和第一應(yīng)用程序。處理器用解釋程序去解釋執(zhí)行第一應(yīng)用程序。概括來說,本發(fā)明具有的特點的另一個方面是一種包括一個存儲應(yīng)用程序和解釋程序的存儲器的微控制器。應(yīng)用程序有一個類文件格式。微控制器的處理器連接存儲器并被配置成用解釋程序來解釋執(zhí)行應(yīng)用程序。在本發(fā)明的實現(xiàn)中,微控制器也可以包括一個配置成與終端通信的通信器。概括來說,本發(fā)明具有的特點的另一個方面是一種用于集成電路卡的方法。該方法包括在集成電路卡的存儲器中存儲第一應(yīng)用程序,在集成電路卡的存儲器中存儲第二應(yīng)用程序,建立一個隔離第一應(yīng)用程序與第二應(yīng)用程序的防火墻,使得第二應(yīng)用程序既不能訪問與第一應(yīng)用程序,也不能訪問與第一應(yīng)用程序關(guān)聯(lián)的數(shù)據(jù)。概括來說,本發(fā)明具有的特點的另一個方面是一種用于終端的集成電路卡。該集成電路卡包括一個配置成與終端通信的通信器、一個存儲器和一個處理器。存儲器存儲應(yīng)用程序,每個應(yīng)用程序都有高級程序設(shè)計語言格式。存儲器也存儲一個解釋程序。處理器與存儲器連接,并被配置成a)用解釋程序來解釋執(zhí)行應(yīng)用程序,b)用解釋程序建立一個將應(yīng)用程序互相隔離的防火墻,c)用通信器與終端通信。閱讀以下說明和權(quán)利要求,其它優(yōu)點和特點將是顯而易見的。圖1是一個集成電路卡系統(tǒng)的框圖。圖2是表示對要下載到集成電路卡的JAVA應(yīng)用程序進行準備的流圖。圖3是由卡類文件轉(zhuǎn)換器使用并生成的文件的框圖。圖4是表示應(yīng)用程序類文件變換成卡類文件的框圖。圖5是表示類文件轉(zhuǎn)換器的工作的流圖。圖6是表示字節(jié)代碼的修改的流圖。圖7是表示專用字節(jié)代碼變換成通用字節(jié)代碼的框圖。圖8是表示用常量替換常量引用的框圖。圖9是表示將引用用它們的更新值進行替換的框圖。圖10是表示對原始字節(jié)代碼重新編號的框圖。圖11是表示為不同的虛擬機結(jié)構(gòu)翻譯原始字節(jié)代碼的框圖。圖12是表示將應(yīng)用程序加載到集成電路卡的框圖。圖13是表示在集成電路卡中執(zhí)行應(yīng)用程序的框圖。圖14是表示ROM、RAM和EEPROM的存儲器組織結(jié)構(gòu)的示意圖。圖15是表示卡JAVA虛擬機的總體體系結(jié)構(gòu)的流圖。圖16是表示在帶有安全檢查的卡JAVA虛擬機中的過程執(zhí)行的流圖。圖17是表示卡JAVA虛擬機中的字節(jié)代碼執(zhí)行的流圖。圖18是表示在沒有安全檢查的卡JAVA虛擬機中的過程執(zhí)行的流圖。圖19是表示卡應(yīng)用程序與身份之間的關(guān)聯(lián)性的框圖。圖20是表示專用運行應(yīng)用程序的訪問權(quán)的框圖。圖21是智能卡上的微控制器的透視圖。圖22是電話上的微控制器的透視圖。圖23是鑰匙環(huán)上的微控制器的透視圖。圖24是戒指上的微控制器的透視圖。圖25是汽車電路卡上的微控制器的透視圖。參見圖1,構(gòu)造一個集成電路卡10(例如智能卡)來提供一個高級的、基于JAVA的多應(yīng)用程序編程和執(zhí)行環(huán)境。集成電路卡10有一個通信器12a,它被配置成與終端14的終端通信器12b進行通信。在有些實施例中,集成電路卡10是一個智能卡,帶有8位的微控制器、512字節(jié)的RAM、4K字節(jié)的EEPROM和20K字節(jié)的ROM;終端通信器12b是常規(guī)的接觸式智能卡讀卡機;終端14是運行WindowsNT操作系統(tǒng)的常規(guī)個人電腦,該操作系統(tǒng)支持個人電腦智能卡(PC/SC)標準并提供JAVA開發(fā)支持。在有些實施例中,微控制器、存儲器和通信器內(nèi)置于與通常的信用卡尺寸幾乎相同的塑料卡中。在另一些實施例中,微控制器、存儲器和通信器安裝在塑料卡以外的基體中,諸如首飾(例如手表、戒指或項鏈)、汽車設(shè)備、電信設(shè)備(例如用戶身份模塊(SIM)卡)、安全設(shè)備(例如加密模塊)和家用電器中。終端14準備JAVA應(yīng)用程序并用終端通信器12b將JAVA應(yīng)用程序加載到集成電路卡10。終端通信器12b是一種能在集成電路卡10與終端14之間建立通信通道的通信設(shè)備。有些通信選擇包括接觸式讀卡機、通過無線頻率或紅外技術(shù)的無線通信,串行通信協(xié)議、分組通訊協(xié)議、ISO7816通訊協(xié)議,等等。終端14也能與集成電路卡10中運行的應(yīng)用程序交互作用。在有些情況下,可以用不同的終端來實現(xiàn)這種目的。例如,可以用一種終端來準備應(yīng)用程序,用不同的終端來下載應(yīng)用程序,用另外其它終端來運行各種應(yīng)用程序。終端可以是自動柜員機(ATM)、銷售點終端、防盜門系統(tǒng)、付費系統(tǒng)、存取控制系統(tǒng)、或者任何其它與集成電路卡或微控制器通信的系統(tǒng)。集成電路卡10含有卡JAVA虛擬機(卡JVM)16,它被用于解釋卡10上含有的應(yīng)用程序。參見圖2,JAVA應(yīng)用程序20包括三個JAVA源代碼文件A.java20a、B.java20b和C.java20c。這些源代碼文件是在JAVA應(yīng)用程序開發(fā)環(huán)境22中被準備和編譯的。當(dāng)JAVA應(yīng)用程序20被開發(fā)環(huán)境22編譯時,就產(chǎn)生了應(yīng)用程序類文件24,其中這些類文件A.class24a、B.class24b和C.class24c分別對應(yīng)它們各自的類JAVA源代碼20a、20b和20c。應(yīng)用程序類文件24符合《JAVA虛擬機規(guī)范》第4章記載的標準類文件格式(《JAVA虛擬機規(guī)范》為TimLindholm和FrankYellin所著,1996年Addison-Wesley公司出版)。這些類文件24被饋送到卡類文件轉(zhuǎn)換器26,后者將文件合并、壓縮,生成單一的卡類文件27。用常規(guī)的卡加載器28將卡類文件27裝入集成電路卡10。參見圖3,卡類文件轉(zhuǎn)換器26是一個處理一組按標準JAVA類文件格式編碼的類文件24的類文件后處理器,它可選擇采用一種串到ID輸入映射文件30來生成某種卡類文件格式的JAVA卡類文件27。附錄A描述了一個這種卡類文件格式,本文引為參考。此外,在有些實施例中,卡類文件轉(zhuǎn)換器26產(chǎn)生一個串到ID輸出映射文件32,用作卡類文件轉(zhuǎn)換器的后繼執(zhí)行的輸入。在有些實施例中,為了使串到ID映射與以前生成的卡類文件一致(在有多個類文件引用相同的串的情況下),卡類文件轉(zhuǎn)換器26能從串到ID輸入映射文件30接受以前定義的串到ID映射。如果沒有這一個文件,各ID就由卡類文件轉(zhuǎn)換器26生成。本文引為參考的附錄B描述了實現(xiàn)并產(chǎn)生串到ID輸入映射文件30和串到ID輸出映射文件32的一種可能方法,并舉例說明了這種映射表。參見圖4,典型的應(yīng)用程序類文件24a包括類文件數(shù)據(jù)41,類常量池42,類、域創(chuàng)建的、界面引用的和過程數(shù)據(jù)43,以及各種屬性數(shù)據(jù)44,它們在前文所述的《JAVA虛擬機規(guī)范》中有詳細說明。注意,屬性數(shù)據(jù)44中許多對于本實施例來說并不需要,因此被卡類文件轉(zhuǎn)換器26剔除45。剔除的屬性包括SourceFile、ConstantValue、Exceptions、LineNumberTable、LocalVariableTable以及任何可選擇的售主屬性。如附錄A中所述的典型卡類文件27是按下列方式從應(yīng)用程序類文件24導(dǎo)出的??愇募?shù)據(jù)46是從所有應(yīng)用程序類文件24a、24b、24c的合計類文件數(shù)據(jù)41導(dǎo)出的。卡類文件常量池47是從所有應(yīng)用程序類文件24a、24b、24c的合計類常量池42導(dǎo)出的???、域創(chuàng)建的、界面引用的和過程數(shù)據(jù)48是從所有應(yīng)用程序類文件24a、24b、24c的合計類、域創(chuàng)建的、界面引用的和過程數(shù)據(jù)43導(dǎo)出的。本實施例中的卡屬性數(shù)據(jù)49僅僅是從所有應(yīng)用程序類文件24a、24b、24c的合計屬性數(shù)據(jù)44的代碼屬性導(dǎo)出的。為了避免在卡中進行動態(tài)鏈接,在構(gòu)成應(yīng)用程序24的若干JAVA類文件24a、24b、24c之間分配的所有數(shù)據(jù)被圖5中流圖中所示的進程合并成一個卡類文件27。在51a,選擇要處理的第一類文件。在51b以下述方式壓縮常量池42。JAVA類文件24a中引用的所有對象、類、域、過程都被用類文件24a的常量池42中的串來標識??愇募D(zhuǎn)換器26將在JAVA類文件24a中發(fā)現(xiàn)的常量池42壓縮成一個優(yōu)化版本。這種壓縮是通過將類文件常量池42中發(fā)現(xiàn)的所有串映射成整數(shù)而完成的(其大小依微控制器的體系結(jié)構(gòu)而定)。這些整數(shù)也被稱作ID。每個ID唯一地標識應(yīng)用程序20中的某特定對象、類、域或過程。因此,卡類文件轉(zhuǎn)換器26將JAVA類文件常量池42中的串替換為其對應(yīng)的唯一ID。附錄B顯示一例應(yīng)用程序HelloSmartCard.java,位于附錄下部的表說明的是與該應(yīng)用程序的類文件的常量池中發(fā)現(xiàn)的串對應(yīng)的ID。本例中所用的ID都是16位無符號整數(shù)。下一步,在51c卡類文件轉(zhuǎn)換器26在輸入JAVA類文件24a的代碼屬性中檢查不受支持的特征碼??↗VM16只支持全部JAVA字節(jié)代碼的一個子集,具體如本文引為參考的附錄C中所述。因此,卡類文件轉(zhuǎn)換器26在JAVA類文件24a的代碼屬性中檢查不受支持的字節(jié)代碼。如果在52發(fā)現(xiàn)任何不受支持的字節(jié)代碼,卡類文件轉(zhuǎn)換器設(shè)立一個錯誤標志并停止轉(zhuǎn)換53。附錄D中作“A”標記的程序代碼片斷顯示了這些寄生字節(jié)代碼是如何被理解的。通過要求標準JAVA開發(fā)環(huán)境22編譯帶“-g”標志的應(yīng)用程序22可以進行另一個層次的檢查。根據(jù)上述JAVA虛擬機規(guī)范,該選項要求JAVA編譯器將關(guān)于JAVA應(yīng)用程序20中所使用變量的數(shù)據(jù)放置到類文件24a的LocalVariableTable屬性中??愇募D(zhuǎn)換器26利用這個數(shù)據(jù)來檢查JAVA類文件24a是否引用不被JAVA卡支持的數(shù)據(jù)類型。下一步,卡類文件轉(zhuǎn)換器26丟棄進行解釋時不要求的、JAVA類文件24a中的所有不需要的部分。JAVA類文件24a存儲與在JAVA類文件的屬性節(jié)44中的類文件中的字節(jié)代碼有關(guān)的數(shù)據(jù)。在45卡JVM16進行解釋時所不要求的屬性,諸如SourceFile、ConstantValue、Exceptions、LineNumberTable、LocalVariableTable可以安全地丟棄。唯一被保留的屬性是代碼屬性。代碼屬性含有對應(yīng)于JAVA類文件24a中過程的字節(jié)代碼。修改字節(jié)代碼54涉及到檢查類文件中每個過程的代碼屬性數(shù)據(jù)44,以及修改引用JAVA類文件常量池42的條目的字節(jié)代碼的操作數(shù)以反映卡類文件常量池47中的條目。在有些實施例中,字節(jié)代碼也被修改,如下文所述。修改字節(jié)代碼54涉及五遍(兩遍是可選擇的),如圖6中的流圖所述。原始字節(jié)代碼60被發(fā)現(xiàn)在正被處理的JAVA類文件24a的代碼屬性44中。第一遍61記錄所有跳轉(zhuǎn)及其在源字節(jié)代碼中的目的地。在以后進行的字節(jié)代碼翻譯中,有些單字節(jié)代碼可能被翻譯成2個或3個字節(jié)。圖7所示的例子中,字節(jié)代碼ILOAD_0被用兩個字節(jié)代替字節(jié)代碼ILOAD和參數(shù)0。這一步完成后,代碼大小發(fā)生變化,這就要求對受其影響的任何跳轉(zhuǎn)目的地進行調(diào)整。因此,在完成這些轉(zhuǎn)換之前,要分析原始字節(jié)代碼60,找出任何跳轉(zhuǎn)字節(jié)代碼,記下它們的位置和當(dāng)前目的地。附錄D中作“B”標記的程序代碼片斷顯示了如何記錄這些跳轉(zhuǎn)指令。附錄D被本文引為參考。一旦記錄了跳轉(zhuǎn)指令,如果不是正在進行可選擇的字節(jié)代碼翻譯62,卡類文件轉(zhuǎn)換器26就可以進行第三遍64。否則,卡類文件轉(zhuǎn)換器就將專用字節(jié)代碼轉(zhuǎn)換成通用字節(jié)代碼。通常,翻譯出的字節(jié)代碼不在卡JVM16中被解釋,但是卻得到支持,因為能將該字節(jié)代碼轉(zhuǎn)換成能被卡JVM16解釋的等價字節(jié)代碼(見圖7)。字節(jié)代碼70可以替換為語義上等價的另一個不同字節(jié)代碼72。這通常導(dǎo)致將諸如ILOAD_0的專用短單字節(jié)代碼翻譯成更通用的形式。例如,ILOAD_0可以被帶參數(shù)0的字節(jié)代碼ILOAD代替。進行這種翻譯,目的是減少由卡JVM16翻譯的字節(jié)代碼的數(shù)量,由此減少對卡JVM16的復(fù)雜程度和代碼空間的要求。附錄D中作“C”標記的程序代碼片斷顯示了這種翻譯是如何完成的。注意,這種翻譯增加了結(jié)果字節(jié)代碼的大小,必須對任何受影響的跳轉(zhuǎn)指令進行重新計算。在第三遍64中,卡類文件轉(zhuǎn)換器重建常量引用,方法是剔除用于表示這些常量的串。圖8表示的例子中,引用通過JAVA類文件24a的常量池42中的索引發(fā)現(xiàn)的常量“18”的字節(jié)代碼LDC80可以被翻譯成BIPUSH字節(jié)代碼82。在這遍中,卡類文件轉(zhuǎn)換器26修改引用JAVA類文件常量池42的條目的所有字節(jié)代碼的操作數(shù)以反映它們在卡類文件常量池47中的新位置。圖9表示的例子中,一個字節(jié)代碼的參數(shù)INVOKESTATIC90引用JAVA類文件常量池42的某個條目,該條目被修改以反映該條目在卡類文件常量池47中的新位置。修改后的操作數(shù)94表示這種轉(zhuǎn)換。附錄D中作“D”標記的程序代碼片斷顯示了這種修改是如何完成的。一旦常量引用被再鏈接后,如果不是正在進行可選擇的字節(jié)代碼修改,卡類文件轉(zhuǎn)換器就繼續(xù)到第五個也是最后一遍67。否則,卡類文件轉(zhuǎn)換器就將原始字節(jié)代碼修改成由正使用的特定卡JVM16支持的某個不同的字節(jié)代碼集合。一種可能的修改是將原始字節(jié)代碼60重新編號變成卡JVM16的字節(jié)代碼(見圖10)。這種重新編號方式導(dǎo)致原始字節(jié)代碼60中的字節(jié)代碼100被修改成重新編號后的字節(jié)代碼102。由值21識別的字節(jié)代碼ILOAD可以被重新編號變成由值50來識別??梢杂眠@種修改來優(yōu)化卡JVM16中的類型測試(在現(xiàn)有技術(shù)中也稱為第三遍檢查)。附錄D中作“E”標記的程序代碼片斷顯示了這個實施例的一個實現(xiàn)。為了減少卡JVM16解釋字節(jié)代碼所需的程序空間可以進行這種修改。這種修改的實質(zhì)是將字節(jié)代碼重組成卡JVM16字節(jié)代碼,使得具有類似操作數(shù)和結(jié)果的字節(jié)代碼被組合在一起,卡JVM16的字節(jié)代碼之間沒有空隙。這就使得卡JVM16能在其執(zhí)行時高效地檢查卡JVM16字節(jié)代碼并確認類型。在有些實施例中,卡類文件轉(zhuǎn)換器將原始字節(jié)代碼60修改成旨在用于不同虛擬機體系結(jié)構(gòu)的不同字節(jié)代碼集合,如圖11中所示。旨在在字堆棧114上使用的JAVA字節(jié)代碼ILOAD112可以被要在字節(jié)堆棧118上使用的卡JVM16的字節(jié)代碼ILOAD_B116替換。字堆棧114中的一個單元要求分配4個字節(jié)的堆??臻g,而字堆棧118中的一個單元僅要求1個字節(jié)的堆??臻g。盡管這種選擇有助于提高執(zhí)行速度,其風(fēng)險是喪失原始字節(jié)代碼所具有的安全特性。因為前面的步驟63、64或66都可能會改變字節(jié)代碼60的大小,在67所以卡類文件轉(zhuǎn)換器26只好再鏈接任何已經(jīng)受影響的跳轉(zhuǎn)指令。由于跳轉(zhuǎn)指令已經(jīng)在卡類文件轉(zhuǎn)換器26的第一個步驟61被記錄,所以進行這種調(diào)整的方法是將跳轉(zhuǎn)目的地確定為適當(dāng)?shù)闹怠8戒汥中作“F”標記的程序代碼片斷顯示了這些跳轉(zhuǎn)是如何確定的??愇募D(zhuǎn)換器現(xiàn)在已經(jīng)修改與待命加載的原始字節(jié)代碼60等價的字節(jié)代碼68。從JAVA類文件24a到卡類文件27的轉(zhuǎn)換現(xiàn)在完成。參見圖5,如果在55還有類文件24等待處理,則對其余的每個類文件重復(fù)執(zhí)行前面的步驟51a、51b、51c、52、54。在56卡類文件轉(zhuǎn)換器26收集已處理過的類24的映射和修改后的字節(jié)代碼,在57將它們合并放置并生成卡類文件27。如果需要的話,卡類文件轉(zhuǎn)換器26就生成一個串到ID輸出映射文件32,它含有為翻譯期間在JAVA類文件24的常量池42中遇到的串所分配的所有新ID的清單。參見圖12,終端14內(nèi)的卡加載器28用標準ISO7816命令將卡類文件發(fā)送到集成電路卡中的加載與執(zhí)行控件120。加載與執(zhí)行控件120有一個卡操作系統(tǒng)122,卡操作系統(tǒng)提供必要的系統(tǒng)資源,包括支持卡文件系統(tǒng)124,卡文件系統(tǒng)可用于存儲幾個卡應(yīng)用程序126。有許多常規(guī)的卡加載器是用由卡操作系統(tǒng)122支持的低級語言編寫的。在優(yōu)選實施例中,引導(dǎo)程序加載器是用JAVA編寫的,集成電路卡10包括運行這個應(yīng)用程序的JAVA虛擬機。在本文引為參考的附錄E中表示了加載與執(zhí)行控件120的一個Java實現(xiàn)。加載與執(zhí)行控件120接收卡類文件26,生成在集成電路卡10的EEPROM中卡文件系統(tǒng)126中存儲的JAVA卡應(yīng)用程序126x。多個JAVA卡應(yīng)用程序126x、126y和126z都能以這種方式存儲在單一的卡中。加載與執(zhí)行控件120支持終端能用來選擇哪一個Java卡應(yīng)用程序立即或在下一次卡復(fù)位時運行的命令。參見圖13,當(dāng)接收到來自加載與執(zhí)行控件120的一個復(fù)位或執(zhí)行命令時,卡JAVA虛擬機(卡JVM)16開始在所選JAVA卡應(yīng)用程序126z中所選類的某個預(yù)定過程(例如主過程)執(zhí)行??↗VM16提供JAVA卡應(yīng)用程序126z訪問基礎(chǔ)卡操作系統(tǒng)122,操作系統(tǒng)用本機JAVA過程來提供諸如I/O、EEPROM支持、文件系統(tǒng)、存取控制以及其它系統(tǒng)功能。所用本機JAVA過程如本文引為參考的附錄F中所示。所選的JAVA卡應(yīng)用程序126z用通信器12a與終端14中的適當(dāng)應(yīng)用程序通信,以便建立通向終端14的通信通道。從通信器12a到終端14的數(shù)據(jù)經(jīng)過終端中的通信驅(qū)動程序132,通信驅(qū)動程序是專門為處理通信器12a所用的通訊協(xié)議而編寫的。數(shù)據(jù)然后傳送到集成電路卡驅(qū)動程序134,集成電路卡驅(qū)動程序是專門為訪問正被使用的特定集成電路卡10的能力而編寫的,它向終端應(yīng)用程序136提供高級軟件服務(wù)。在優(yōu)選實施例中,這個驅(qū)動程序是合適的PC/SC智能卡服務(wù)提供商(SSP-SmartcardServiceProvider)軟件。數(shù)據(jù)然后傳送到終端應(yīng)用程序136,后者必須處理由正在運行的特定卡應(yīng)用程序126z所提供的能力。命令和響應(yīng)就這樣在終端應(yīng)用程序136和選定的卡應(yīng)用程序126z之間來回傳送。終端應(yīng)用程序與用戶交互作用,接收來自用戶的命令—其中有些命令被傳送到選定的JAVA卡應(yīng)用程序126z,接收來自選定的JAVA卡應(yīng)用程序126z的響應(yīng)—這些響應(yīng)經(jīng)處理后被傳送回用戶。參見圖14,卡JVM16是一個解釋卡應(yīng)用程序126x的解釋器。微控制器中影響卡JVM16的存儲器資源是卡ROM140、卡RAM141和卡EEPROM142??≧OM140用于存儲卡JVM16和卡操作系統(tǒng)122。卡ROM140也可用于存儲固定的卡應(yīng)用程序140a和類庫140b??杉虞d的應(yīng)用程序141a、141b和庫141c也可以存儲在卡RAM141中??↗VM16解釋卡應(yīng)用程序141a、141b或140a??↗VM16用卡RAM來存儲VM堆棧144a和系統(tǒng)狀態(tài)變量144b??↗VM16通過VM堆棧144a來跟蹤所進行的操作。由卡JVM16創(chuàng)建的對象或者存儲在RAM堆144c中,或者存儲在EEPROM堆146a中,或者存儲在文件系統(tǒng)147中。所有由卡JVM16操縱的堆都可以作為RAM堆144c存儲在卡RAM141中,也可以作為EEPROM堆分布到卡EEPROM142。卡RAM141也用于記錄用微控制器的本機代碼編寫的例程所用的系統(tǒng)堆棧148的狀態(tài)??↗VM16用卡EEPROM142來把應(yīng)用程序數(shù)據(jù)存儲在EEPROM堆146a或文件系統(tǒng)147中。存儲在文件中的應(yīng)用程序數(shù)據(jù)可以通過到卡操作系統(tǒng)122的接口來操縱。這種接口由卡ROM140中存儲的類庫140b提供,由卡EEPROM142中存儲的可加載類庫141c提供。附錄F中描述了一個這樣的接口??ㄖ械膽?yīng)用程序和數(shù)據(jù)被防火墻機構(gòu)149隔離。為了適應(yīng)微控制器上所能得到的有限資源,卡JVM16執(zhí)行JAVA程序設(shè)計語言的一個嚴格的子集。結(jié)果,JAVA應(yīng)用程序20編譯成一個含有JAVA字節(jié)代碼的一個嚴格子集的類文件。這就使應(yīng)用程序設(shè)計者能以這個JAVA的嚴格子集編寫程序并仍然保持與現(xiàn)有JAVA虛擬機的兼容。由卡JVM16解釋的JAVA字節(jié)代碼的語義在前面所述的《JAVA虛擬機規(guī)范》中有描述。附錄C中有由卡JVM16解釋的字節(jié)代碼子集。卡類文件轉(zhuǎn)換器26檢查JAVA應(yīng)用程序20以確保只使用這個子集中可用的特征,并將應(yīng)用程序轉(zhuǎn)換成能被卡JVM16理解和解釋的形式。在其它實施例中,卡JVM16被設(shè)計成能解釋字節(jié)代碼116的一個不同集合或增廣集合。盡管不同的字節(jié)代碼集合可能導(dǎo)致某些性能上的提高,從原始JAVA字節(jié)代碼具有的安全性或者從與主流JAVA開發(fā)工具的兼容性角度來說,偏離嚴格的JAVA子集可能并不可取。所有卡JVM16應(yīng)用程序126都有一個定義好的入口點,入口點由某個類和該類中的某個過程指示。這種入口點在串到ID輸入映射30中映射,并由卡類文件轉(zhuǎn)換器26分配。JAVA應(yīng)用程序20中的類、過程和域是由卡類文件轉(zhuǎn)換器26分配ID的。例如,對應(yīng)主應(yīng)用程序類的ID可被定義為F001,對應(yīng)其主過程諸如“main()V”的ID可被定義為F002。圖15中的流圖描述了卡JVM的總體執(zhí)行體系。卡JVM16的執(zhí)行從執(zhí)行控件120開始,執(zhí)行控件選擇一個要執(zhí)行的卡應(yīng)用程序126z。它接著就尋找并分配卡應(yīng)用程序中的一個入口點152(某過程)供卡JVM16去解釋??↗VM16解釋該過程153。如果解釋進行得成功154,卡JVM16就報告成功155,將控制返還給執(zhí)行控件120。如果在進行解釋的過程中153,卡JVM16遇到未處理的錯誤或異常(通常是資源限制或安全侵犯),則卡JVM16就停止156并將適當(dāng)?shù)腻e誤報告給終端14??↗VM16的核心部分是一個處理字節(jié)代碼的執(zhí)行的子例程。圖16中的流圖描述了這個子例程。該流圖假定一個過程160,該子例程執(zhí)行該過程中的字節(jié)代碼。子例程的開始是準備該過程的參數(shù)161。這涉及到設(shè)置VM堆棧144a指針、VM堆棧144a幀限制,以及將程序計數(shù)器設(shè)置到過程的第一個字節(jié)代碼。下一步檢查過程各標志162。如果過程被標志為本地的,則過程實際上是一個對本機過程代碼(用微控制器的本地處理器代碼編寫的子例程)的調(diào)用。在這種情況下,卡JVM16為有效調(diào)用進行準備163并返回到本機代碼例程。參數(shù)可以在VM堆棧144a上或通過系統(tǒng)堆棧148傳送給本機過程。在進行適當(dāng)?shù)陌踩珯z查后本機過程子例程被調(diào)用。返回時,本機過程子例程的結(jié)果(如果有結(jié)果的話)被置于VM堆棧144a上,以便能被下一個要執(zhí)行的字節(jié)代碼來存取。然后就進入了卡JVM16的調(diào)度循環(huán)164。字節(jié)代碼調(diào)度循環(huán)負責(zé)每個字節(jié)代碼的準備、執(zhí)行和退役。循環(huán)結(jié)束的條件是,循環(huán)結(jié)束了對過程160中字節(jié)代碼的解釋,或者卡JVM16遇到資源限制或安全侵犯。如果上一個字節(jié)代碼導(dǎo)致要轉(zhuǎn)移165,則卡JVM16準備轉(zhuǎn)移165a。提取下一個字節(jié)代碼165b。為了保持以低代價處理每個字節(jié)代碼,要盡可能提取并存儲常用的單元,諸如字節(jié)代碼參數(shù)、長度、類型。為了提供程序設(shè)計語言的安全模型具有的安全性,要檢驗類文件中字節(jié)代碼,判斷是否符合該模型。這種檢查在現(xiàn)有技術(shù)中通常是由一個稱為字節(jié)代碼檢驗器的程序執(zhí)行的,按照《JAVA虛擬機規(guī)范》,字節(jié)代碼檢驗器進行四遍操作。為了提供由字節(jié)代碼檢驗器保障的運行時的安全性,卡JVM16必須進行與檢驗器的第三、第四遍相關(guān)的檢查。這種檢查可以被卡JVM16省略,條件是由卡JVM16解釋的字節(jié)代碼60的安全性能得到保證(這幾乎不可能做到)。至少,只要對象引用不可能是假造的、VM堆棧144a和本地變量界限得到遵守,代碼安全性就可能得到保持。這就要求針對正在執(zhí)行的字節(jié)代碼檢查VM堆棧144a的狀態(tài)。為了實施程序設(shè)計語言的安全模型,要創(chuàng)建一個256字節(jié)的表,如本文引為參考的附錄G所示。該表由字節(jié)代碼的編號標引。該表含有與索引字節(jié)代碼關(guān)聯(lián)的類型和長度數(shù)據(jù)。其編碼方式是前5位代表類型,后3位代表長度。字節(jié)代碼的類型和長度是直接從該表由字節(jié)代碼編號索引的。這種類型和長度然后被用于進行由本文引為參考的附錄H所示的檢查。附錄H中,這種檢查始于從本文引為參考的附錄G的表中解碼長度和類型。長度用于遞增程序計數(shù)器。類型首先用于執(zhí)行前的檢查,以保證在VM堆棧144a上的數(shù)據(jù)類型對于要執(zhí)行的字節(jié)代碼來說是正確的。用256個字節(jié)的ROM存儲該表,使得原始Java字節(jié)代碼能在卡JVM16中運行并使對要加載到卡的JAVA類文件所需的改變最少。其它JAVA字節(jié)代碼可以容易地被支持,因為更新適當(dāng)?shù)谋項l目是相對容易的事情。在其它實施例中,如圖10所示,過程中JAVA字節(jié)代碼是這樣重新編號的,即要使得存儲在附錄H的表中的字節(jié)代碼類型和長度數(shù)據(jù)在重定序中是隱含的。附錄H被本文引為參考。于是,必須對VM堆棧144a的狀態(tài)和正在處理的字節(jié)代碼進行的檢查并不涉及對表的查找。通過執(zhí)行本文引為參考的附錄I中所示的幾個簡單比較就能進行檢查。當(dāng)ROM空間非常寶貴時,最好采用這個實施例,因為它去除了一個256字節(jié)的表。然而要向被支持字節(jié)代碼的集合添加新字節(jié)代碼,必須仔細地設(shè)計周到,因為新字節(jié)代碼必須適合被支持字節(jié)代碼的隱含編號方案。在另一個實施例中,卡JVM16為了卡JVM16的執(zhí)行速度而選擇不進行任何安全檢查。這在圖18的流圖中表示。圖18的流圖與去掉安全檢查后的圖16的流圖相同。從安全的觀點來說,這種選擇是不可取的,除非能保證字節(jié)代碼是安全的??↗VM16也能實施其它安全檢查。如果字節(jié)代碼可以引用局部變量,卡JVM16就檢查這種引用是否有效,如果無效,就發(fā)出出錯信號。如果引用有效,卡JVM16就將該局部變量的類型存儲起來用于將來的檢查。要檢查VM堆棧144a指針,看其是否仍然處于有效區(qū)間。如果不在有效區(qū)間,就發(fā)出異常信號。要檢查字節(jié)代碼編號,如果不受支持,就發(fā)出異常信號。最后,字節(jié)代碼本身被調(diào)度165d。由卡JVM16翻譯的字節(jié)代碼清單列舉在附錄C中。前述的《JAVA虛擬機規(guī)范》中有針對字節(jié)代碼調(diào)度之前和之后VM堆棧144a的狀態(tài)對字節(jié)代碼的語義的描述。注意,有些字節(jié)代碼(字節(jié)代碼INVOKESTATIC、INVOKESPECIAL、INVOKENONVIRTUAL和INVOKEVIRTUAL)可能導(dǎo)致重新進入卡JVM16,要求在子例程161的入口處開始處理。圖17表示字節(jié)代碼執(zhí)行例程的流圖。該例程被賦予一個要執(zhí)行的字節(jié)代碼171。卡JVM16執(zhí)行該字節(jié)代碼所要求的指令172。如果在執(zhí)行的過程中,卡JVM16遇到某資源限制173,它就返回一個錯誤156。這個錯誤被卡JVM16返回給終端16。如果字節(jié)代碼執(zhí)行成功,它就返回一個成功信號175。執(zhí)行之后,結(jié)果的類型被用于正確地設(shè)置VM堆棧144a(165e),適當(dāng)?shù)卦赩M堆棧144a上設(shè)置數(shù)據(jù)類型標志。上一次從字節(jié)代碼信息表收集(165b)的字節(jié)代碼數(shù)據(jù)被用于按照剛剛執(zhí)行的字節(jié)代碼來設(shè)置VM堆棧144a的狀態(tài)。在其它實施例中,針對被執(zhí)行的字節(jié)代碼來設(shè)置VM堆棧144a的輸出狀態(tài)在字節(jié)代碼是重新編號過的情況下被簡化。這種簡化在本文引為參考的附錄I中表示。在另一個實施例中,卡JVM16為了卡JVM16的執(zhí)行速度,可能省略對VM堆棧144a的輸出狀態(tài)的設(shè)置。從安全的觀點來說,這種選擇并不可取—除非能保證字節(jié)代碼是安全的。在字節(jié)代碼已經(jīng)執(zhí)行后,字節(jié)代碼被退役(165f)。這涉及到使參數(shù)從VM堆棧144a出棧。一旦字節(jié)代碼的處理完成,循環(huán)164就對過程的下一個字節(jié)代碼重復(fù)。一旦調(diào)度循環(huán)164終止,VM堆棧144a就被清空(166)。這就防止有任何對象引用滲漏到其它卡JVM16調(diào)用,破壞卡JVM16的安全。字節(jié)代碼調(diào)度循環(huán)164的停止167,標志卡JVM16已經(jīng)完成了對所請求過程的執(zhí)行。為了將集成電路卡10中的數(shù)據(jù)和應(yīng)用程序互相隔離,集成電路卡10要依靠由卡JVM16提供的防火墻機構(gòu)149。因為卡JVM實施標準的第3和第4遍的檢驗器檢查,它能檢測到某應(yīng)用程序引用另一個應(yīng)用程序所用數(shù)據(jù)或代碼空間的任何企圖并發(fā)出安全錯誤信號(156)。例如,常規(guī)低級應(yīng)用程序能將非引用數(shù)據(jù)類型變造成引用,由此使得能訪問未經(jīng)授權(quán)的存儲空間,侵犯安全。如果采用本發(fā)明,則要是卡應(yīng)用程序126z企圖用一個非引用數(shù)據(jù)類型作為引用的話,就會觸發(fā)一個安全侵犯錯誤(156)。在常規(guī)JAVA中,這種受保護的應(yīng)用程序環(huán)境被稱為沙箱應(yīng)用程序-解釋環(huán)境。然而,這些防火墻設(shè)施并不是獨立工作的。實際上,這些設(shè)施是與下表所示的常規(guī)存取控制列表和加密機構(gòu)重疊并互相加強的這些設(shè)施結(jié)合在一起,隔離集成電路卡10上的數(shù)據(jù)和應(yīng)用程序,保證每個卡應(yīng)用程序126只能訪問集成電路卡10的授權(quán)資源。參見圖19,當(dāng)卡應(yīng)用程序126執(zhí)行時,卡應(yīng)用程序126x、126y、126z能被賦予特別的特權(quán)。這些特權(quán)例如確定,卡應(yīng)用程序126能訪問哪些數(shù)據(jù)文件,卡應(yīng)用程序126在文件系統(tǒng)147上能執(zhí)行哪些操作。授予卡應(yīng)用程序126的特權(quán)一般是在特定的卡應(yīng)用程序126z被用戶通常從終端14啟動時設(shè)置的。集成電路卡10用加密驗證過程來將某身份190(例如身份190a、190b和190c)并因此將一組特權(quán)關(guān)聯(lián)到卡應(yīng)用程序126的執(zhí)行。特定身份190c與卡應(yīng)用程序126z的關(guān)聯(lián)是在卡應(yīng)用程序126z開始執(zhí)行時作出的,因此而創(chuàng)建一個特定的運行應(yīng)用程序200,如圖20所示。身份190是一種獨特可識別的文字,與某身份標志可靠關(guān)聯(lián)。身份標志(例如個人身份證號(PIN)或RSA私人密鑰)是一種密鑰。參見圖20,為了運行特定的卡應(yīng)用程序126z,必須驗證卡應(yīng)用程序126z的身份190c。身份190c是通過展示知道與身份190c關(guān)聯(lián)的身份標志而驗證的。因此,為了運行卡應(yīng)用程序126z,代理(例如持卡者或希望運行該應(yīng)用程序的另一個應(yīng)用程序)必須顯示其擁有或知道該應(yīng)用程序的定義身份的密鑰。展示擁有密鑰的一種方式是簡單地展示該鑰本身。PIN驗證就是這種驗證形式的一個例子。另一種不展示密鑰本身就能顯示擁有密鑰的方式是,展示有能力以該密鑰來加密或解密普通文字。因此,集成電路卡10上特定的運行應(yīng)用程序200包括一個卡應(yīng)用程序126z和一個驗證過的身份190c。沒有這兩個單元的就位,任何卡應(yīng)用程序126都不能運行。卡應(yīng)用程序126z定義要執(zhí)行的數(shù)據(jù)處理操作,驗證過的身份190c確定這些操作可以在什么計算對象上執(zhí)行。例如,某特定應(yīng)用程序126z只能訪問文件系統(tǒng)147中與該特定身份190c關(guān)聯(lián)的該身份C的文件202,該特定卡應(yīng)用程序126z不能訪問與該特定身份190c以外的身份關(guān)聯(lián)的其它文件204。集成電路卡10可以采取其它步驟來保證應(yīng)用程序和數(shù)據(jù)的隔離。集成電路卡10具有三個軟件部件集驗證過的身份的存取控制列表、基于JAVA的虛擬機、分別保護數(shù)據(jù)文件、應(yīng)用程序執(zhí)行和通信通道的一次性會話密鑰。這些部件集聯(lián)合起來用于一個實施例時,能為一個實施例提供應(yīng)用程序防火墻149。下面討論每個軟件部件集,然后展示這三個集是如何共同工作來保證在集成電路卡10上隔離應(yīng)用程序和數(shù)據(jù)的。集成電路卡10上每一個受保護的—即對其的訪問要受控制的—計算對象(例如數(shù)據(jù)文件或通信通道)都有一個關(guān)聯(lián)的存取控制列表(ACL)。(特定計算對象的)ACL上的條目的數(shù)據(jù)格式稱為e-tupletype(類型)identity(身份)permissions(允許)type域指示后面的(identity域中的)身份—例如某用戶(例如“JohnSmith”)或某小組—的類型。permissions域指示能由該身份對計算對象進行的操作(例如讀、追加數(shù)據(jù)和更新)的一個列表。例如,假定某數(shù)據(jù)文件有ACL條目USERAcmeAirlinesRAU,則任何身份是“AcmeAirlines”的應(yīng)用程序都能對該數(shù)據(jù)文件進行讀(“R”)、追加數(shù)據(jù)(“A”)和更新(“U”)。此外,該ACL可以選擇性地用于允許創(chuàng)建和刪除數(shù)據(jù)文件。此外,該ACL可以選擇性地用于允許執(zhí)行一個應(yīng)用程序。每當(dāng)某計算對象被運行應(yīng)用程序200訪問時,訪問都被卡JVM16截獲并傳送到卡操作系統(tǒng)122,后者判斷是否有ACL與該對象關(guān)聯(lián)。如果有關(guān)聯(lián)的ACL,則與運行應(yīng)用程序200關(guān)聯(lián)的身份190c在該ACL上被匹配。如果該身份不存在,或者不允許該身份進行正在請求的類型的訪問,則訪問被拒絕。否則,就允許進行訪問。參見圖13,為了防止由于集成電路卡10與終端14之間只有單一的數(shù)據(jù)通路而可能產(chǎn)生的問題,要完成通信通道的隔離,方法是在身份驗證進程中增加在卡應(yīng)用程序126z與終端應(yīng)用程序136之間交換一次性會話密鑰209。密鑰209然后被用于加密隨后在驗證終端應(yīng)用程序136與驗證過的卡應(yīng)用程序126z之間的通信。有了一次性會話密鑰209后,無賴終端應(yīng)用程序既不能“收聽”在終端14與集成電路卡10之間的驗證過的通信,也不能“電子欺騙”卡應(yīng)用程序去代表無賴終端應(yīng)用程序進行沒有驗證的操作???終端通信的加密解密,既可以由卡操作系統(tǒng)122處理,也可以有卡應(yīng)用程序本身126z處理。在前一種情況下,與終端14的通信是對應(yīng)用程序透明地進行加密的,信息通信解密后到達應(yīng)用程序的數(shù)據(jù)空間。在后一種情況下,卡應(yīng)用程序126z選擇進行加密和解密來提供一個額外的安全層,這是因為應(yīng)用程序能在數(shù)據(jù)一旦創(chuàng)建時就加密數(shù)據(jù),在數(shù)據(jù)要使用時就解密數(shù)據(jù)。否則,數(shù)據(jù)就用會話密鑰209保持在加密狀態(tài)。所以,應(yīng)用程序防火墻包括三個互相加強的軟件集。數(shù)據(jù)文件受到驗證過的身份存取控制列表的保護。應(yīng)用程序執(zhí)行空間受卡JVM16的保護。通信通道用一次性會話密鑰209保護。在其它實施例中,上述用于微控制器(諸如處理器12)的技術(shù)可以控制集成電路卡以外的設(shè)備(例如汽車發(fā)動機的一部分)。在這些應(yīng)用中,微控制器提供一個小平臺(即一個中央處理單元和一個存儲器,二者都位于一個半導(dǎo)體襯底上)來存儲和執(zhí)行高級程序設(shè)計語言。多數(shù)采用微控制器的現(xiàn)有設(shè)備和新設(shè)計都能用本發(fā)明來提供用高級語言為微控制器編程的能力,特別是包括了本發(fā)明對這類設(shè)備的應(yīng)用。應(yīng)用程序這個用語包括任何諸如JAVA應(yīng)用程序、JAVA小應(yīng)用程序、JAVAaglets、JAVA小服務(wù)程序(servlets)、JAVA小通信程序(commlets)、JAVA部件程序,以及其它能產(chǎn)生如下所述的類文件的非JAVA程序。類文件可以具有一個不是JAVA程序文件的源。有一些非JAVA的程序設(shè)計語言也有用于從各自的源文件生成類文件的編譯程序或匯編程序。例如,程序設(shè)計語言Eiffel可用于用PirminKalberer的“J-Eiffel”來生成類文件?!癑-Eiffel”是具有JVM字節(jié)代碼生成功能的Eiffel編譯程序(web網(wǎng)址http∥www.spin.ch/~kalberer/jive/index.htm)。在以下的(本文引為參考的)參考文獻中描述了一種將Ada95到JAVA字節(jié)代碼的翻譯器《用Ada95編寫因特網(wǎng)程序》(原文標題為“ProgrammingtheInternetinAda95”,作者taft,S.Tucker,1996年發(fā)表于’96歐洲Ada學(xué)會會刊)。Jasmin是一種JAVA字節(jié)代碼匯編程序,能用于生成類文件,方法如以下的(本文引為參考的)參考文獻中所描述《JAVA虛擬機》(原文標題為“JAVAVirtualMachine”作者Meyer、Jon和TroyDowning,1997年O’Reilly出版)。不管類文件的源是什么,上述描述可應(yīng)用于JAVA以外的語言以生成要被解釋的代碼。圖21表示一種集成電路卡或智能卡,它包括的微控制器210安裝在塑料卡212上。塑料卡212具有與典型的信用卡大致相同的形式因素。通信器12a能用接觸焊點(contactpad)214來建立通信通道,通信器12a或者也能采用無線通信系統(tǒng)。在其它實施例中,微控制器210被安裝在移動式或固定的電話220中,實際上向電話添加了智能卡的功能,如圖22所示。在這些實施例中,微控制器210被安裝在能插入電話220或從電話中摘除的模塊(諸如用戶身份模塊(SIM-SubscribeIdentityModule))中。在其它實施例中,微控制器210被加到鑰匙環(huán)230上,如圖23所示。這可用于保護安裝有識別與鑰匙環(huán)230上微控制器210相關(guān)聯(lián)的身份的裝備的汽車的出入。諸如手表或戒指240等貴重物品上也能以符合人機工程學(xué)的方式安裝微控制器210,如圖24所示。這種實施例通常用無線通信系統(tǒng)來建立通信通道,是一種對用戶妨礙最小的存取控制的實現(xiàn)方式。圖25表示一個在汽車254的電子子系統(tǒng)252中安裝的微控制器210。在這個實施例中,微控制器被用于各種用途,諸如控制進出汽車(例如檢查身份或駕車人是否清醒后才啟動汽車的點火系統(tǒng))、通過無線通信來付路橋費、或者與全球定位系統(tǒng)(GPS)交互作用來追蹤汽車的位置,如此等等。本文描述了本發(fā)明的特定實施例,但本領(lǐng)域的熟練人員通過閱讀本說明書顯然知道存在各種修改和替代方案。這種修改和替代并不超出本發(fā)明的范圍,被包含在后附的諸項權(quán)利要求內(nèi)。附錄A優(yōu)選實施例的卡類文件格式介紹該卡類文件是原始類文件的一種壓縮形式??愇募缓薪忉審脑碱愇募淼腏AVA程序所需的語文數(shù)據(jù)。原始類文件中的間接引用被替換為直接引用,結(jié)果產(chǎn)生一種緊湊的表示??愇募母袷交谙铝性瓌t貼近標準類文件格式??愇募袷綉?yīng)當(dāng)盡可能地接近標準類文件格式。類文件中的JAVA字節(jié)代碼保持不變。不改變字節(jié)代碼,保證了對它們的結(jié)構(gòu)和靜態(tài)約束依然可以驗證是完好無缺的。容易實現(xiàn)??愇募袷綉?yīng)當(dāng)足夠簡單,以吸引JAVA虛擬機的實現(xiàn)者。它必須允許不同形式但行為相當(dāng)?shù)膶崿F(xiàn)??尚行???愇募袷奖仨毦o湊,以便能與智能卡技術(shù)結(jié)合。必須既符合當(dāng)今技術(shù)條件,又不失對明日創(chuàng)新的遠見。本文件基于題為《JAVATM虛擬機規(guī)范》[1]一書中的第4章“類文件格式”,此后稱該書為紅皮書。由于本文件基于紅皮書中說明的標準類文件格式,我們只展示不同的數(shù)據(jù)。任何澄清都要以紅皮書為最終權(quán)威依據(jù)。與標準類文件格式的主要不同之處是常量池被優(yōu)化成只含有16位的標識符,在可能的地方,間接引用被替換成直接引用。原始類文件中的屬性被剔除或重新分組。JAVA卡類文件格式本節(jié)描述JAVA卡類文件格式。每個卡類文件含有一個或許多JAVA類型,其中的類型可以是類或界面??愇募?位字節(jié)的流組成。所有16位、32位和64位數(shù)都是通過分別讀取兩個、四個和八個連續(xù)的8位字節(jié)而構(gòu)造的。多字節(jié)的數(shù)據(jù)項總是以大結(jié)尾順序(big-endianorder)存儲的,其中高位字節(jié)位于前面。在JAVA語言中,這種格式受界面java.io.DataInput和java.io.DataOutput以及諸如java.io.DataInputStream和java.io.DataOutputStream的類的支持。我們定義并使用相同的數(shù)據(jù)類型集表示Java類文件數(shù)據(jù)類型u1、u2和u4分別代表無符號的1字節(jié)、2字節(jié)或4字節(jié)數(shù)。在JAVA語言中,這些類型可以被諸如界面java.io.DataInput的readUnsignedByte、readUnsignedShort和readInt的過程讀取。卡類文件格式采用用與C語言相象的結(jié)構(gòu)記號編寫的偽結(jié)構(gòu)來表示。為了避免與JAVA卡虛擬機類和類實例的域混淆,描述卡類文件格式的結(jié)構(gòu)的內(nèi)容被稱為項。與C結(jié)構(gòu)的域不同,連續(xù)的項被順序存儲在卡類文件中,沒有填充或?qū)R。由可變長項組成的可變長表在幾個類文件結(jié)構(gòu)中被使用。盡管將用類似C的數(shù)組語法來引用表項,但事實上表是可變長度結(jié)構(gòu)的流,這就意味著不可能直接將表索引翻譯成表內(nèi)字節(jié)位移地址。當(dāng)我們稱某數(shù)據(jù)為數(shù)組時,它實際就是一個數(shù)組。為了區(qū)別卡類文件結(jié)構(gòu)與標準類文件結(jié)構(gòu),我們增加了大寫表示法。例如我們將原始類文件中的field_info重新命名為卡類文件中的FieldInfo??愇募愇募幸粋€單一的CardClassFile結(jié)構(gòu)CardClassFile{u1major_version;u1minor_version;u2name_index;u2const_size;u2max_class;Cpinfoconstant_pool[const_size];ClassInfoclass[max_class];}CardClassFile結(jié)構(gòu)中的項如下minor_version,major_versionminor_version和major_version項的值是產(chǎn)生該卡類文件的卡外JAVA卡虛擬機的低和高版本號。JAVA卡虛擬機的實現(xiàn)一般支持具有給定高版本號和0到某特定minor_version的低版本號的卡類文件。只有Java卡論壇(JavaCardForum)才可以定義卡類文件版本號的意思。name_indexname_index的值必須代表一個有效的Java類名。由name_index代表的Java類名必須與要在卡中運行的主應(yīng)用程序?qū)?yīng)的Java類名嚴格相同。卡類文件含有若干類或界面,是它們構(gòu)成了在卡中運行的應(yīng)用程序。由于Java允許每個類都含有一個主過程,必須有方法來區(qū)別含有與卡應(yīng)用程序?qū)?yīng)的主過程的類文件。const_sizeconst_size的值給出在卡類文件常量池中條目的數(shù)量。constant_pool下標如果大于等于0并且小于const_size時才被視為有效。max_class該值指的是卡類文件中出現(xiàn)的類的數(shù)目。由于Java卡中的名字歸結(jié)和鏈接都是由卡外Java虛擬機完成的,所以應(yīng)用程序所需的所有類文件或類都被一起放置在一個卡類文件中。constant_pool[]constant_pool是一個可變長度結(jié)構(gòu)的表(),代表各種串常量、類名、域名和其它在CardClassFile結(jié)構(gòu)和其子結(jié)構(gòu)內(nèi)被引用的常量??愇募械牡谝粋€條目是constant_pool。下標在0到const_size的constant_pool表的每個條目都是一個可變長度的結(jié)構(gòu)()。class[]該類是構(gòu)成加載到卡上的應(yīng)用程序的max_class個類的一個表。constant_pool所有constant_pool表條目都具有以下的通用格式CpInfo{u1tag;u1info[];}constant_pool表中的每項都必須以標志cp_info條目的種類的1字節(jié)的標簽開始。該info數(shù)組的內(nèi)容隨標簽的值而變化。有效標簽以及它們的值與紅皮書中規(guī)定的一樣。每個標簽字節(jié)后必須跟隨兩個或更多給出有關(guān)特定常量的數(shù)據(jù)的字節(jié)。額外數(shù)據(jù)的格式隨標簽值而變。當(dāng)前要包括的標簽只有CONSTANT_Class、CONSTANT_FiledRef、CONSTANT_MethodRef和CONSTANT_InterfaceRef。也可以增加對其它標簽的支持,因為它們包含在規(guī)范中。CONSTANT_ClassCONSTANT_Class_info結(jié)構(gòu)用于代表一個類或一個界面CONSTANT_Classinfo{u1tag;u2name_index;}CONSTANT_Class_info結(jié)構(gòu)的諸項如下所述tagtag項具有值CONSTANT_Class(7)。name_indexname_index的值必須代表一個有效的Java類名。由name_index代表的Java類名必須是與由原始類文件的constant_pool中對應(yīng)的CONSTANT_Class條目所描述的完全相同的Java類名。CONSTANT_Fieldref、CONSTANT_Methodref和CONSTANT_InterfaceMethodref域、過程和界面過程由類似結(jié)構(gòu)代表CONSTANT_FieldrefInfo{u1tag;u2class_index;u2name_sig_index;}CONSTANT_MethodrefInfo{u1tag;u2class_index;u2name_sig_index;}CONSTANT_InterfaceMethodrefInfo{u1tag;u2class_index;u2name_sig_index;}這些結(jié)構(gòu)的諸項如下所述tagCONSTANT_FieldrefInfo結(jié)構(gòu)的tag項具有值CONSTANT_Fieldref(9)。CONSTANT_MethodrefInfo結(jié)構(gòu)的tag項具有值CONSTANT_Methodref(10)。CONSTANT_InterfaceMethodrefInfo結(jié)構(gòu)的tag項具有值CONSTANT_InterfaceMethodref(11)。CLass_indexclass_index項的值必須代表一個有效的Java類或界面名。由class_index代表的名必須是與由原始類文件的constant_pool中對應(yīng)的CONSTANT_Class_info條目所描述的完全相同的名。name_sig_indexname_sig_index的值必須代表一個有效的Java名和類型。由name_sig_index代表的名和類型必須是與由原始類文件的constant_pool結(jié)構(gòu)中的CONSTANT_NameAndType_info條目所描述的完全相同的名和類型。Class每個Class都由一個定長的ClassInfo結(jié)構(gòu)來描述。這種結(jié)構(gòu)的格式是ClassInfo{u2name_index;u1max_field;u1max_sfield;u1max_method;u1max_interface;u2superclass;u2access_flagsFieldInfofield[max_field+max_sfield];InterfaceInfointerface[max_interface];MethodInfomethod[max_method];}ClassInfo結(jié)構(gòu)的諸項如下所述name_indexname_index項的值必須代表一個有效的Java類名。由name_index代表的Java類名必須是與由原始類文件的對應(yīng)ClassFile結(jié)構(gòu)所描述的完全相同的Java類名。max_fieldmax_field項的值給出域表中代表由該類或界面類型說明的實例變量的FieldInfo()結(jié)構(gòu)的數(shù)目。這個值指的是卡類文件中非靜態(tài)域的數(shù)目。如果類代表一個結(jié)構(gòu)則max_field的值為0。max_sfieldmax_sfield項的值給出域表中代表由該類或界面類型說明的類變量的FieldInfo結(jié)構(gòu)的數(shù)目。這個值指的是卡類文件中靜態(tài)域的數(shù)目。max_methodmax_method項的值給出過程表中MethodInfo()結(jié)構(gòu)的數(shù)目。max_interfacemax_interface項的值給出該類或界面類型的直接超界面的數(shù)目。superclass對于一個類來說,superclass項的值必須代表一個有效的Java類名。由superclass代表的Java類名必須是與由原始類文件的對應(yīng)ClassFile結(jié)構(gòu)所描述的完全相同的Java類名。無論該superclass還是其任何超類都不以是一個最后類。如果superclass的值是0,則該類必須代表類java.lang.Object,這是唯一沒有超類的類或界面。對于界面來說,superclass的值總是代表Java類java.lang.Object。access_flagsaccess_flags項的值是用在類和界面說明中的修改符的一個屏蔽。這些access_flags修改符和它們的值是與原始類文件的對應(yīng)ClassFile結(jié)構(gòu)中的完全相同的access_flags修改符。field[]field表中的每個值都必須是一個定長的FieldInfo()結(jié)構(gòu),能全面描述類或界面類型中的一個域。field表僅包括那些由該類或界面說明過的域。它不包括代表從超類或超界面繼承的域的項。interface[]interface數(shù)組中每個值都必須代表一個有效的界面名。由每個條目代表的界面名必須是與由原始類文件的對應(yīng)界面數(shù)組所描述的完全相同的界面名。method[]method表中的每個值都必須是一個可變長的MethodInfo()結(jié)構(gòu),能全面描述類或界面中某過程的Java虛擬機代碼。MethodInfo結(jié)構(gòu)代表由該類或界面類型所說明的所有過程,包括實例過程和-對于類來說-類(靜態(tài))過程。該method表只包括由該類所顯式說明的那些過程。界面只有一個過程<clinit>,即界面初始化過程。說method表不包括表示從超類或超界面所繼承的過程的那些項。Fields每個field都由一個定長的field_info結(jié)構(gòu)來描述。這種結(jié)構(gòu)的格式是FieldInfo{u2name_index;u2signature_index;u2access_flags;}FieldInfo結(jié)構(gòu)的諸項如下所述name_indexname_index項的值必須代表一個有效的Java域名。由name_index代表的Java域名必須是與由原始類文件的對應(yīng)field_info結(jié)構(gòu)所描述的完全相同的Java域名。signature_indexsignature_index項的值必須代表一個有效的Java域描述符。由name_index代表的Java域描述符必須是與由原始類文件的對應(yīng)field_info結(jié)構(gòu)所描述的完全相同的Java域描述符。access_flagsaccess_flags項的值是用于描述對域的訪問許可和域的特性的修改符的一個屏蔽。這些access_flags修改符和它們的值是與原始類文件的對應(yīng)field_info結(jié)構(gòu)中的完全相同的access_flags修改符。methods每個method(過程)都由一個變長的MethodInfo結(jié)構(gòu)來描述。MethodInfo結(jié)構(gòu)是一個變長的結(jié)構(gòu),含有用于一個單一Java過程、實例初始化過程、或類或界面初始化過程的Java虛擬機指令和輔助信息。該結(jié)構(gòu)具有以下的格式MethodInfo{u2name_index;u2signature_index;u1max_local;u1max_arg;u1max_stack;ulaccess_flags;u2code_lengthu2exception_length;u1code[code_length];{u2start_pc;u2end_pc;u2handler_pc;u2catch_type;}einfo[exception_length];}MethodInfo結(jié)構(gòu)的諸項如下所述name_indexname_index項的值必須要么代表一個特殊內(nèi)部過程名-<init>或者<clinit>,要么代表一個有效的Java過程名。由name_index代表的Java過程名必須是與由原始類文件的對應(yīng)method_info結(jié)構(gòu)所描述的完全相同的Java過程名。signature_indexsignature_index項的值必須代表一個有效的Java過程描述符。由signature_index代表的Java過程描述符必須是與由原始類文件的對應(yīng)method_info結(jié)構(gòu)所描述的完全相同的Java過程描述符。max_localmax_local項的值給出該過程所用的局部變量的數(shù)目,不包括調(diào)用時傳遞給過程的參數(shù)。第一個局部變量的變址值是0。對于一個單字值最大的局部變量變址量是max_locals-1。max_argmax_arg項的值規(guī)定向該過程傳遞的參數(shù)的最大數(shù)目。max_stackmax_stack項的值規(guī)定在執(zhí)行該過程期間的任何時刻操作數(shù)堆棧上的最多字數(shù)。access_flagsaccess_flags項的值是用于描述對過程或?qū)嵗跏蓟^程的訪問許可和過程的特性的修改符的一個屏蔽。這些access_flags修改符和它們的值是與原始類文件的對應(yīng)method_info結(jié)構(gòu)中的完全相同的access_flags修改符。code_lengthcode_length項的值給出該過程的代碼數(shù)組中的字節(jié)數(shù)。code_length的值必須大于0,代碼數(shù)組不得為空數(shù)組。exception_lengthexception_length項的值給出exception_info表中的條目數(shù)。code[]code(代碼)數(shù)組給出實現(xiàn)該過程的Java虛擬機代碼的實際字節(jié)。當(dāng)代碼數(shù)組被讀入字節(jié)可尋址機器上的存儲器中時,如果數(shù)組的第一個字節(jié)是在4字節(jié)邊界上對齊的,則表切換(tableswitch)和查找切換(lookupswitch)的32位位移地址是4字節(jié)對齊的;關(guān)于代碼數(shù)組對齊的重要性可參閱對這些指令的說明以了解更多情況。對代碼數(shù)組內(nèi)容的具體限制很廣泛,與《Java虛擬機規(guī)范》一文中所述的相同。einfo[]einfo數(shù)組中的每個條目都描述代碼數(shù)組中的一個異常處理程序。每個einfo條目都含有以下各項start_pc、end_pcstart_pc、end_pc這兩項的值表示代碼數(shù)組中異常處理程序活動時所處的范圍。start_pc的值必須是一個在某指令的操作碼的代碼數(shù)組內(nèi)的有效變址量。end_pc的值要么必須是在某指令的操作碼的代碼數(shù)組內(nèi)的有效變址量,要么必須等于code_length即代碼數(shù)組的長度。start_pc的值必須小于end_pc的值。start_pc是包含的,end_pc是排除的,就是說,當(dāng)程序計數(shù)器位于區(qū)間[start_pc,end_pc]內(nèi)時,異常處理程序必須是活動的。handler_pchandler_pc項的值指示異常處理程序的開始。該項的值必須是代碼數(shù)組內(nèi)的一個有效變址,必須是某指令的操作碼的變址,必須小于code_length項的值。catch_type如果catch_type項的值是非零的,它必須代表一個有效的Java類類型。由catch_type代表的Java類類型必須是與由原始類文件的對應(yīng)method_info結(jié)構(gòu)中的catch_type所描述的完全相同的Java類類型。該類必須是類Throwable或者它的其中一個子類。異常處理程序僅當(dāng)被拋出的異常是給定類或者它的其中一個子類的一個實例時才被調(diào)用。如果catch_type項的值為零,則該異常處理程序就對所有異常而被調(diào)用。這被用于最終的執(zhí)行。Attributes原始類文件中使用的屬性要么被剔除,要么被重組,目的是為了緊湊??梢詫㈩A(yù)先定義的屬性SourceFile、ConstantValue、Exception、LineNumberTable和Local-VariableTable剔除,而不犧牲Java字節(jié)代碼解釋所需的任何信息。預(yù)先定義的含有特定過程的所有字節(jié)代碼的屬性Code,在對應(yīng)的MethodInfo結(jié)構(gòu)中被移動。對Java卡虛擬機代碼的限制過程、實例初始化過程、或者類或界面初始化過程的Java卡虛擬機代碼被存儲在卡類文件的MethodInfo結(jié)構(gòu)的數(shù)組代碼中。對這個代碼數(shù)組的靜態(tài)的和結(jié)構(gòu)性的兩種限制都與紅皮書中所述的相同。Java卡虛擬機和Java卡類文件格式的限制該版本的《Java卡虛擬機規(guī)范》在Java卡虛擬機中施加以下限制每個卡的類文件常量池由CardClassFile結(jié)構(gòu)()的16位const_size域限制在65535個條目。這作為對一個單一卡類文件的總體復(fù)雜程度的內(nèi)部限制。這個計數(shù)也包括對應(yīng)卡中應(yīng)用程序可用的類層次的常量池的條目。每個過程的代碼量由MethodInfo結(jié)構(gòu)中的變址量大小限制在65535個字節(jié)。過程中的局部變量個數(shù)由MethodInfo結(jié)構(gòu)()的max_local項的大小限制在255。類的域的個數(shù)由ClassInfo結(jié)構(gòu)()的max_field和max_sfield項的大小限制在510。類的過程個數(shù)由ClassInfo結(jié)構(gòu)()的max_method項的大小限制在255。操作數(shù)堆棧的大小由MethodInfo結(jié)構(gòu)()的Max_stack域限制到255個字。參考文獻[1]TimLinfholmandFrankYellin,TheJavaVirtualMachineSpeicification,Addison-Wesley,1996.附錄B串到ID輸入和輸出為了卡JVM的正確操作,很重要的一點是對所說明和生成的各ID加以正確的管理。這種管理由串到ID輸入文件String-IDINMap中的定義來控制。這個文本文件的基礎(chǔ)如以下所示,它說明名字的哪些地方可以用于什么用途。這個映射的一種可能安排可以保留一些ID供卡JVM解釋器作內(nèi)部使用,其余的被分配給卡JVM應(yīng)用程序。##String-IDINMap文件##4000-7FFF可供應(yīng)用程序所用#F000-FFFE保留供卡JVM作內(nèi)部使用#constantBaseF000#從F000到FFFF的區(qū)域保留#供卡JVM作內(nèi)部使用#MainApplication#F000-Startup類的名字#(隨各應(yīng)用程序而變)main()V#F001-Startup過程的名字#(可以隨應(yīng)用程序而變)java/lang/Object#F002java/lang/String#F003<init>()V#F004<clinit>()V#F005[L#F006[I#F007[C#F008[B#F009[S#F000A#constantBaseFFF0#本區(qū)保留用于簡單返回類型L#FFF0V#FFF1I#FFF2S#FFF3C#FFF4B#FFF5Z#FFF6#constantBase4000#此處開始的該空間依應(yīng)用程序而定。實際上,所有要被加載進智能卡中的應(yīng)用程序都在OX4000-OX7FFF之間被分配一個它們自己的ID。對于每一個應(yīng)用程序,這一空間是空閑的,因為不允許所加載的應(yīng)用程序訪問其它應(yīng)用程序。一定要注意管理預(yù)加載的類庫的ID。通過串到ID輸出文件String-IDOUTMap文件的生成(可選)可有助于這些ID的管理。這種映射是以新String-ID綁定擴充的String-IDINMap。這些綁定可以是在卡類文件轉(zhuǎn)換器應(yīng)用程序終止時產(chǎn)生。產(chǎn)生String-IDOUTMap用于在卡上加載的支持庫和OS接口。該映射可用作使用加載在該卡上的支持庫和OS接口的智能卡應(yīng)用程序的String-IDINMap。作為一個例子,考慮下面的Java程序,HelloSmartCard.Java。在對其編譯時,產(chǎn)生一個類文件HelloSmartCard.Class。該類文件已嵌入表示該類名、過程和類型信息的串中。根據(jù)上述的String-IDINMap,卡類文件轉(zhuǎn)換器產(chǎn)生一個卡類文件,該文件用卡類文件轉(zhuǎn)換器分配的ID替換該類文件中的串。表1列出了在HelloSmareCard。Class的常量池中發(fā)現(xiàn)的串,這些串具有各自的卡類文件轉(zhuǎn)換器分配的ID。注一些串(象“Java/Lang/Object”)具有預(yù)先分配的值(F002),一些串(象“()V”)獲得一個新值(4004)。ProgramHelloSmartCard.javapublicclassHelloSmartCard{publicbyteaVariable;publicstaticvoidmain(){HelloSmartCardh=newHelloSmartCard();h.aVariable=(byte)13;}}String-IDOUTMap的相關(guān)條目附錄C由優(yōu)選實施例中的卡JVM支持的字節(jié)代碼AALOADAASTOREACONST_NULLALOADALOAD_0ALOAD_1ALOAD_2ALOAD_3ARETURNARRAYLENGTHASTOREASTORE_0ASTORE_1ASTORE_2ASTORE_3ATHROWBALOADBASTORECHECKCASTDUPDUP2DUP2_X1DUP2_X2DUP_X1DUP_X2GETFIELDGETSTATICGOTOIADDIALOADIANDIASTOREICONST_0ICONST_1ICONST_2ICONST_3ICONST_4ICONST_5ICONST_M1IDIVIFEQIFGEIFGTIFLEIFLTIFNEIFNONNULLIFNULLIF_ACMPEQIF_ACMPNEIF_ICMPEQIF_ICMPGEIF_ICMPGTIF_ICMPLEIF_ICMPLTIF_ICMPNEIINCILOADILOAD_0ILOAD_1ILOAD_2ILOAD_3IMULINEGINSTANCEOFINT2BYTEINT2CHARINT2SHORTINVOKEINTERFACEINVOKENONVIRTUALINVOKESTATICINVOKEVIRTUALIORIREMIRETURNISHLISHRISTOREISTORE_0ISTORE_1ISTORE_2ISTORE_3ISUBIUSHRIXORJSRLDC1LDC2LOOKUPSWITCHNEWNEWARRAYNOPPOPPOP2PUTFIELDPUTSTATICRETRETURNSALOADSASTORESIPUSHSWAPTABLESWITCHBIPUSH優(yōu)選實施例中支持的字節(jié)代碼的標準Java字節(jié)代碼號packageutil;<prelisting-type="program-listing"><![CDATA[/**由該JVM處理的實際Java字節(jié)代碼的列表*參見Lindohlm和Yellin的文章。**版權(quán)屬于美國的SchlumbergerAustinProductsCenter,*Schlumberger,Austin,Texas,1996。*/publicinterfaceBytecodeDefn{publicstaticfinalbytej_NOP=(byte)0;publicstaticfinalbyteACONST_NULL=(byte)1;publicstaticfinalbyteICONST_M1=(byte)2;publicstaticfinalbyteICONST_0=(byte)3;publicstaticfinalbyteICONST_1=(byte)4;publicstaticfinalbyteICONST_2=(byte)5;publicstaticfinalbyteICONST_3=(byte)6;publicstaticfinalbyteICONST_4=(byte)7;publicstaticfinalbyteICONST_5=(byte)8;publicstaticfinalbyteBIPUSH=(byte)16;publicstaticfinalbyteSIPUSH=(byte)17;publicstaticfinalbyteLDC1=(byte)18;publicstaticfinalbyteLDC2=(byte)19;publicstaticfinalbyteILOAD=(byte)21;publicstaticfinalbyteALOAD=(byte)25;publicstaticfinalbyteILOAD_0=(byte)26;publicstaticfinalbyteILOAD_1=(byte)27;publicstaticfinalbyteILOAD_2=(byte)28;publicstaticfinalbyteILOAD_3=(byte)29;publicstaticfinalbyteALOAD_0=(byte)42;publicstaticfinalbyteALOAD_1=(byte)43;publicstaticfinalbyteALOAD_2=(byte)44;publicstaticfinalbyteALOAD_3=(byte)45;publicstaticfinalbyteIALOAD=(byte)46;publicstaticfinalbyteAALOAD=(byte)50;publicstaticfinalbyteBALOAD=(byte)51;publicstaticfinalbyteCALOAD=(byte)52;publicstaticfinalbyteISTORE=(byte)54;publicstaticfinalbyteASTORE=(byte)58;publicstaticfinalbyteISTORE_0=(byte)59;publicstaticfinalbyteISTORE_1=(byte)60;publicstaticfinalbyteISTORE_2=(byte)61;publicstaticfinalbyteISTORE_3=(byte)62;publicstaticfinalbyteASTORE_0=(byte)75;publicstaticfinalbyteASTORE_1=(byte)76;publicstaticfinalbyteASTORE_2=(byte)77;publicstaticfinalbyteASTORE_3=(byte)78;publicstaticfinalbyteIASTORE=(byte)79;publicstaticfinalbyteAASTORE=(byte)83;publicstaticfinalbyteBASTORE=(byte)84;publicstaticfinalbyteCASTORE=(byte)85;publicstaticfinalbytePOP=(byte)87;publicstaticfinalbytePOP2=(byte)88;publicstaticfinalbyteDUP=(byte)89;publicstaticfinalbyteDUP_X1=(byte)90;publicstaticfinalbyteDUP_X2=(byte)91;publicstaticfinalbyteDUP2=(byte)92;publicstaticfinalbyteDUP2_X1=(byte)93;publicstaticfinalbyteDUP2_X2=(byte)94;publicstaticfinalbyteSWAP=(byte)95;publicstaticfinalbyteIADD=(byte)96;publicstaticfinalbyteISUB=(byte)100;publicstaticfinalbyteIMUL=(byte)104;publicstaticfinalbyteIDIV=(byte)108;publicstaticfinalbyteIREM=(byte)112;publicstaticfinalbyteINEG=(byte)116;publicstaticfinalbyteISHL=(byte)120;publicstaticfinalbyteISHR=(byte)122;publicstaticfinalbyteIUSHR=(byte)124;publicstaticfinalbytelAND=(byte)126;publicstaticfinalbyteIOR=(byte)128;publicstaticfinalbyteIXOR=(byte)130;publicstaticfinalbyteIINC=(byte)132;publicstaticfinalbyteINT2BYTE=(byte)145;publicstaticfinalbyteINT2CHAR=(byte)146;publicstaticfinalbyteINT2SHORT=(byte)147;publicstaticfinalbyteIFEQ=(byte)153;publicstaticfinalbyteIFNE=(byte)154;publicstaticfinalbyteIFLT=(byte)155;publicstaticfinalbyteIFGE=(byte)156;publicstaticfinalbyteIFGT=(byte)157;publicstaticfinalbyteIFLE=(byte)158;publicstaticfinalbyteIF_ICMPEQ=(byte)159;publicstaticfinalbyteIF_ICMPNE=(byte)160;publicstaticfinalbyteIF_ICMPLT=(byte)161;publicstaticfinalbyteIF_ICMPGE=(byte)162;publicstaticfinalbyteIF_ICMPGT=(byte)163;publicstaticfinalbyteIF_ICMPLE=(byte)164;publicstaticfinalbyteIF_ACMPEQ=(byte)165;publicstaticfinalbyteIF_ACMPNE=(byte)166;publicstaticfinalbyteGOTO=(byte)167;publicstaticfinalbytej_JSR=(byte)168;publicstaticfinalbyteRET=(byte)169;publicstaticfinalbyteTABLESWITCH=(byte)170;publicstaticfinalbyteLOOKUPSWITCH=(byte)171;publicstaticfinalbyteIRETURN=(byte)172;publicstaticfinalbyteARETURN=(byte)176;publicstaticfinalbyteRETURN=(byte)177;publicstaticfinalbyteGETSTATIC=(byte)178;publicstaticfinalbytePUTSTATIC=(byte)179;publicstaticfinalbyteGETFIELD=(byte)180;publicstaticfinalbytePUTFIELD=(byte)181;publicstaticfinalbyteINVOKEVIRTUAL=(byte)182;publicstaticfinalbyteINVOKENONVIRTUAL=(byte)183;publicstaticfinalbyteINVOKESTATIC=(byte)184;pubiicstaticfinalbyteINVOKEINTERFACE=(byte)185;publicstaticfinalbyteNEW=(byte)187;publicstaticfinalbyteNEWARRAY=(byte)188;publicstaticfinalbyteARRAYLENGTH=(byte)190;publicstaticfinalbyteATHROW=(byte)191;publicstaticfinalbyteCHECKCAST=(byte)192;publicstaticfinalbyteINSTANCEOF=(byte)193;publicstaticfinalbyteIFNULL=(byte)198;publicstaticfinalbyteIFNONNULL=(byte)199;]]></pre>附錄D卡類文件轉(zhuǎn)換程序的字節(jié)代碼轉(zhuǎn)換過程<prelisting-type="program-listing"><![CDATA[/**再處理代碼塊*/staticvoidreprocessMethod(iMethod*imeth){intpc;intnpc;intalign;bytecode*code;intcodelen;inti;intopad;intnpad;intapc;inthigh;intlow;/*Codeinfo表跟蹤有效Java字節(jié)代碼及其對應(yīng)*的翻譯*/code=imeth->external->code;codelen=imeth->external->code_length;jumpPos=0;align=0;/*掃描不支持的操作碼*/for(pc=0;pc<codelen;pc=npc){if(codeinfo[code[pc]].valid==0){error(″Unsupportedopcode%d″,code[pc]);}npc=nextPC(pc,code);}/*掃描跳轉(zhuǎn)指令并插入跳轉(zhuǎn)表*/for(pc=0;pc<codelen;pc=npc){npc=nextPC(pc,code);if(codeinfo[code[pc]].valid==3){insertJump(pc+1,pc,(int16)((code[pc+1]<<8)|code[pc+2]));}eiseif(codeinfo[code[pc]].valid==4){apc=pc&-4;low=(code[apc+8]<<24)|(code[apc+9]<<16)|(code[apc+10]<<8)|code[apc+11];high=(code[apc+12]<<24)|(code[apc+13]<<16)|(code[apc+14]<<8)|code[apc+15];for(i=0;i<high-low+1;i++){insertJump(apc+(i*4)+18,pc, (int16)((code[apc+(i*4)+18]<<8)|code[apc+(i*4)+19]));}insertJump(apc+6,pc,(int16)((code[apc+6]<<8)|code[apc+7]));}elseif(codeinfo[code[pc]].valid==5){apc=pc&-4;low=(code[apc+8]<<24)|(code[apc+9]<<16) |(code[apc+10]<<8)|code[apc+11];for(i=0;i<low;i++){insertJump(apc+(i*8)+8,pc, (int16)((code[apc+(i*8)+18]<<8)|code[apc+(i*8)+19]));}insertJump(apc+6,pc,(int16)((code[apc+6]<<8)|code[apc+7]));}}#ifdefTRANSLATE_BYTECODE/*翻譯專用操作的以生成通用操作碼*/for(pc=0;pc<codelen;pc=npc){/*這是一個翻譯代碼*/if(codeinfo[code[pc]].valid==2){ switch(code[pc]){ caseILOAD_0 caseILOAD_1 caseILOAD_2 caseILOAD_3 insertSpace(code,&codelen,pc,1); align+=1; code[pc+1]=code[pc]-ILOAD_0; code[pc+0]=ILOAD; break; caseALOAD_0 caseALOAD_1 caseALOAD_2 caseALOAD_3 insertSpace(code,&codelen,pc,1); align+=1; code[pc+1]=code[pc]-ALOAD_0; code[pc+0]=ALOAD; break; caseISTORE_0 caseISTORE_1 caseISTORE_2 caseISTORE_3 insertSpace(code,&codelen,pc,1); align+=1; code[pc+1]=code[pc]-ISTORE_0; code[pc+0]=ISTORE;break; caseASTORE_0 caseASTORE_1 caseASTORE_2 caseASTORE_3 insertSpace(code,&codelen,pc,1); align+=1; code[pc+1]=code[pc]-ASTORE_0; code[pc+0]=ASTORE; break; caseICONST_M1 insertSpace(code,&codelen,pc,2); align+=2; code[pc+2]=255; code[pc+1]=255; code[pc+0]=SIPUSH; break; caseICONST_0 caseICONST_1 caseICONST_2 caseICONST_3 caseICONST_4 caseICONST_5 insertSpace(code,&codelen,pc,2); align+=2; code[pc+2]=code[pc]-ICONST_0; code[pc+1]=0; code[pc+0]=SIPUSH; break; caseLDC1 insertSpace(code,&codelen,pc,1);align+=1; code[pc+1]=0; code[pc+0]=LDC2; break;caseBIPUSHinsertSpace(code,&codelen,pc,1);align+=1;if((int8)code[pc+2]>=0){code[pc+1]=0;}else{code[pc+1]=255;}code[pc+0]=SIPUSH;break;caseINT2SHORTremoveSpace(code,&codelen,pc,1);align-=1;npc=pc;continue;}}elseif(codeinfo[code[pc]].valid==4||codeinfo[code[pc]].valid==5){/*切換被對齊到4字節(jié)的邊界。由于我們在插入,刪除字節(jié)代碼,*這會改變切換指令的對齊。*因此我們必須重新調(diào)整切換中的填充來加以補償。*/opad=(4-(((pc+1)-align)%4))%4;/*當(dāng)前切換填充*/npad=(4-((pc+1)%4))%4;/*新切換填充/*if(npad>opad){insertSpace(code,&codelen,pc+1,npad-opad);align+=(npad-opad);}elseif(npad<opad){removeSpace(code,&codelen,pc+1,opad-npad);align-=(opad-npad);}}npc=nextPC(pc,code);}#endif/*重鏈接常量*/for(pc=0;pc<codelen;pc=npc){npc=nextPC(pc,code);i=(uint16)((code[pc+1]<<8)+code[pc+2]);switch(code[pc]){caseLDC2/*′i′==通用變址*/switch(cltem(i).type){caseCONSTANNT_Integeri=cltem(i).v.tint;code[pc]=SIPUSH;break;caseCONSTANT_Stringi=buildStringindex(i);break;defaulterror(″Unsupportedloadingofconstanttype″);break;}break;caseNEWcaseINSTANCEOFcaseCHECKCAST/*′i′==類變址*/i=buildClassIndex(i);break;caseGETFIELDcasePUTFIELD/*′i′==域變址*//*i=buildFieldSignaturelndex(i);*/i=buildStaticFieldSignaturelndex(i);break;caseGETSTATICcasePUTSTATIC/*′i′==域變址*/i=buildStaticFieldSignaturelndex(i);break;caseINVOKEVIRTUALcaseINVOKENONVIRTUALcaseINVOKESTATICcaseINVOKEINTERFACE/*′i′==過程簽名變址*/i=buildSignaturelndex(i);break;}/*插入應(yīng)用程序的常量引用*/code[pc+1]=(i>>8)&0×FF;code[pc+2]=i&0×FF;}#ifdefMODIFY_BYTECODE/*翻譯代碼*/for(pc=0;pc<codelen;pc=npc){npc=nextPC(pc,code);code[pc]=codeinfo[code[pc]].translation;}#endif/*重鏈接跳轉(zhuǎn)*/for(i=0;i<jumpPos;i++){apc=j(luò)umpTable[i]at;pc=j(luò)umpTable[i].from;npc=j(luò)umpTable[i].to-pc;code[apc+0]=(npc>>8)&0×FF;code[apc+1]=npc&0×FF;}/*固定長度*/imeth->external->code_length=codelen;imeth->esize=(SIZEOFMETHOD+codelen+3)&-4;}]]></pre>附錄E加載和執(zhí)行控制程序舉例<prelisting-type="program-listing"><![CDATA[publicclassBootstrap{∥整個程序所使用的常量staticfinalbyteBUFFER_LENGTH=32;staticfinalbyteACK_SIZE=(byte)1;staticfinalbyteACK_CODE=(byte)0;staticfinalbyteOS_HEADER_SIZE=(byte)0×10;staticfinalbyteGPOS_CREATE_FILE=(byte)0×E0;staticfinalbyteST_INVALID_CLASS=(byte)0×C0;staticfinalbyteST_INVALID_PARAMETER=(byte)0×A0;staticfinalbyteST_INS_NOT_SUPPORTED=(byte)0×B0;staticfinalbyteST_SUCCESS=(byte)0×00;staticfinalbyteISO_COMMAND_LENGTH=(byte)5;staticfinalbyteISO_READ_BINARY=(byte)0×B0;staticfinalbyteISO_UPDATE_BINARY=(byte)0×D6;staticfinalbyteISO_INIT_APPLICATION=(byte)0×F2;staticfinalbyteISO_VERIFY_KEY=(byte)0×2A;staticfinalbyteISO_SELECT_FILE=(byte)0×A4;staticfinalbyteISO_CLASS=(byte)0×C0;staticfinalbyteISO_APP_CLASS=(byte)0×F0;publicstaticvoidmain(){bytepbuffer[]=newbyte[ISO_COMMAND_LENGTH];bytedbuffer[]=newbyte[BUFFER_LENGTH];byteackByte[]=newbyte[ACK_SIZE];∥shortfileld;shortoffset;bytebReturnStatus;∥初始化通信_OS.SendATR();do{∥提取命令首部_OS.GetMessage(pbuffer,ISO_COMMAND_LENGTH,ACK_CODE);∥檢驗報文的類-僅ISO和應(yīng)用程序if((pbuffer?。絀SO_APP_CLASS)&&(pbuffer?。絀SO_CLASS)){_OS.SendStatus(ST_INVALID_CLASS);}else{∥通過切換∥發(fā)送應(yīng)答代碼∥檢驗數(shù)據(jù)長度是否太大if(pbuffer[4]>BUFFER_LENGTH){bReturnStatus=ST_INVALID_PARAMETER;}else{switch(pbuffer[1]){caseISO_SELECT_FILE∥假定長度總是2if(pbuffer[4]?。?){bReturnStatus=ST_INVALID_PARAMETER;}else{∥讀取數(shù)據(jù)緩沖器中的field(offset)_OS.GetMessage(dbuffer,(byte)2,pbuffer[1]);∥將dbuffer變換成短整數(shù)offset=(short)((dbuffer<<8)|(dbuffer[1]&0×00FF)); bReturnStatus=_OS.SelectFile(offset);}break;caseISO_VERIFY_KEY∥從終端取得密鑰_OS.GetMessage(dbuffer,pbuffer[4],pbuffer[1]);bReturnStatus=_OS.VerifyKey(pbuffer[3], dbuffer, pbuffer[4]);break;caseISO_INIT_APPLICATION∥應(yīng)發(fā)送有效程序文件的ID_OS.GetMessage(dbuffer,(byte)1,pbuffer[1]);∥通過變換從pbuffer[2..3]計算fileld(offset)offset=(short)((pbuffer[2]<<8)|(pbuffer[3]&0×00FF));bReturnStatus=_OS.Execute(offset, dbuffer);break;caseGPOS_CREATE_FILEif(pbuffer[4]?。絆S_HEADER_SIZE){ bReturnStatus=ST_INVALID_PARAMETER; break;}∥接收數(shù)據(jù)_OS.GetMessage(dbuffer,pbuffer[4],pbuffer[1]);bReturStatus=_OS.CreateFile(dbuffer);break;caseISO_UPDATE_BINARY_OS.GetMessage(dbuffer,pbuffer[4],pbuffer[1]);∥通過變換從pbuffer[2..3]計算偏移offset=(short)((pbuffer[2]<<8)|(pbuffer[3]&0×00FF)); ∥假定有文件已被選擇 bReturnStatus=_OS.WriteBinaryFile(offset, pbuffer[4], dbuffer); break; caseISO_READ_BINARY ∥通過變換從pbuffer[2..3]計算偏移 offset=(short)((pbuffer[2]<<8)|(pbuffer[3]&0×00FF)); ∥假定某文件已經(jīng)被選擇 bReturnStatus=_OS.ReadBinaryFile(offset, pbuffer[4], dbuffer); ∥如果成功則發(fā)送數(shù)據(jù) ackByte=pbuffer[1]; if(bReturnStatus==ST_SUCCESS){ _OS.SendMessage(ackByte,ACK_SIZE); _OS.SendMessage(dbuffer,pbuffer[4]); } break; default bReturnStatus=ST_INS_NOT_SUPPORTED; } } _OS.SendStatus(bReturnStatus);}}while(true);}}]]></pre>附錄F優(yōu)選實施例中訪問卡操作系統(tǒng)功能的過程<prelisting-type="program-listing"><![CDATA[pubiicclass_OS{staticnativebyteSelectFile(shortfile_id);staticnativebyteSelectParent();staticnativebyteSelectCD();staticnativebyteSelectRoot();staticnativebyteCreateFile(bytefile_hdr[]);staticnativebyteDeleteFile(shortfile_id);∥一般文件操作staticnativebyteResetFile();staticnativebyteReadByte(byteoffset);staticnativeshortReadVVord(byteoffset);∥首部操作staticnativebyteGetFilelnfo(bytefile_hdr[]);∥二進制文件支持staticnativebyteReadBinaryFile(shortoffset, bytedata_length, bytebuffer[]);staticnativebyteWriteBinaryFile(shortoffset, bytedata_length, bytebuffer[]);∥記錄文件支持staticnativebyteSelectRecord(byterecord_nb, bytemode);staticnativebyteNextRecord();staticnativebytePreviousRecord();staticnativebyteReadRecord(byterecord_data[], byterecord_nb, byteoffset, bytelength);staticnativebyteWriteRecord(bytebuffer[], byterecord_nb, byteoffset, bytelength);∥循環(huán)文件支持staticnativebyteLastUpdatedRec();∥報文傳遞功能staticnativebyteGetMessage(bytebuffer[], byteexpected_length, byteack_code);staticnativebyteSendMessage(bytebuffer[], bytedata_length);staticnativebyteSetSpeed(bytespeed);∥身份管理staticnativebyteCheckAccess(byteac_action);staticnativebyteVerifyKey(bytekey_number, bytekey_buffer[], bytekey_length);staticnativebyteVerifyCHV(byteCHV_number, byteCHV_bufferr[], byteunblock_flag);staticnativebyteModifyCHV(byteCHV_number, byteold_CHV_buffer[], bytenew_CHV_buffer[], byteunblock_flag);staticnativebyteGetFileStatus();staticnativebyteSetFileStatus(bytefile_status);staticnativebyteGrantSupervisorMode();staticnativebyteRevokeSupervisorMode();staticnativebyteSetFileACL(bytefile_acl[]);staticnativebyteGetFileACL(bytefile_acl[]);∥文件上下文操作staticnativevoidInitFileStatus();staticnativevoidBackupFileStatus();staticnativevoidRestoreFileStatus();∥實用程序staticnativebyteCompareBuffer(bytepatterm_length, bytebuffer_1[], bytebuffer_2[]);staticnativeshortAvailableMemory();staticnativevoidResetCard(bytemode);staticnativebyteSendATR();staticnativebyteSetDefaultATR(bytebuffer□, bytelength);staticnativebyteExecute(shortfile_id, byteflag);∥全局狀態(tài)變量函數(shù)staticnativebyteGetldentity();staticnativebyteGetRecordNb();staticnativeshortGetApplicationld();staticnativebyteGetRecordLength();staticnativebyteGetFileType();staticnativeshortGetFileLength();staticnativevoidSendStatus(bytestatus);}]]></pre>附錄G字節(jié)代碼屬性表劃分Java字節(jié)代碼成類型組每個字節(jié)代碼都被分配一個與之關(guān)聯(lián)的5位類型。它用于將代碼劃分為行為相似的各個集合。一般來說,這種行為反映的是各類型的字節(jié)代碼是如何在堆棧上操作的;但是,類型0、13、14和15反映的是特殊種類的指令,如注解欄所注明。下表表示在每類指令被執(zhí)行前后堆棧的狀態(tài)。類型執(zhí)行前執(zhí)行后注解0非法指令1stk0==intstk1==intpop(1)2stk0==intpop(1)3stk0==intstk1==intpop(2)45push(1)6stk0==intstk1==intpop(3)7stk0==intpop(1)8stk0==refpop(1)9stk0==intpop(1)10push(1)stk0<-int11push(1)stk0<-ref12stk0==refstk0<-int13DUPs,SWAP指令14INVOKE指令15FIELDS指令16stk0<-ref使用標準Java字節(jié)代碼(設(shè)有重新排序)-屬性查找表<prelisting-type="program-listing"><![CDATA[ /* *字節(jié)代碼譯碼信息表。該表內(nèi)容是字節(jié)代碼類型和 *字節(jié)代碼長度。當(dāng)前支持代碼0-201的所有 *標準字節(jié)代碼(共202個代碼) */ #defineT_0 #defineT31 #defineT62 #defineT13 #defineT24 #defineT75 #defineT96 #defineT87 #defineT128 #defineT109 #defineT510 #defineT1111 #defineT1612 #defineT413 #defineT1314 #defineT1415 #defineT1516 #defineD(T,L) _BUILD_ITYPE_AND_ILENGTH(T,L) #define_BUILD_ITYPE_AND_ILENGTH(T,L) (_BUILD_ITYPE(T)I_BUILD_ILENGTH(L)) #define_BUILD_ITYPE(T)((T)<<3) #define_BUILD_ILENGTH(L)(L) #define_GET_ITYPE(I)((I)&0×F8) #define_GET_ILENGTH(I)((I)&0×07)constuint8_SCODE_decodeinfo[256]={ D(T4,1),/*NOP*/ D(T11,1),/*ACONST_NULL*/ D(T10,1),/*ICONST_M1*/ D(T10,1),/*ICONST_0*/ D(T10,1),/*ICONST_1*/ D(T10,1),/*ICONST_2*/ D(T10,1),/*ICONST_3*/ D(T10,1),/*ICONST_4*/ D(T10,1),/*ICONST_5*/ D(T_,1), D(T_,1), D(T_,1), D(T_,1), D(T_,1), D(T_,1), D(T_,1), D(T10,2),/*BIPUSH*/ D(T10,3),/*SIPUSH*/ D(T_,2),/*LDC1*/ D(T11,3),/*LDC2*/ D(T_,3), D(T5,2),/*ILOAD*/ D(T_,2), D(T_,2), D(T_,2), D(T5,2),/*ALOAD*/ D(T5,1),/*ILOAD_0*/ D(T5,1),/*ILOAD_1*/ D(T5,1),/*ILOAD_2*/ D(T5,1),/*ILOAD_3*/ D(T_,1), D(T_,1), D(T_,1), D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T5,1),/*ALOAD_0*/D(T5,1),/*ALOAD_1*/D(T5,1),/*ALOAD_2*/D(T5,1),/*ALOAD_3*/D(T_,1),/*IALOAD*/D(T_,1),D(T_,1),D(T_,1),D(T_,1),/*AALOAD*/D(T7,1),/*BALOAD*/D(T_,1),/*CALOAD*/D(T7,1),/*SALOAD*/D(T2,2),/*ISTORE*/D(T_,2),D(T_,2),D(T_,2),D(T8,2),/*ASTORE*/D(T2,1),/*ISTORE_0*/D(T2,1),/*ISTORE_1*/D(T2,1),/*ISTORE_2*/D(T2,1),/*ISTORE_3*/D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T8,1),/*ASTORE_0*/D(T8,1),/*ASTORE_1*/D(T8,1),/*ASTORE_2*/D(T8,1),/*ASTORE_3*/D(T_,1),/*IASTORE*/D(T_,1),D(T_,1),D(T_,1),D(T_,1),/*AASTORE*/D(T6,1),/*BASTORE*/D(T_,1),/*CASTORE*/D(T6,1),/*SASTORE*/D(T2,1),/*POP*/D(T3,1),/*POP2*/D(T13,1),/*DUP*/D(T13,1),/*DUP_X1*/D(T13,1),/*DUP_X2*/D(T13,1),/*DUP2*/D(T13,1),/*DUP2_X1*/D(T13,1),/*DUP2_X2*/D(T13,1),/*SWAP*/D(T1,1),/*IADD*/D(T_,1),D(T_,1),D(T1,1),D(T_,1),/*ISUB*/D(T_,1),D(T_,1),D(T_,1),D(T1,1),/*IMUL*/D(T_,1),D(T_,1),D(T_,1),D(T1,1),/*IDIV*/D(T_,1),D(T_,1),D(T_,1),D(T1,1),/*IREM*/D(T_,1),D(T_,1),D(T_,1),D(T9,1),/*INEG*/D(T_,1),D(T_,1),D(T_,1),D(T1,1),/*ISHL*/D(T_,1),D(T1,1),/*ISHR*/D(T_,1),D(T1,1),/*IUSHR*/D(T_,1),D(T1,1),/*IAND*/D(T_,1),D(T1,1),/*IOR*/D(T_,1),D(T1,1),/*IXOR*/D(T_,1),D(T4,3),/*IINC*/D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T9,1),/*INT2BYTE*/D(T9,1),/*INT2CHAR*/D(T_,1),/*INT2SHORT*/D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T2,3),/*IFEQ*/D(T2,3),/*IFNE*/D(T2,3),/*IFLT*/D(T2,3),/*IFGE*/D(T2,3),/*IFGT*/D(T2,3),/*IFLT*/D(T3,3),/*IF_ICMPEQ*/D(T3,3),/*IF_ICMPNE*/D(T3,3),/*IF_ICMPLT*/D(T3,3),/*IF_ICMPGE*/D(T3,3),/*IF_ICMPGT*/D(T3,3),/*IF_ICMPLE*/D(T3,3),/*IF_ACMPEQ*/D(T3,3),/*IF_ACMPNE*/D(T4,3),/*GOTO*/D(T_,3),/*JSR*/D(T_,2),/*RET*/D(T2,0),/*TABLESWITCH*/D(T2,0),/*LOOKUPSWITCH*/D(T2,1),/*IRETURN*/D(T_,1),D(T_,1),D(T_,1),D(T8,1),/*ARETURN*/D(T4,1),/*RETURN*/D(T15,3),/*GETSTATIC*/D(T15,3),/*PUTSTATIC*/D(T15,3),/*GETFIELD*/D(T15,3),/*PUTFIELD*/D(T14,3),/*INVOKEVIRTUAL*/D(T14,3),/*INVOKESPECIAL*/D(T14,3),/*INVOKESTATIC*/D(T14,5),/*INVOKEINTERFACE*/D(T_,1),D(T11,3),/*NEW*/D(T16,2),/*NEWARRAY*/D(T_,3),D(T12,1),/*ARRAYLENGTH*/D(T8,1),/*ATHROW*/D(T16,3),/*CHECKCAST*/D(T12,3),/*INSTANCEOF*/D(T_,1),D(T_,1),D(T_,1),D(T_,4),D(T8,3),/*IFNULL*/D(T8,3),/*IFNONNULL*/D(T_,5),D(T_,5),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),D(T_,1),};]]></pre>附錄H通過類型對Java字節(jié)代碼進行的檢查將指令解碼,得出要生成下一個PC的長度、以及指令類型<prelisting-type="program-listing"><![CDATA[pcarg1=_GET_ILENGTH(_decodeinfo[insn]); itype=_GET_ITYPE(_decodeinfo[insn]); 根據(jù)以下內(nèi)容進行一些執(zhí)行前檢查 /*根據(jù)指令類型來檢查輸入堆棧類型*/ if(itype<=ITYPE9){ if(itype<=ITYPE1){ check_stack_int(1); } check_stack_int(0); } elseif(itype<=ITYPE12){ check_stack_ref(0); } elseif(itype<ITYPE11){ push(1); } 最后,進行一些執(zhí)行后的檢查 /*設(shè)置輸出狀態(tài)*/ if(itype<=ITYPE8){ if(itype<=ITYPE6){ if(itype>=ITYPE6){ pop(1); }pop(1); } pop(1);}elseif(itype<=ITYPE10){ set_stack_int(0);}elseif(itype>=ITYPE11&&itype<=ITYPE16){ set_stack_ref(0);}]]></pre>附錄I對重編號的Java字節(jié)代碼進行的檢查取指令。指令的數(shù)字值隱含地包括指令類型insn=getpc(-1);根據(jù)以下內(nèi)容進行一些執(zhí)行前檢查<prelisting-type="program-listing"><![CDATA[/**檢查輸入堆棧狀態(tài)。通過對字節(jié)代碼重新編號, *如果字節(jié)代碼的值(因此字節(jié)代碼)屬于正確的 *組,則能通過測試而進行必需的安全檢查?! ?/ if(insn<=TYPE9_END){ if(insn<=TYPE1_END){ check_stack_int(1); } check_stack_int(0); } elseif(insn<=TYPE12_END){ check_stack_ref(0); } elseif(insn<=TYPE11_END){ push(1) } 最后,進行一些執(zhí)行后檢查 /**設(shè)置輸出堆棧狀態(tài)。*/if(insn<=TYPE8_END){if(insn<=TYPE6_END){if(insn>=TYPE6_START){ pop(1);}pop(1);}pop(1);}elseif(insn<=TYPE10_END){set_stack_int(0);}elseif(insn>=TYPE11_START&&insn<=TYPE16_END){set_stack_ref(0);}按類型來對所支持的Java字節(jié)代碼進行重定序/*類型3*/#defines_POP20#defines_IF_ICMPEQ1#defines_IF_ICMPNE2#defines_IF_ICMPLT3#defines_IF_ICMPGE4#defines_IF_ICMPGT5#defines_IF_ICMPLE6#defines_IF_ACMPEQ7#defines_IF_ACMPNE8/*類型6*/#defineTYPE6_START9#defines_SASTORE9#defines_AASTORE10#defines_BASTORE11#defineTYPE6_END12/*類型1*/#defines_IADD13#defines_ISUB14#defines_IMUL15#defines_IDIV16#defines_IREM17#defines_ISHL18#defines_ISHR19#defines_IUSHR20#defines_IAND21#defines_IOR22#defines_IXOR23#defineTYPE1_END23/*類型2*/#defines_ISTORE24#defines_POP25#defines_IFEQ26#defines_IFNE27#defines_IFLT28#defines_IFGE29#defines_IFGT30#defines_IFLE31#defines_TABLESWITCH32#defines_LOOKUPSWITCH33#defines_IRETURN34/*類型7*/#defines_SALOAD35#defines_AALOAD36#defines_BALOAD37/*類型9*/#defines_INEG39#defines_INT2BYTE40#defines_INT2CHAR41#defineTYPE9_END41/*類型8*/#defines_ASTORE42#defines_ARETURN43#defines_ATHROW44#defines_IFNULL45#defines_IFNONNULL46#defineTYPE8_END46/*類型12*/#defines_ARRAYLENGTH47#defines_INSTANCEOF48#defineTYPE12_END48/*類型10*/#defines_SIPUSH49#defineTYPE10_END49/*類型5*/#defines_ILOAD50#defines_ALOAD51/*類型11*/#defineTYPE11_START52#defines_ACONST_NULL52#defines_LDC253#defines_JSR54#defines_NEW55#defineTYPE11_END55/*類型16*/#defines_NEWARRAY56#defines_CHECKCAST57#defineTYPE16_END57/*類型13*/#defines_DUP58#defines_DUP_X159#defines_DUP_X260#defines_DUP261#defines_DUP2_X162#defines_DUP2_X263#defines_SWAP64/*類型14*/#defines_INVOKEVIRTUAL65/*01000001*/#defines_INVOKENONVIRTUAL66/*01000010*/#defines_INVOKESTATIC67/*01000011*/#defines_INVOKEINTERFACE68/*01000100*//*類型15*/#defines_GETSTATIC69#defines_PUTSTATIC70#defines_GETFIELD71#defines_PUTFIELD72/*類型4*/#defines_NOP73#defines_IINC74#defines_GOTO75#defines_RET76#defines_RETURN77]]></pre>權(quán)利要求1.一種用于終端的集成電路卡,包含一個配置成能與該終端通信的通信器;一個存儲一個具有高級程序設(shè)計語言格式的應(yīng)用程序和一個解釋程序的存儲器;一個與該存儲器相連的處理器,該處理器被配置成能用該解釋程序來解釋執(zhí)行該應(yīng)用程序并用該通信器與該終端通信。2.權(quán)利要求1的集成電路卡,其中,該高級程序設(shè)計語言包含一個類文件格式。3.權(quán)利要求1的集成電路卡,其中,該處理器包含一個微控制器4.權(quán)利要求1的集成電路卡,其中,該存儲器至少有一部分位于該處理器中。5.權(quán)利要求1的集成電路卡,其中,該高級程序設(shè)計語言格式包含Java程序設(shè)計語言格式。6.權(quán)利要求1的集成電路卡,其中,該應(yīng)用程序已經(jīng)被有一個字符串的第二應(yīng)用程序處理過,該字符串在第一應(yīng)用程序中用一個標識符來代表。7.權(quán)利要求6的集成電路卡,其中,該標識符包含一個整數(shù)。8.權(quán)利要求1的集成電路卡,其中,該處理器被進一步配置成從某個請求者接收要求訪問該卡的某個單元的請求;接收該請求后,與該請求者交互作用以驗證該請求者的身份;根據(jù)該身份,有選擇地授予對該單元的訪問權(quán)。9.權(quán)利要求8的集成電路卡,其中,該請求者包含該處理器。10.權(quán)利要求8的集成電路卡,其中,該請求者包含該終端。11.權(quán)利要求8的集成電路卡,其中,該單元包含在該存儲器中存儲的該應(yīng)用程序,并且一旦訪問被允許時,該請求者被配置成能使用該應(yīng)用程序。12.權(quán)利要求8的集成電路卡,其中,該單元包含另一個在該存儲器中存儲的應(yīng)用程序。13.權(quán)利要求8的集成電路卡,其中,該單元包含在存儲器中存儲的數(shù)據(jù)。14.權(quán)利要求8的集成電路卡,其中,該單元包含該通信器。15.權(quán)利要求8的集成電路卡,其中,該存儲器也為該單元存儲一個存取控制列表,該存取控制列表中有一個表示要授予該身份的訪問的類型的標志,該處理器進一步被配置成能根據(jù)該存取控制列表有選擇地將特定的訪問類型授權(quán)給該請求者。16.權(quán)利要求15的集成電路卡,其中,該訪問的類型包括讀數(shù)據(jù)。17.權(quán)利要求15的集成電路卡,其中,該訪問的類型包括寫數(shù)據(jù)。18.權(quán)利要求15的集成電路卡,其中,該訪問的類型包括追加數(shù)據(jù)。19.權(quán)利要求15的集成電路卡,其中,該訪問的類型包括創(chuàng)建數(shù)據(jù)。20.權(quán)利要求15的集成電路卡,其中,該訪問的類型包括刪除數(shù)據(jù)。21.權(quán)利要求15的集成電路卡,其中,該訪問的類型包括執(zhí)行某應(yīng)用程序。22.權(quán)利要求1的集成電路卡,其中,該應(yīng)用程序是該存儲器中存儲的多個應(yīng)用程序的其中之一,該處理器進一步被配置成接收來自一個請求者要求訪問多個應(yīng)用程序的其中之一的請求;接收該請求后,判定多個應(yīng)用程序的該其中之一是否與一個預(yù)定的規(guī)則集相符;根據(jù)該判定,有選擇地授予該請求者對多個應(yīng)用程序的所述一個的訪問權(quán)。23.權(quán)利要求22的集成電路卡,其中,該預(yù)定的規(guī)則為決定多個應(yīng)用程序的所述一個是否訪問存儲器的某預(yù)定區(qū)域提供指引。24.權(quán)利要求22的集成電路卡,其中,該處理器進一步被配置成驗證該請求者的一個身份;根據(jù)該身份,授予對多個應(yīng)用程序的所述一個的訪問權(quán)。25.權(quán)利要求1的集成電路卡,其中,該處理器進一步被配置成通過該通信器與該終端進行交互作用以驗證某個身份;判斷該身份是否已經(jīng)被驗證;根據(jù)該判斷,有選擇地允許該終端與該集成電路卡之間的通信。26.權(quán)利要求25的集成電路卡,其中,該通信器與該終端通過通信通道進行通信,該處理器進一步被配置成當(dāng)該處理器允許在終端與該集成電路卡之間通信時,將其中一個通信通道分配給該身份。27.權(quán)利要求26的集成電路卡,其中,該處理器進一步被配置成向該其中一個通信通道分配一個會話密鑰;當(dāng)該處理器與該終端通過該其中之一通信通道進行通訊時,使用該會話密鑰。28.權(quán)利要求1的集成電路卡,其中,該終端具有一個讀卡機,該通信器包含一個用于與該讀卡機通信的觸點。29.權(quán)利要求1的集成電路卡,其中,該終端有一個無線通信設(shè)備,該通信器有一個用于與該無線通信設(shè)備通信的無線收發(fā)機。30.權(quán)利要求1的集成電路卡,其中,該終端有一個無線通信設(shè)備,該通信器包含一個用于與該無線通信設(shè)備通信的無線發(fā)射機。31.一種用于集成電路卡和終端的方法,包含在該集成電路卡的存儲器中存儲一個解釋程序和一個具有高級程序設(shè)計語言格式的應(yīng)用程序;用該集成電路卡的處理器來用該解釋程序去解釋執(zhí)行該應(yīng)用程序;當(dāng)該處理器與該終端之間進行通信時,使用該卡的通信器。32.權(quán)利要求31的方法,其中,該高級程序設(shè)計語言包含一個類文件格式。33.權(quán)利要求31的方法,其中,該處理器包含一個微控制器34.權(quán)利要求31的方法,其中,該存儲器至少有一部分位于該處理器中。35.權(quán)利要求31的方法,其中,該高級程序設(shè)計語言格式包含Java程序設(shè)計語言格式。36.權(quán)利要求31的方法,其中,該應(yīng)用程序已經(jīng)被有一個字符串的第二應(yīng)用程序處理過,進一步包含在第一應(yīng)用程序中用一個標識符來代表該字符串。37.權(quán)利要求36的方法,其中,該標識符包含一個整數(shù)。38.權(quán)利要求31的方法,進一步包含從某個請求者接收要求訪問該卡的某個單元的請求;接收該請求后,與該請求者交互作用以驗證該請求者的身份;根據(jù)該身份,有選擇地授予對該單元的訪問權(quán)。39.權(quán)利要求38的方法,其中,該請求者包含該處理器。40.權(quán)利要求38的方法,其中,該請求者包含該終端。41.權(quán)利要求38的方法,其中,該單元包含在該存儲器中存儲的該應(yīng)用程序,進一步包含一旦訪問被允許時,以該請求者來使用該應(yīng)用程序。42.權(quán)利要求38的方法,其中,該單元包含另一個在該存儲器中存儲的應(yīng)用程序。43.權(quán)利要求38的方法,其中,該單元包含在該存儲器中存儲的數(shù)據(jù)。44.權(quán)利要求38的方法,其中,該單元包含該通信器。45.權(quán)利要求38的方法,其中,存儲器也為該單元存儲一個存取控制列表,該存取控制列表中有一個表示要授予該身份的訪問的類型的標志,進一步包含根據(jù)該存取控制列表,用該處理器來有選擇地將特定的訪問類型授權(quán)給該請求者。46.權(quán)利要求45的方法,其中,該訪問的類型包括讀數(shù)據(jù)。47.權(quán)利要求45的方法,其中,該訪問的類型包括寫數(shù)據(jù)。48.權(quán)利要求45的方法,其中,該訪問的類型包括追加數(shù)據(jù)。49.權(quán)利要求45的方法,其中,該訪問的類型包括創(chuàng)建數(shù)據(jù)。50.權(quán)利要求45的方法,其中,該訪問的類型包括刪除數(shù)據(jù)。51.權(quán)利要求45的方法,其中,該訪問的類型包括執(zhí)行某應(yīng)用程序。52.權(quán)利要求31的方法,其中,該應(yīng)用程序是存儲器中存儲的多個應(yīng)用程序的其中之一,進一步包含接收來自請求者要求訪問存儲在該存儲器中的該多個應(yīng)用程序的其中之一的請求;接收該請求后,判定該多個應(yīng)用程序的所述一個是否與預(yù)定的規(guī)則集相符;根據(jù)該判定,有選擇地授予該請求者對該多個應(yīng)用程序的所述一個的訪問權(quán)。53.權(quán)利要求52的方法,其中,該預(yù)定的規(guī)則為決定該多個應(yīng)用程序的所述一個是否訪問該存儲器的某預(yù)定區(qū)域提供指南。54.權(quán)利要求52的方法,進一步包含驗證該請求者的一個身份;根據(jù)該身份,授予對該多個應(yīng)用程序的所述一個的訪問權(quán)。55.權(quán)利要求31的方法,進一步包含通過與該終端的通信來驗證某個身份;判斷該身份是否已經(jīng)被驗證;根據(jù)該判斷,有選擇地允許該終端與該集成電路卡之間的通信。56.權(quán)利要求55的方法,進一步包含該終端與該處理器通過通信通道進行通信;當(dāng)允許該讀卡機與該集成電路卡之間通信時,將其中一個通信通道分配給該身份。57.權(quán)利要求56的方法,進一步包含向該其中一個通信通道分配會話密鑰;當(dāng)該處理器與該終端通過該其中之一通信通道進行通信時,使用該會話密鑰。58.一種智能卡,包含一個存儲一個Java解釋程序的存儲器;一個配置成用該解釋程序來解釋執(zhí)行Java應(yīng)用程序的處理器。59.一種微控制器,包含一個半導(dǎo)體襯底;一個位于該半導(dǎo)體襯底的存儲器;一個在該存儲器中存儲并配置成能執(zhí)行安全檢查的程序設(shè)計語言解釋程序;一個位于該襯底并與該存儲器相連的中央處理單元。60.權(quán)利要求59的微控制器,其中,該解釋程序包含Java字節(jié)代碼解釋程序。61.權(quán)利要求59的微控制器,其中,該安全檢查包含建立防火墻。62.權(quán)利要求59的微控制器,其中,該安全檢查包含實行沙箱安全模型。63.一種智能卡,包含一個存儲器;一個在該存儲器中存儲并配置能執(zhí)行安全檢查的程序設(shè)計語言解釋程序;一個與該存儲器相連的中央處理單元。64.權(quán)利要求63的智能卡,其中,該解釋程序包含Java字節(jié)代碼解釋程序。65.權(quán)利要求63的智能卡,其中,該安全檢查包含建立防火墻。66.權(quán)利要求63的智能卡,其中,該安全檢查包含實行沙箱安全模型。67.一種用于終端的集成電路卡,包含一個通信器;一個存儲器,該存儲器存儲一個解釋程序和第一應(yīng)用程序的第一指令,該第一指令是從第二應(yīng)用程序的第二指令轉(zhuǎn)換的;一個處理器,該處理器與該存儲器相連并被配置成能用該解釋程序來執(zhí)行該第一指令以及通過該通信器與該終端進行通信。68.權(quán)利要求67的集成電路卡,其中,該第一應(yīng)用程序有一種類文件格式。69.權(quán)利要求67的集成電路卡,其中,該第二應(yīng)用程序有一種類文件格式。70.權(quán)利要求67的集成電路卡,其中,該第一指令包含字節(jié)代碼。71.權(quán)利要求67的集成電路卡,其中,該第二指令包含字節(jié)代碼。72.權(quán)利要求67的集成電路卡,其中,該第一指令包含Java字節(jié)代碼。73.權(quán)利要求67的集成電路卡,其中,該第二指令包含Java字節(jié)代碼。74.權(quán)利要求67的集成電路卡,其中,該第一指令包含第二指令的通用化版本。75.權(quán)利要求67的集成電路卡,其中,該第一指令包含第二指令的重編號版本。76.權(quán)利要求67的集成電路卡,其中,第二指令包括常量引用;該第一指令包括替代該第二指令的該常量引用的常量。77.權(quán)利要求67的集成電路卡,其中,該第二指令包括引用,這些引用在該第二指令向該第一指令轉(zhuǎn)換期間移動位置;該第一指令被重新鏈接到移位后的該引用。78.權(quán)利要求67的集成電路卡,其中,該第一指令包含用于第一類虛擬機的字節(jié)代碼;該第二指令包含用于第二類虛擬機的字節(jié)代碼,該第一類與該第二類不同。79.一種用于集成電路卡的方法,包含將第二應(yīng)用程序的第二指令轉(zhuǎn)換成第一應(yīng)用程序的第一指令;該將第一指令存儲到該集成電路卡的存儲器中;用該集成電路卡的解釋程序來執(zhí)行該第一指令。80.權(quán)利要求79的方法,其中,該第一應(yīng)用程序有一種類文件格式。81.權(quán)利要求79的方法,其中,該第二應(yīng)用程序有一種類文件格式。82.權(quán)利要求79的方法,其中,該第一指令包含字節(jié)代碼。83.權(quán)利要求79的方法,其中,該第二指令包含字節(jié)代碼。84.權(quán)利要求79的方法,其中,該第一指令包含Java字節(jié)代碼。85.權(quán)利要求79的方法,其中,該第二指令包含Java字節(jié)代碼。86.權(quán)利要求79的方法,其中,該第一指令是該第二指令的通用化版本。87.權(quán)利要求79的方法,其中,該轉(zhuǎn)換包括將該第二指令重編號后形成第一指令。88.權(quán)利要求79的方法,其中,該第二指令包括常量引用,該轉(zhuǎn)換包括用常量來替代該第二指令的該常量引用。89.權(quán)利要求79的方法,其中,該第二指令包括引用,該轉(zhuǎn)換包括將該引用移動位置,進一步包含將該第一指令重新鏈接到轉(zhuǎn)換后的該引用。90.權(quán)利要求79的方法,其中,該第一指令包含用于第一類虛擬機的字節(jié)代碼,該第二指令包含用于第二類虛擬機的字節(jié)代碼,該第一類與該第二類不同。91.一種用于終端的集成電路卡,包含一個配置成與該終端通信的通信器;一個存儲器,該存儲器存儲一個已經(jīng)被有一個字符串的第二應(yīng)用程序處理過的第一應(yīng)用程序,該字符串在該第一應(yīng)用程序中用一個標識符來代表;一個與該存儲器相連的處理器,該處理器被配置成用該解釋程序來解釋執(zhí)行該第一應(yīng)用程序,用該通信器來與該終端通信。92.權(quán)利要求91的集成電路卡,其中,該標識符包含一個整數(shù)。93.一種用于集成電路卡和終端的方法,包含處理第二應(yīng)用程序以創(chuàng)建第一應(yīng)用程序,該第二應(yīng)用程序有一個字符串;在該第二應(yīng)用程序中用一個標識符來代表該第一應(yīng)用程序的字符串;在該集成電路卡的存儲器中存儲解釋程序和該第一應(yīng)用程序;用該集成電路卡的處理器來用解釋程序解釋執(zhí)行該第一應(yīng)用程序。94.權(quán)利要求93的方法,其中,該標識符包括一個整數(shù)。95.一種微控制器,包含一個存儲具有一個類文件格式的應(yīng)用程序和一個解釋程序的存儲器;一個與該存儲器相連的處理器,該處理器被配置成用該解釋程序解釋執(zhí)行該應(yīng)用程序。96.權(quán)利要求95的微控制器,進一步包含一個配置成與該終端通信的通信器。97.權(quán)利要求96的微控制器,其中,該終端有一個讀卡機,該通信器包含一個用于與該讀卡機通信的觸點。98.權(quán)利要求96的微控制器,其中,該終端有一個無線通信設(shè)備,該通信器有一個用于與該無線通信設(shè)備通信的無線收發(fā)機。99.權(quán)利要求96的微控制器,其中,該終端有一個無線通信設(shè)備,該通信器包含一個用于與該無線通信設(shè)備通信的無線發(fā)射機。100.權(quán)利要求95的微控制器,其中,該類文件格式包含一個Java類文件格式。101.一種用于集成電路卡和終端的方法,包含在該集成電路卡的存儲器中存儲第一應(yīng)用程序;在該集成電路卡的存儲器中存儲第二應(yīng)用程序;建立一個將該第一和該第二應(yīng)用程序隔離的防火墻,使得該第二應(yīng)用程序既不能訪問該第一應(yīng)用程序也不能訪問與該第一應(yīng)用程序關(guān)聯(lián)的數(shù)據(jù)。102.權(quán)利要求101的方法,其中,該第一和該第二應(yīng)用程序包含Java字節(jié)代碼。103.權(quán)利要求101的方法,其中,建立防火墻包括使用一個Java解釋程序。104.權(quán)利要求101的方法,其中,該第一應(yīng)用程序的存儲是與該集成電路卡的制造結(jié)合進行的;該第二應(yīng)用程序的存儲是在完成制造之后的晚些時間進行的。105.一種用于終端的集成電路卡,包含一個配置成與該終端通信的通信器;一個存儲應(yīng)用程序和一個解釋程序的存儲器,每個應(yīng)用程序都有一種高級程序設(shè)計語言格式;一個與該存儲器相連的處理器,該處理器被配置成a)用該解釋程序來解釋執(zhí)行該應(yīng)用程序;b)用該解釋程序來建立一個使該應(yīng)用程序彼此隔離的防火墻;c)用該通信器來與該終端通信。全文摘要一種用于終端的集成電路卡。集成電路卡包括一個存儲器,存儲器存儲解釋程序和具有高級程序設(shè)計語言格式的應(yīng)用程序。卡的處理器被配置成用解釋程序來解釋執(zhí)行應(yīng)用程序并用卡的通信器來與終端通信。文檔編號H04L29/08GK1242086SQ97181037公開日2000年1月19日申請日期1997年10月22日優(yōu)先權(quán)日1996年10月25日發(fā)明者T·J·維爾金森,S·B·古特賴,K·克里斯納,M·A·蒙特格梅賴申請人:施盧默格系統(tǒng)公司