




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第6章匯編語言程序設計6.1匯編語言語法6.2匯編語言程序設計6.3匯編程序及上機過程
6.4DOS及BIOS功能調用
6.5任務切換與混合語言編程6.1匯編語言語法6.1.1計算機程序設計語言的演變1.機器語言(MachineLanguage)
任何計算機實際上只能直接識別設計微處理器時所規(guī)定好的,一整套用“0”、“1”數(shù)字代碼表示的機器指令。這些機器指令的全體是指令系統(tǒng)。不同類型的CPU,其機器語言必然是不同的。這種直接用機器指令來編制計算機程序的方法就稱為機器語言程序設計。教學用的單板計算機一般都直接采用機器語言編程。這種直接用機器語言編程的方法難度大,閱讀、查錯和修改程序也很不方便。通常,只有當編程者對CPU指令系統(tǒng)比較熟悉,編寫的程序較短時,才有可能直接用機器語言來寫。人們?yōu)榱藬[脫編程中這種原始而低級的狀態(tài),就設法采用一組字母、數(shù)字或字符來代替機器指令,這樣就產生了匯編語言的概念和方法。2.匯編語言(AssemblyLanguage)和機器語言相比,使用匯編語言來編寫程序可以用助記符來表示指令的操作碼和操作數(shù),也可以用標號和符號來代替地址、常量和變量。但由于不同CPU的指令系統(tǒng)的指令編碼不同,因此與之相應的匯編語言亦不相同。由于這種符號化的語言使用了用英文字母縮寫表示的助記符,便于識別與記憶。另外,匯編程序還引入了新的匯編指令——偽指令和宏指令,使得采用匯編語言進行程序設計更為方便靈活。圖6.1匯編程序的“翻譯”作用3.高級語言(Highlevellanguage)低級語言編程方式阻礙了計算機在國民經(jīng)濟及日常生活中的推廣應用。隨著計算機科學的發(fā)展,軟件、硬件技術在相輔相成、相互支持中不斷改進與完善,逐步創(chuàng)造出許多適用于不同應用場合的計算機高級語言,如BASIC、FORTRAN、COBOL、PASCAL、FORTH、C語言等。這些高級的程序設計語言,使用了更接近于人們的自然語言(英語)和習慣的教學語言來描述算法的執(zhí)行過程,從而使編寫的程序更加直觀和簡練。這些高級語言通常都包含有各種函數(shù)計算、字符串處理、數(shù)據(jù)I/O等功能。所以程序的編寫、閱讀和修改變得相當容易掌握和使用。高級語言無論是面向問題或面向過程,一般總是獨立于具體機器的。程序員可不必了解機器的指令系統(tǒng)和內部的具體結構,而把精力集中在正確掌握語言的語法規(guī)則和算法的程序實現(xiàn)上。同樣,高級語言也必須借助于更強有力的翻譯系統(tǒng)——編譯程序(Compiler)才能將源程序轉換成相應的機器語言目標程序。與匯編程序不同,此處一條最簡單的高級語言語句,可能對應著一組機器指令。6.1.2為什么要用匯編語言編寫程序為什么還要學習和使用匯編語言呢?主要有以下幾點:(1)匯編語言非常接近機器語言程序,通過編制匯編語言程序,可以更清楚地了解計算機的工作過程。(2)現(xiàn)在的微機系統(tǒng)中,底層的一些功能仍然靠匯編語言程序來實現(xiàn)。(3)匯編語言程序的效率通常高于高級語言程序。6.1.3匯編語言的語句種類及其格式1.指令語句每一條指令語句在匯編時都要產生一個可供機器執(zhí)行的機器目標代碼,所以這種語句又叫可執(zhí)行語句。指令語句的格式如下:標號:(前綴指令)助記符(操作符);(注釋)(1)標號。這是一個任選字段。標號是指令語句的標識符,在語句之首,必須以“:”作為結束符。標號的組成規(guī)則如下:①必須由字母、數(shù)字(0,…,9)及特殊符號(?,·,@,-,$)組成,且必須以字母打頭。②字符總數(shù)限制在31個以內。③不能使用屬于系統(tǒng)專用保留字(Reservedword)。保留字主要有CPU中各寄存器名(如AX,CS);指令助記符(如MOV,ADD);偽指令(SEGMENT,DB);表達式中的運算符(如GE,EQ)和屬性操作符(如PTR,OFFSET,SEG等)。語句格式中帶()的項,是可有可無的項。如果有此項時,書寫時不能加()括號。在有些指令語句中,需要在助記符前加前綴指令(例如LOCK或REP),中間應用空格使兩者分開,如REPMOVSB。(2)指令助記符。這是為指令操作碼規(guī)定的符號。任何指令語句都需要此部分,它表示了指令語句的基本操作功能。如MOV是傳送指令的助記符,ADD是加法指令的助記符。(3)操作數(shù)。操作數(shù)可以根據(jù)指令的功能需要,可不帶操作數(shù),帶1個操作數(shù)或2個操作數(shù),若有兩個操作數(shù)時,中間用“,”號分開。例如,NOP;STD;INCSI;ADDBL,30H。而操作數(shù)與助記符之間必須以空格分隔。(4)注釋。注釋是為方便程序人員閱讀程序而加的說明。它既不影響源程序的匯編,也不會出現(xiàn)在目標程序中。通常并不要求每個匯編語句都應加注釋。6.1.4常數(shù)、標號、變量及表達式1.常數(shù)常數(shù)就是指令中出現(xiàn)的那些固定值,可以分為數(shù)值常數(shù)和字符串常數(shù)兩類。例如,立即數(shù)尋址時所用的立即數(shù),直接尋址時所用的地址,ASCII字符等都是常數(shù)。常數(shù)除了自身的值以外,沒有其它屬性的數(shù)值。在源程序中,數(shù)值常數(shù)按其基數(shù)的不同,可有二進制數(shù)、八進制數(shù)、十進制數(shù)、十六進制數(shù)等幾種不同的表示形式。匯編語句中用不同的后綴加以區(qū)別。①二進制數(shù):數(shù)字后面跟字母B。如:00101101B②八進制數(shù):用數(shù)字0~7表示,數(shù)字后跟字母Q或字母O。例如:177567Q(或177567O)263Q(或263O)③十進制數(shù):數(shù)字后跟字母D或不跟字母。例如:17893D(或17893)。④十六進制數(shù):十六進制數(shù)用0~9及A~F表示。后面跟字母H。如:B7H,2031H。還應指出,匯編語句中的數(shù)值常數(shù)的第一位必須是數(shù)字,否則匯編時將被看成是標識符。如常數(shù)B7H在語句中應寫成0B7H,F(xiàn)FH應寫成0FFH。字符串常數(shù)是由單引號‘’括起來的一串字符。例如:‘ABCDEFG’和‘179’。單引號內的字符在匯編時都以ASCII的代碼形式存放在存儲單元中。如上述兩字符串其ASCII代碼分別為41H、42H、43H、44H,…,4BH和31H、37H、39H。字符串最長允許有255個字符。2.標號標號是用符號表示的地址,稱為符號地址,用以指示此指令語句所在的地址。標號有3個屬性:段地址、偏移地址和類型。標號的段地址和偏移地址屬性是指標號對應的指令首字節(jié)所在的段地址和段內的偏移地址。標號的類型屬性有兩種:NEAR和FAR類型。標號如定義成NEAR類型,表示標號僅在本段內被引用;如定義成FAR類型,表示標號可以在段間使用。在轉移和調用指令中常將標號作為轉移目標地址使用。3.變量變量是與一個數(shù)據(jù)項的第一字節(jié)相對應的標識符,它表示該數(shù)據(jù)項第一字節(jié)在現(xiàn)行段中的偏移量。變量的值在程序運行期間可隨時修改。變量具有3個屬性: ①段地址(SEG):變量所在段的段地址; ②偏移地址(OFFSET):變量所在段內的偏移地址; ③類型(TYPE):變量的類型是所定義的每個變量所占據(jù)的字節(jié)數(shù)。在匯編語言中,變量是通過偽指令來定義的,其格式如下:變量名DB表達式;定義字節(jié)變量。變量名DW表達式;定義字變量。變量名DD表達式;定義雙字變量。變量名DQ表達式;定義長字變量。變量名DT表達式;定義一個十字節(jié)變量。上述偽指令的格式中的表達式可以有以下幾種情況:(1)一個或多個常數(shù)或某個運算公式(其值應為常數(shù))。當為多個常數(shù)或運算式時,其間用逗號隔開。在這種情況下,DB將給定常數(shù)定義為字節(jié)。DW將給定常數(shù)定義為字(兩個字節(jié)),并給它分配兩個存儲單元,低位字節(jié)數(shù)占低地址單元,高位字節(jié)數(shù)占高地址單元。DD將給定常數(shù)定義為雙字,分配4個存儲單元。同理,DQ則分配8個存儲單元,DT分配10個存儲單元。當定義的變量有幾個操作數(shù)時,則應從左到右由低地址向高地址順序排列所定義的常數(shù)。(2)帶引號的字符串。字符串必須用單引號括住,字符串的字符不超過255個。DB對每一個字符分配一個存儲單元,字符是由左向右按地址遞增的順序排列。例如KFDB‘ABC’;按41H、42H、43H的順序由低地址到高地址分配存儲地址。當操作數(shù)有多個字符串時,也是從左到右按地址遞增順序分配各字符串的存放單元。(3)用問號作為表達式。不帶引號的問號是一個保留字,它可用作數(shù)據(jù)類型偽指令DB、DW、DD語句中的表達式。用它告訴匯編程序,留出DB、DW、DD所分配的存儲單元,原先內存內容不改變。例如:SURDW?;預留一個字(二個字節(jié))。SUMDB?;預留一個字節(jié)。(4)帶DUP(重復方式)表達式。DUP是表達式中的一個操作符。此時表達式的格式為重復次數(shù)DUP(表達式)DUP操作符的后面為一個加圓括號的表達式。DUP表示的功能是把表達式重復預置,重復的次數(shù)由DUP前面的常數(shù)決定。例如:TABADB120DUP(0);分配120個字節(jié),并預置為零。TABBDW1000DUP(?);分配1000個字,不改變原先內容。TABCDB10DUP(′WELCOME′,0AH,0BH);表達式由一個字符串‘WELCOME’和兩個常數(shù)0AH,0BH組成,并重復預置;10次。還應指出,DUP可以重疊使用,例如:TABDDB2DUP(0,3DUP(1))DW100DUP(5DUP(5),38FBH)第一句是用DB定義的,表達式的外括號中的3DUP(1)表示把由DB定義的預置為1的字節(jié)數(shù)重復3次。這樣,2DUP(0,3DUP(1))=2DUP(0,1,1,1)。再根據(jù)定義,把(0,1,1,1)重復2次,這樣2DUP(0,3DUP(1))=0,1,1,1,0,1,1,1。整個語句的意思是:給命名為TABD的數(shù)組分配8個字節(jié)單元,并由低地址到高地址順序放置0,1,1,1,0,1,1,1。第二個語句中(5DUP(5),38FBH)=(5,5,5,5,5,38FBH)。然后再把括號內由6個元素組成的數(shù)組重復100次。(5)地址表達式(只能用于DW或DD)。操作數(shù)為地址表達式時,應遵循下列規(guī)則:①當用DW定義地址表達式時,地址表達式中的變量名稱表示該變量的第一個存儲單元的偏移地址,地址表達式中的標號表示它所代表的指令(或偽指令)的第一個字節(jié)的偏移地址。②當用DD定義地址表達式時,低位字用于預置偏移地址,高位字用于預置段地址,這些數(shù)值都是在定位時裝入的。③地址表達式中的變量或標號可與常數(shù)值相加減。對于變量來說,運算結果的類型不變;對標號來說,運算結果仍表示原標號所在段中的偏移地址。④變量或標號不能與變量或標號相加,但可相減,結果是沒有屬性的純數(shù)值。定義地址表達式舉例如下:A1DWVALUE;定義變量A1為VALUE的偏移地址。A2DWVALUE+5;定義變量A2為VALUE第6個字節(jié)的偏移地址。A3DWVALUE-3;定義變量A3為VALUE前3個字節(jié)的偏移地址。A4DDVALUE;高位字為VALUE所在段的段地址,低位字為VALUE的 偏移地址。定義變量的偽指令的功能是在變量名所對應的地址開始的內存區(qū)依次存入各項值。當同時有幾個變量定義語句時,將按照由上到下書寫順序,由低地址到高地址給每個變量語句中的表達式分配存儲單元。例如:DATA1DB20HDATA2DW0204H,100HDATA3DB(-1*3),(15/3)DATA4DD12345HDATA5DB′0123′DATA6DW′Ab′,′C′,′D′DATA7DB?DATA8DD?DATA9DB5DUP(00)
DATA10DW3DUP(?)圖6.2各變量在內存中分配的單元4.表達式(1)操作數(shù)。一個操作數(shù)在內容上可能代表一個數(shù)據(jù),也可能代表一個存儲單元的地址。對于數(shù)據(jù),最簡單的表達方式就是用常數(shù)形式表示,如20H,1234H,0FDH。匯編語言源程序中也常用標號來表示數(shù)據(jù),如可用PORTA表示一個端口地址號,而在源程序中應對PORTA作出定義,使它等于某個常數(shù)。在源程序中,存儲器地址常用標識符(也稱標號)來表示。如規(guī)范程序中常用START、MOVE、CLOSE作為標號。源程序中的地址標號常常作為轉移指令的轉移地址或調用指令的調用地址。這些標號所代表的具體的地址值應由段地址和偏移地址兩部分組成。(2)運算符。用一個運算符可以對一個或幾個操作數(shù)進行運算,構成一個表達式。源程序中表達式經(jīng)匯編后為一個值。匯編語言中有5類運算符,即①算術運算符(ArithmeticOperators);②邏輯運算符(LogicalOperators);③關系運算符(RelationalOperators);④分析運算符(AnalyticOperators);⑤綜合運算符(SyntheticOperators)。①算術運算符包括加(+)、減(-)、乘(*)、除(/)和取模運算(MOD)。取模運算是取兩數(shù)相除的余數(shù),但兩操作數(shù)必須為正整數(shù)。例如
82MOD16結果為2(相當于取低4位的值)。B5HMOD20H結果為21(相當于取低5位的值)。20HMOD7結果為4。②邏輯運算符。邏輯運算符包括與(AND)、或(OR)、非(NOT)和異或(XOR)。邏輯運算符又能對常數(shù)進行運算,所得的結果也是常數(shù)。兩數(shù)進行邏輯運算是兩數(shù)的對應位按位進行相應的邏輯運算。例如:11001100BAND11110000B;結果為11000000B。11001100BOR11110000B;結果為11111100B。 NOTFFH;結果為00H。11001100BXOR11110000B;結果為00111100B。
應注意的是,邏輯操作符和邏輯運算指令的操作助記符是相同的。只有當它們出現(xiàn)在指令的操作數(shù)部分時,匯編程序才將它看成是邏輯運算符。例如:ANDDX,PORTAAND0FEHAND操作助記符邏輯運算符③關系運算符。關系運算符有:相等EQ(Equal)、不等NE(NoEqual)、小于LT(LessThan)、大于GT(GreaterThan)、小于或等于LE(LessthanorEqual)、大于或等于GE(GreaterthanorEqual)。參加關系運算的兩個操作數(shù)必須都是操作數(shù)或者是同一段中的存儲單元地址,結果總是一個數(shù)值。當關系成立時,其結果為全1,當關系不成立時,其結果為全0。例如:MOVBX,PORTLT5表示如果PORT的值確實小于5,則匯編后得到的代碼等效于指令MOVBX,0FFFFH。如果PORT的值大于或等于5,等效于指令MOVBX,0。所以關系運算符一般不單獨使用,往往和邏輯運算符組合起來使用。例如:MOVBX,((PORTLT5)AND20)OR((PORTGE5)AND30)表示當PORT小于5時,上述指令等效于MOVBX,20當PORT大于或等于5時,上述指令等效于MOVBX,30④分析運算符和綜合運算符。利用分析運算符可以把一個存儲單元地址分解為段地址和偏移量。利用綜合運算符可以規(guī)定存儲單元的性質。ASM匯編語言的分析運算符有OFFSET、SEG、TYPE、SIZE和LENGTH。如表6.1所示。例如:MOVDX,OFFSETDATA1;取出標號DATA1的偏移量到DX中。MOVAX,SEGDATA1 ;取出DATA1的段地址送到DS中。MOVDS,AX
表6.1分析運算符表達式帶分析運算符的表達式表達式的意義OFFSET變量名或標號取出變量名或標號所在段的偏移地址SEG變量名或標號取出變量名或標號所在段的段地址TYPE變量名或標號取出變量名或標號的類型SIZE變量名取出變量的大小LENGTH變量名取出變量的長度類型TYPE運算符用來說明變量名或標號分配存儲單元的類型,如是字節(jié)分配類型,對應值為1;如是字分配類型,對應值為2;如是雙字分配類型,對應值為4。如表6.2所示。表6.2存儲單元分配類型和對應值存儲單元分配類型對應值字節(jié)1字2雙字4變量的類型是由偽指令DB、DW和DD來定義的。比如:
DATA3DB(-1*3),(15*3);定義DATA3為字節(jié)變量。
此時TYPEDATA3對應的值為1,以字節(jié)分配存儲單元。又如TABADB20DUP(?),那么TYPETABA也等于1。運算符LENGTH對于變量中使用DUP的情況,匯編程序將給出分配給該變量的單元數(shù)(分配單元可以以字節(jié)、字或雙字為單位計算),而對于其它情況則給出值1。例如:
DATA6DW′Ab′,′C′,′D′
此時LENGTHDATA6等于1。又如: ABCDW100DUP(?)此時LENGTHABC等于100。運算符SIZE用來計算一個變量存儲區(qū)所占用的字節(jié)數(shù)。同樣,以ABC變量為例,SIZEABC等于200,因它占用的字節(jié)為200(100個字)。由上可知,SIZE、LENGTH和TYPE之間有如下關系:SIZE=LENGTH*TYPEASM的綜合運算符有PTR和THIS。PTR用來對存儲單元規(guī)定類型。PRT運算符所表示操作數(shù)的格式為類型PTR表達式格式中的類型可以是:BYTE、WORD、DWORD、NEAR和FAR。前3個類型是變量類型,后兩個是標號類型。格式中的表達式可以是變量名、標號或其它地址表達式。PTR運算符的功能是用來重新定義已定義過的變量或標號的類型。例如:
MOVBYTEPTR[1000],0
此語句是用BYTE和PTR規(guī)定地址號為1000存儲單元為字節(jié)單元。所以執(zhí)行結果是將[1000]單元清零。如使用下列語句:
MOVWORDPRT[1000],0此語句是規(guī)定地址號1000存儲單元為字單元,所以執(zhí)行結果應將[1000]及[1001]兩單元清零。又如,若已定義DATA3是字變量,則程序中需將它作為字節(jié)變量使用時,必須用PTR來重新定義其類型??梢杂萌缦抡Z句:MOVBYTEPTRDATA3,AL
它的功能是將(AL)送至DATA3對應的一個字節(jié)中。應指出變量DATA3僅在此語句中臨時被定義成字節(jié)變量,DATA3原先定義的字變量類型沒有修改。THIS綜合運算符也可以用來改變存儲區(qū)的類型,稱類型指定運算符。THIS運算符的運算對象是類型(BYTE、WORD、DWORD)或距離(NEAR、FAR),用于規(guī)定所指變量或標號類型屬性或距離屬性。例如:
XYZEQUTHISBYTE此等價語句的功能是把字節(jié)類型BYTE屬性賦予變量XYZ。它等效于下述表達式:
BYTEPTRXYZTHIS可提高訪問標號的靈活性,如:FAROUTEQUTHISFAR此語句的功能是把段間距離屬性FAR賦予標號FAR-OUT。6.1.5偽指令1.方式偽指令(1).8086。在這條偽指令后,匯編程序將在8086/8088方式下操作,實際上這是微處理器的默認操作狀態(tài)。(2).386。在這條偽指令后,匯編程序將在80386方式下操作。如果想利用32位寄存器,必須加上這條偽指令。2.賦值偽指令EQU在匯編語言程序中,當某個表達式被多次引用時,常采用給這個表達式賦予一個名稱,這樣源程序中就可以以名稱代替表達式;另外常使用標號來代表數(shù)據(jù)、數(shù)據(jù)地址或程序地址。這種賦予表達式或數(shù)據(jù)/地址以名稱/標號的偽指令EQU有兩種格式,即①表達式名稱EQU表達式②新標號EQU老標號在①種格式中,表達式可以是常數(shù)或者地址表達式,例如:ABCEQU2000H;表示名稱ABC就是等價于數(shù)值2000H。XYZEQU[BP+5];名稱XYZ就代表地址表達式[BP+5]。ECONEQUE7HMOD10;ECON是代表取模運算后的余在②種格式中,可以對以前已經(jīng)賦過值的標號以新的標號,例如:
AADEQUPAR-3;新標號AAD等價于老標號PAR-3的值。COUNTEQUCX;使COUNT和寄存器CX具有相同的意義。如果有了上列語句,則指令語句MOVAL,AAD等價于MOVAL,PAR-3MOVAX,COUNT等價于MOVAX,CX3.定義變量偽指令前面已經(jīng)提及定義變量的偽指令,就是給變量分配存儲單元。這些偽指令是DB、DW、DD、DQ、DT。DB用來定義字節(jié),DW定義字,DD定義雙字,DQ定義4個字,DT定義10個字。這些偽指令的格式及用法見前述。
4.定義存儲單元類型的偽指令BYTE、WORD、DWORD定義存儲單元的偽指令并不是單獨使用,而是和指令結合起來使用的。利用這些偽指令,對存儲單元類型進行規(guī)定。例如:MOVBYTEPTR[DI],00MOVWORDPTR[1000],00INCBYTEPTR[DI]JMPDWORDPTR[2000]
5.LABEL本條偽指令用于定義標號名稱和屬性,它和下一條指令共享存儲器單元。格式: 名字LABEL類型例如:BYTE-ARRAYLABELBYTEWORD-ARRAYDW100DUP(?)在第二條語句中指明了有100個字存儲單元,它們的符號地址名為WORD-ARRAY,但在第一行說明這100個字存儲單元可以看成200個字節(jié)存儲單元。符號地址名為BYTE-ARRAY。這樣,當我們訪問存儲器操作時,就可以有兩種觀點:(1)MOVWORD-ARRAY,0;是把第一個字置為0。(2)MOVBYTE-ARRAY,0;是把第一個字節(jié)置為0。利用LABEL偽指令,對存儲器單元就可以有不同的劃分,這為訪問存儲器單元提供了較大的靈活性。
6.SEG和OFFSETSEG操作符返回存儲器地址操作數(shù)的段地址部分,而OFFSET返回存儲器地址操作數(shù)的段內偏移地址部分。例如:
…NUMBER-1DD?…MOVAX,SEGNUMBER-1MOVDS,AX ;段地址進入DS。MOVSI,OFFSETNUMBER-1;偏移地址進入SI。7.TYPE、SIZE和LENGTH表6.3存儲器地址操作數(shù)類型值存儲器操作數(shù)類型值(DB)字節(jié)數(shù)據(jù)1(DW)字數(shù)據(jù)2(DD)雙字數(shù)據(jù)4(DF)三字數(shù)據(jù)6(DQ)四字數(shù)據(jù)8(DT)五字數(shù)據(jù)10NEAR指令單元-1FAR指令單元12這里,字節(jié)、字等的類型就是它們所占用的字節(jié)數(shù),而NEAR和FAR指令單元的類型值沒有物理意義。SIZE和LENGTH只應用于存儲器地址操作數(shù)。LENGTH返回一個你定義的數(shù)的尺寸的單元數(shù)。SIZE則返回存儲器地址操作數(shù)占用的字節(jié)數(shù)。例如:LARGE-NUMDD40DUP(0)這里是按雙字尺寸分配存儲單元的,所以LENGTH(LARGE-NUM)是40,而SIZE(LARGE-NUM)是160??梢钥闯?,如果X是地址操作數(shù),則
SIZE(X)=(LENGTH(X))*(TYPE(X))8.段定義偽指令(1)SEGMENT/ENDS偽指令。偽指令SEGMENT和ENDS總是成對使用的。用這對偽指令來指定段的名稱和范圍,還可指明段的定位類型(aligntype)、組合類型(combinetype)和分類名。段定義偽指令的格式為
段名SEGMENT[定位類型][組合類型][分類名]…}本段程序內容(指令語句或偽指令語句)段名ENDS從SEGMENT偽指令之后出現(xiàn)的指令和偽指令都被認為是在該段之內,直至ENDS出現(xiàn)為止。段定義格式中,帶有‘[]’部分根據(jù)需要可有可無。還應指出,當用于定義數(shù)據(jù)段、附加數(shù)據(jù)段和堆棧段時,處于SEGMENT/ENDS偽指令中間的語句,只能包括偽指令語句,不能包括指令語句,一般格式為
段名SEGMENT…}數(shù)據(jù)定義,存儲單元分配等偽指令語句段名ENDS當由SEGMENT/ENDS定義代碼段時,中間的語句可包括指令語句和與指令有關的偽指令語句。一般格式為
段名SEGMENT…}指令語句和與偽指令有關的偽指令語句段名ENDS段定義格式中,各部分的用法說明如下:段名:所定義段的名稱。段名是標識符,同一段的SEGMENT/ENDS偽指令前的段名必須一致。一個段一經(jīng)定義,其中指令的標號、變量等在段內的偏移地址就已排定,它們都在同一個段地址控制之下,整個段占用的存儲空間大小也就確定。由SEGMENT/ENDS偽指令所定義的段,通常小于64K單元,而且經(jīng)過匯編和連接,定義的各段不互相覆蓋。一個源程序模塊的典型結構如下:STACK-SEGSEGMENT;STACK-SEGENDS;…定義堆棧段DATA-SEGSEGMENT;DATA-SEGENDS;EXTRA-SEGSEGMENT;EXTRA-SEGENDS;CODE-SEGSEGMENT;START:CODE-SEGENDS;ENDSTART;源程序模塊結束………定義數(shù)據(jù)段定義附加數(shù)據(jù)段定義代碼(即指令)段段定義格式中SEGMENT偽指令后,用‘[]’括起來的不是規(guī)定的語法符號,而是表示該項是可選的,有時可以全部省略。當它們存在時,用于指明段間的聯(lián)系形態(tài),說明段定義的輔助屬性?,F(xiàn)說明如下:①定位類型。定位類型給出實際段起點的類型。它有PAGE、PARA、WORD、BYTE四種類型。PAGE:表示相應的段必須從某一頁(256個字節(jié))的邊界開始。即段的起始地址能為256整除。此時20位的段地址為PAGE=××××××××××××00000000BPARA:表示段的起點是從存儲器中的某一個節(jié)(一節(jié)等于16個字節(jié))的邊界開始。也即段的起始地址能被16整除。此時20位的段起始地址為PARA=××××××××××××××××0000BWORD:表示段的起點可以從任何一個字的邊界(偶地址)開始。即地址能被2整除。段起始地址為WORD=×××××××××××××××××××0BBYTE:表示段的地址可以從存儲器的任何地址開始。段起始地址為BYTE=××××××××××××××××××××B對于PAGE和PARA類型其段內的偏移地址都是從0開始的。而對WORD類型,段內偏移地址不一定從0開始,合理選擇定位類型,能夠使得在進行段和模塊的定位連接時,可充分地利用存儲器空間。②組合類型。組合類型在模塊式程序設計中表示該段和其它同名段間的組合連接方法。如果在SEGMENT偽指令后面沒有指明組合類型,則匯編程序ASM認為這個段是不準備與別的段相連接的。組合類型有以下5種選擇:PUBLIC:表示該段可與模塊連接時所遇到的其它同名段在滿足定位類型的前提下依次連接起來。連接的順序由連接程序LINK確定。COMMON:表示該段與別的模塊中的所有其它同名同類別段共享相同的存儲空間。即各段都是從相同的地址開始,具有同樣的段地址,且互相覆蓋。連接后,段的長度等于最長的COMMON段的長度。AT表達式:表示相應段定位在由表達式求值得到的節(jié)邊界地址上。表達式也可以是一個常數(shù)。例如,AT2345H表示該段定位在實際物理地址23450H處。STACK:與PUBLIC組合類型的處理方式相同,即把不同模塊中帶有STACK組合類型的同名段連接起來,使這些同名段都從同一基地址開始。但STACK組合方式僅用于堆棧段。MEMORY:表示在連接時,本段應裝在被連接的其它段之上,即在同名段中具有最高的地址。若連接時具有MEMORY組合類型的段不止一個,則只有第一段才當成MEMORY組合類型來處理,其它的段將重疊,即按COMMON組合類型來處理。③類名。類名是程序員任選的一個字符串,使用時必須用單引號括起來‘類名’。連接時,將把不同模塊中相同‘類名’的各段在物理地址上相鄰的連接在一起,其順序則與LINK時提供的各模塊順序一致。(2)ORG偽指令。偽指令ORG用來規(guī)定目標程序存放單元的偏移量。它的格式如下:
ORG表達式其中表達式以65536(216)為模進行計算,計算結果應是一個不為負的常數(shù)。若表達式中有標識符,則標識符必須是已經(jīng)定義過的。匯編程序ASM規(guī)定ORG偽指令不能帶標識符。例如: START:ORG2000H是非法語句。如果在源程序中的第一條指令用了如下偽指令:ORG2000H,則匯編程序將把指令指針I(yè)P的值置成2000H,目標程序的第一個字節(jié)將放置在2000H單元,后面的程序就會依次順序存放。當遇上另一個ORG語句時,目標程序的存放地址才會從新的ORG語句指定的地址單元存放。例如,若當前的(IP)=2400H,這時若又遇到如下ORG語句:
ORG2464H則匯編程序會修改IP內容,使(IP)=2464H,并以此存儲單元開始存放目標程序。這樣就保留了100個字節(jié)的存儲空間。ORG偽指令可以放置在源程序中的任何位置。(3)ASSUME偽指令。ASSUME偽指令語句用來告訴匯編程序在指令執(zhí)行期間內存的哪一段是數(shù)據(jù)段,哪一段是堆棧段,哪一段是代碼段。ASSUME偽指令語句的格式如下:
ASSUME段寄存器名:段名符[,段寄存器名:段名符,…]上述格式中[]內的內容可有可無。例如:
ASSUMECS:MYCODE,DS:MYDATAASSUMEES:MYEXTRA,SS:MYSTACK這兩個語句是將所定義的段MYCODE、MYDATA、MYEXTRA和MYSTACK分別置于段寄存器CS、DS、ES和SS的控制之下。ASSUME語句只能安排在代碼段內,一般應排在代碼段作為首始指令。ASSUME語句中的‘段寄存器名:段名符’可以有一項,也可以有多項,如果一行寫不下,可分成兩個ASSUME語句。一個源程序模式至少包括一個段,當指令(即代碼)、數(shù)據(jù)及堆棧區(qū)都將集中在一個段內時,ASSUME語句的格式應該是為
ASSUMECS:MYCODE,DS:MYCODE,ES:MYCODE,SS:YCODE除了CS以外,各個段寄存器的實際值,還要用MOV指令來賦值。例如:…
MYCODESEGMENTASSUMECS:MYCOED,DS:MYDATA,ES:MYEXTRA,SS:MYSTACKSTART:MOVAX,MYDATAMOVDS,AXMOVAX,MYEXTRAMOVES,AXMOVAX,MYSTACKMOVSS,AX…MYCODEENDS …
9.過程定義偽指令PROC,ENDP,NEAR,F(xiàn)AR在ASM語言中,過程的含義和子程序是一樣的。一個過程可以被其它程序所調用,它的最后一條指令總是返回指令,用以控制此過程在執(zhí)行完畢后,返回到主程序。定義過程的偽指令PROC/ENDP總是成對出現(xiàn)的,在這兩條偽指令間的內容就作為一個過程,即一個子程序。有關PROC/ENDP偽指令的格式定義在第4章中已作了介紹,現(xiàn)僅舉例說明PROC/ENDP等一組偽指令的用法。下面是實現(xiàn)多字節(jié)BCD碼相加的完整的程序片段:DATASEGMENT;定義數(shù)據(jù)段。FIRSTDB11,22,33,44;第一個加數(shù)。SECONDDB55,66,77,88;第二個加數(shù)。SUMDB4DUP(?);存放結果單元。DATAENDSSTACKSEGMENT;定義堆棧段。STADB20DUP(?);設置堆棧長度為20個字節(jié)。TOPEQULENGTHSTASTACKENDSCODESEGMENT;定義代碼段。ASSUMECS:CODE,DS:DATA,SS:STACKSTART:MOVAX,DATA;裝入段寄存器實際值數(shù)據(jù)。 MOVDS,AX MOVAX,STACK;裝入段寄存器實際值堆棧。 MOVSS,AX MOVAX,TOP ;設置堆棧指針。 MOVSP,AX MOVSI,OFFSETFIRST;SI指向第一個加數(shù)。 MOVDI,OFFSETSUM;DI指向結果單元。 MOVBX,OFFSETSECOND;BX指向第二加數(shù)。 MOVCX,04 ;共4個字節(jié)長。 CLD ;清方向標志。 CLC ;清進位標志。ADITI:CALLAAA;調用多字節(jié)加法子程序。 LOOPADITI… ;繼續(xù)后面主程序?!瑼AA1PROCNEAR;單字節(jié)加法子程序。LODSB;取第一個加數(shù)。ADCAL,[BX];相加。DAA;十進制調整。STOSB;結果送DI所指單元。INCBX;修改指針。RET;返回。AAAENDP;子程序結束。CODEENDS;程序段結束。ENDSTART;程序結束。10.定義結構的偽指令STRUC/ENDS(1)結構的定義。結構偽指令的格式如下:
結構名稱STRUC…結構名稱ENDS
如果DB、DW或DD語句包括變量標識符,則該標識符表示一個字段的開始,稱為字段標識符。例如,對上述所說的學生學業(yè)管理可采用以下所示的結構形式:由DB、DW、DD偽指令所組成的語句序列STUDENT-RECORDSTRUCNAMEDB′LiPing′SEXDB0,0formale,1forfemaleAGEDB25HNUMBERDB′??????′MATHDB91HPHYSICALDB85HCIRCUITDB95H…STUDENT-RECORDENDS(2)結構的存儲分配和預置。為了給結構分配存儲空間或預置,必須有一個援用該結構的語句,其格式如下: 變量結構名稱〈賦值說明〉其中結構名稱是指STRUC偽指令中的結構名稱(在前面的例子中為STUDENT-RECORD),變量與結構的起始點相對應,另外變量名要與字段標識符一起使用方可訪問結構中的各個字段(對上述的例子,變量名可用所管理的學生名表示,也可以用其它方法為變量命名)。賦值說明必須寫在尖括號‘〈〉’內,它由一系列常數(shù)表達式組成,一個字段一個表達式,由逗號分開;如果某個字段有某n個字段使用結構定義中的預賦值,則相應的表達式可省缺,但應保留逗號;如果全部表達式都省缺,則只要寫一對尖括號;如果省缺的是最后面的一些字段,則可以省去逗號。此外,對字符串常量所表示的字段要替換的話,若替換的字符長度大于原來形式參數(shù)的長度,匯編程序將自動截去多出的字符;若替換字符長度小,則用最后的那個字符填滿剩余的存儲空間。例如,對上述的例子援用語句可以是:LiPingSTUDENT-RECORD〈,,,′891011′〉LuiYiSTUDENT-RECORD〈′LuiYi′,1,′891011′,80H〉(3)對結構的訪問。通過援用語句對結構進行存儲空間分配和預置之后,結構及其字段就以變量的形式出現(xiàn),可以像使用其它變量一樣使用。但對結構的訪問必須用變量路徑名的方法進行,路徑名的格式為變量名·字段名例如,對于前面的例子,若需要將學生A的年齡傳送到寄存器AL,則可以使用下列指令語句:
MOVAL,LiPing·AGE如果BX中存有變量LiPing的偏移地址,則下列語句與上述語句是等效的:MOVAL,[BX]·AGE11.IFELSEENDIF條件匯編偽指令MASM提供了功能強大的條件匯編偽指令,使用它的一般格式是:IF ;如果條件成立…[ELSE];[否則]…ENDIF;結束條件匯編語句其中IF有多種形式,它們是:IF操作數(shù);如果操作數(shù)不等于0時。IFE操作數(shù);如果操作數(shù)等于0時。IFDEF標號或變量;如果標號或變量已被定義時。IFNDEF標號或變量;如果標號或變量還沒被定義時。IFB〈變量〉;如果變量為空時。IFNB〈變量〉 ;如果變量不為空時。IFIDN〈操作數(shù)1〉,〈操作數(shù)2〉;如果〈操作數(shù)1〉等于〈操作數(shù)2〉時。IFDIF〈操作數(shù)1〉,〈操作數(shù)2〉;如果〈操作數(shù)1〉不等于〈操作數(shù)2〉時。IF1 ;如果匯編程序在第一遍掃描時。IF2 ;如果匯編程序在第二遍掃描時。在IF的形式中,尖括號“〈〉”中內容是必需的。
12.邏輯運算偽指令AND、OR、XOR、NOT按位操作,運算規(guī)則與它們作為指令時一樣,但只能用于算術表達式中。與指令AND、OR、XOR、NOT區(qū)別如下:作為指令時它們用在最前面,且目的操作數(shù)必須為寄存器或存儲器操作數(shù);作為偽指令時它們用在數(shù)學表達式中,操作數(shù)在它們的兩邊,可以都是立即數(shù)。例如:
ANDAX,CX ;AND作為指令。MOVAX,OFEHAND145H;AND作為偽指令。ANDDX,CXANDOFA4CH;第一個作為指令,第二個是偽指令。
13.訪問外部標識符的偽指令EXTRN、PUBLIC當把若干個模塊連接在一起時,必須解決其中的任一模塊能夠引用其它模塊中的某些變量或標號的問題,這里引入的定義訪問外部標識偽指令EXTRN和PUBLIC就是提供解決這個問題的方法。如果一個標識符只在一個模塊中定義過,那么就說它相對這個模塊是一個內部標識符或局部標識符;如果一個標識符在其模塊內未定義過,而是在其它模塊中定義,那么它就被稱為相對該模塊的外部標識符。對于只產生一個單一目標模塊的匯編語言程序,它所訪問的所有標識符必須是局部定義的,對于多模塊程序來說,必須給匯編程序一個信息以說明其間的有些標識符是外部的,而不致被匯編程序把它們處理為一些無效的標識符。此外,為了允許其它模塊訪問一給定模塊中的標識符,該給定模塊必須包含一個標識符清單以說明其中的標識符可為其它模塊訪問。因此,每個模塊可含有兩個清單:一個清單標明它所要訪問的其它模塊的標識符;另一個清單是列出它所定義的,且為其它模塊所訪問的標識符。這兩個清單依靠偽指令EXTRN和PUBLIC列出。EXTRN和PUBLIC偽指令語句的格式如下:EXTRN標識符:類型,…,標識符:類型PUBLIC標識符,…,標識符EXTRN偽指令語句中的標識符表示是外部的變量或標號,而PUBLIC偽指令語句中的標識符表示可供其它模塊引用的變量或標號。在EXTRN偽指令中,若標識符為標號,則類型有NEAR或FAR;若標識符為變量,則類型有BYTE,WORD或DWORD。在語句INCVAR1中,若VAR1是外部變量,且對應于一個字,則含有該語句的模塊中就必須有如下所示的一條偽指令語句:EXTRN…,VAR1:WORD,…而在定義VAR1模塊中就必須含有下列語句:PUBLIC,…,VAR1,…
14.源程序結束偽指令END偽指令END用來表明END語句處是源程序的終結。其格式如下:END表達式這里的表達式通常就是程序第一條指令的語句標號。這樣,程序在匯編、連接后,將目標代碼裝入內存之后準備要執(zhí)行的起始地址由此標號所決定。當然,這個表達式也可以省去。下面是一個完整的源程序片斷,從中可以看出END偽指令的用法:DATASEGSEGMENTVAR1DW7654HVAR2DW2345HRESULTDW?DATA-SEGENDSCODE-SEGSEGMENTASSUMECS:CODESEG,DS:DATA-SEGSTART:MOVAX,DATA-SEGMOVDS,AXMOVAX,VAR1SUBAX,VAR2MOVRESULT,AXCODE-SEGENDSENDSTART15.常用偽指令列表表6.4MASM偽操作符表續(xù)表續(xù)表續(xù)表續(xù)表續(xù)表續(xù)表續(xù)表續(xù)表續(xù)表續(xù)表6.1.6宏指令及其使用1.宏指令、宏定義和宏調用宏指令是源程序中具有獨立功能的一段程序代碼。它可以根據(jù)用戶的需要,由用戶自己在源程序中定義。宏指令一經(jīng)定義,便可在以后的程序中多次調用。宏定義由MASM宏匯編程序提供的偽指令實現(xiàn),格式為宏指令名MACRO〈形式參數(shù)〉;…;ENDM宏體其中MACRO和ENDM均為偽指令,它們必須成對出現(xiàn)在源程序中,且必須以MACRO作為宏定義的開頭,而以ENDM作為宏定義的結尾。MACRO和ENDM之間為宏體,是實現(xiàn)宏指令功能的實體。宏指令名(Macroname)是為宏指令起的名字,以供在源程序中調用該宏指令時用。形式參數(shù)(也稱虛擬參數(shù))的設置增強了宏指令的功能,使其更加靈活。形式參數(shù)的設置可根據(jù)需要而定,可用一個或多個(最多不超過132個),也可以沒有。當有多個形式參數(shù)時,參數(shù)之間必須以逗號隔開。宏調用的格式為宏指令名〈實際參數(shù)〉例6.1設有如下4個宏定義:PUSHREGMACROPUSHAXPUSHBXPUSHCXPUSHDXPUSHSIPUSHDIENDM顯而易見,這是一個無形式參數(shù)的宏定義。LOADWMACROPR,VAR MOVPR,VAR MOVAX,[PR] ENDM該宏定義有2個形式參數(shù),它們都在操作數(shù)域,互相之間必須用逗號分開。SHIFTMACRON,REG,CCMOVCL,NS&CCREG,CLENDM根據(jù)以上宏定義,若需編一段程序,將某變量WVAR內容送AX寄存器,右移4位后,再存入WVAR變量處,則可采用宏調用方法編寫如下程序段:LOADWSI,WVARSHIFT4,AX,ARSAVEWSI,AX,INC……相應的宏展開如下:
LOADWSI,WVAR+MOVSI,WVAR+MOVAX,[SI]SHIFT4,AX,AR+MOVCL,4+SARAX,CLSAVEWSI,AX,INC+MOV[SI],AX+INCSI……宏展開時,匯編程序在所展開的指令前加“+”,以便與其它指令區(qū)別。上述宏展開中LOADWSI,WVAR語句、SHIFT4,AX,AR語句及SAVEWSI,AX,INC語句是為程序閱讀方便而提供的,不占內存單元。又若需將變量FIRST的內容取入BX,左移4位后再存入FIRST變量處,則有如下程序段:LOADWDI,FIRSTMOVBX,AXSHIFT4,BX,ALSAVEWDI,BX,INC……宏展開后程序段如下:
+LOADWDI,FIRST+MOV DI,FIRST+MOV AX,[DI]MOV BX,AXSHIFT 4,BX,AL+MOV CL,4+SAL BX,CL+SAVEWDI,BX,INC+MOV DI],BX+INC DI……2.宏嵌套宏定義中允許使用宏調用,但所調用的宏指令必須先定義過。不僅如此,宏定義中還可以包含宏定義。例6.2設計一個程序段實現(xiàn)下列運算:FIRST1*FIRST2+SECOND1*SECOND2并將結果存儲起來(不考慮最后結果溢出)。MULTIPLYMACROOPR1,OPR2,RESULT MOVAL,OPR1 IMULOPR2 MOVRESULT,AX ENDMADDMULTMACROREG,VAR1,VAR2 MULTIPLYFIRST1,FIRST2,MULT1 MULTIPLYSECOND1,SECOND2,MULT2 MOVREG,VAR1 ADDREG,VAR2 MOVSUM,REG ENDM
可以看出,在ADDMULT宏定義中兩次調用了定義過的宏指令MULTIPLY。若有宏調用:ADDMULTAX,MULT1,MULT2則宏展開后的程序段如下:
MULTIPLYFIRST1,FIRST2,MULT1+MOV AL,FIRST1+IMULFIRST2+MOVMULT1,AXMULTIPLYSECOND1,SECOND2,MULT2+MOVAL,SECOND1+IMULSECOND2+MOVMULT2,AXADDMULTAX,MULT1,MULT2+MOVAX,MULT1+ADDAX,MULT2+MOVSUM,AX……例6.3采用宏定義體內包含宏定義的方法設計一個運算宏指令。宏定義:DEFCALCUMACROCALCULATION,OPERATORCALCULATIONMACROX,Y,Z PUSHAX MOVAX,X OPERATORAX,Y MOVZ,AX POPAX ENDM ENDMDEFCALCU宏指令定義體內包含了一個宏定義CALCULATION。并且,內層宏定義的宏指令名CALCULATION又是外層宏定義的形式參數(shù)。由于CALCULATION宏指令的定義包含在DEFCALCU宏指令的定義體內,要調用CALCULATION宏指令,必須先調用DEFCALCU宏指令,以便使CALCULATION宏指令先得到定義,即需按如下步驟進行:宏調用DEFCALCUADDITION,ADD宏展開+ADDITIONMACROX,Y,Z PUSHAXMOVAX,XADDAX,YMOVZ,AXPOPAXENDM
得到宏指令ADDITION的宏定義。這樣便可有宏調用:ADDITIONFIRST,SECOND,SUM并有宏展開:+PUSHAX+MOVAX,FIRST+ADDAX,SECOND+MOVSUM,AX+POPAX對于宏指令DEFCALCU宏定義體中的形式參數(shù)CALCULATION及OPERATOR給予不同的實際參數(shù)去取代,便會得到不同的運算宏指令,如宏調用
DEFCALCUSUBTRACT,SUB可形成減法的宏定義;宏調用
DEFCALCULOGAND,AND可形成邏輯與的宏定義等。
3.宏定義中的標號與變量如果宏定義體中出現(xiàn)標號或變量,該宏指令又需要被多次調用,這樣宏展開后程序中將會多次重復出現(xiàn)相同的標號或變量,也就是說會產生重復定義標號或變量的錯誤,這是不允許的。MASM宏匯編程序解決這一問題的方法是在宏定義中用偽指令LOCAL把要出現(xiàn)在宏體中的標號或變量定義成局部標號或變量。LOCAL偽指令定義局部標號或變量的格式為LOCAL參數(shù)表其中參數(shù)表是指宏體中要用到的標號或變量。該
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 湖北省鄂州市華容區(qū)2024-2025學年數(shù)學三下期末質量跟蹤監(jiān)視試題含解析
- 哈爾濱工業(yè)大學《鋼琴即興伴奏(一)》2023-2024學年第二學期期末試卷
- 邯鄲應用技術職業(yè)學院《給排水施工與監(jiān)理》2023-2024學年第二學期期末試卷
- 佳木斯職業(yè)學院《馬克思主義哲學原著》2023-2024學年第二學期期末試卷
- 湖南益陽箴言中學2024-2025學年普通高中畢業(yè)班單科質量檢查語文試題含解析
- 山東省2025屆高三下學期診斷性考試化學試題含解析
- 河海大學《發(fā)酵食品工藝學》2023-2024學年第一學期期末試卷
- 湖南理工職業(yè)技術學院《土木工程檢測技術》2023-2024學年第二學期期末試卷
- ??诮?jīng)濟學院《病原生物學與免疫學實驗(微免)》2023-2024學年第二學期期末試卷
- 溶栓病人高血壓管理
- 湖南水泥倉施工方案
- 2025年中國人壽招聘筆試筆試參考題庫附帶答案詳解
- 2024-2025學年高中化學上學期第十四周 化學反應速率教學實錄
- 2025年初中地理中考押題卷(含解析)
- 老人預防電信詐騙
- 2024年11月-礦山隱蔽致災因素普查
- 【2025新教材】教科版一年級科學下冊全冊教案【含反思】
- 《經(jīng)濟學原理》課件
- 第16課《有為有不為 》課件-2024-2025學年統(tǒng)編版語文七年級下冊
- 火鍋店創(chuàng)業(yè)計劃書:營銷策略
- 交通大數(shù)據(jù)分析-深度研究
評論
0/150
提交評論