第4章----匯編與C混合程序設計(共40頁)_第1頁
第4章----匯編與C混合程序設計(共40頁)_第2頁
第4章----匯編與C混合程序設計(共40頁)_第3頁
第4章----匯編與C混合程序設計(共40頁)_第4頁
第4章----匯編與C混合程序設計(共40頁)_第5頁
已閱讀5頁,還剩36頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1、精選優(yōu)質(zhì)文檔-傾情為你奉上第4章匯編語言程序設計匯編語言是以處理機指令系統(tǒng)為基礎面向機器的語言。用匯編語言編寫程序的主要優(yōu)點是程序設計人員可以直接對存儲器、CPU內(nèi)部寄存器和輸入/輸出端口編程,程序效率高,執(zhí)行速度快;匯編語言源程序比高級語言源程序生成的目標代碼短,占用存儲空間少,因而在對于程序空間和時間要求很高的場合,如系統(tǒng)軟件設計、實時控制系統(tǒng)和I/O接口驅(qū)動程序的設計中,匯編語言的作用是不可代替的,至于對很多需要直接控制硬件的場合,匯編語言的作用更是必不可少的。但是匯編語言要求程序員了解計算機的硬件,并對計算機的指令系統(tǒng)比較熟悉;另外不同的處理器有不同指令系統(tǒng),故不同機器之間匯編語言程序

2、難以移植,這些也限制了匯編語言的應用范圍。匯編語言的源程序是不能直接運行的,要用匯編程序?qū)υ闯绦蜻M行匯編,翻譯成機器語言目標程序,再連接形成可執(zhí)行的程序,才能交付計算機執(zhí)行。匯編程序是實現(xiàn)把匯編語言源程序翻譯成目標程序的一種系統(tǒng)軟件。匯編語言源程序是由匯編指令、匯編偽指令等按照規(guī)定的語法規(guī)則編寫的。本章介紹了匯編語言程序的編程格式、基本的匯編語言偽指令,并以分支程序、循環(huán)程序、子程序和DOS系統(tǒng)功能調(diào)用為例,論述匯編語言的基本程序設計方法,還介紹了匯編語言與C語言的混合編程方法,最后給出了匯編語言程序上機過程。本章的重點是掌握匯編語言程序的基本設計方法,正確使用程序結構及常用偽指令,掌握分支、

3、循環(huán)、子程序的設計方法和DOS功能調(diào)用。本章的難點是正確理解和掌握偽指令的應用以及子程序的設計。41匯編語言源程序的語句類型80X86宏匯編語言有兩種基本語句:指令語句和指示語句(偽指令語句)。指令語句是可執(zhí)行語句,它要求CPU執(zhí)行某種操作。在匯編時產(chǎn)生一一對應的機器目標代碼。指令語句的格式為:標號: 指令助記符操作數(shù);注釋一條指令可以由4個字段組成,其中,方括號內(nèi)的字段為可選項。指令語句的詳細說明見3.1節(jié)。指示語句又稱偽指令或偽操作。偽指令是不可執(zhí)行語句,它只是在源程序匯編期間給匯編程序提供匯編信息,如指示匯編程序為數(shù)據(jù)分配內(nèi)存空間、或者提供段定義的信息等,不產(chǎn)生任何機器代碼,偽指令與機器

4、指令無關。偽指令的格式為:符號名 偽指令定義符參數(shù)表;注釋本章的4.2節(jié)將介紹80X86的常用偽指令。42 80X86匯編語言的數(shù)據(jù)和表達式匯編語言程序的語句,是按照匯編語言的基本語法書寫的,匯編語言語句中的數(shù)據(jù)、表達式和運算符也是指令的一個重要組成部分,數(shù)據(jù)、表達式和運算符的格式對指令有很大的影響。下面對此加以討論。421常量1.常量的類型常量是匯編時已確定的值,在程序運行中,常量的值不會改變。例如,立即尋址時所用的立即數(shù),直接尋址時所用的地址等都是常量。常量有兩種類型:數(shù)值型常量和字符串型常量。(1) 數(shù)值型常量二進制數(shù):以字母B結尾,例如:B。十進制數(shù):以字母D結尾(或省略),例如:38

5、76,3421D。八進制數(shù):以字母Q或O結尾,例如:765Q、321O。十六進制數(shù):以字母H結尾,由09,AF所組成,為了避免與字母開頭的標識符相混淆,匯編語言規(guī)定,凡是以字母AF開頭的十六進制數(shù),必須在字母前加上數(shù)字0。例如:89ABH、0FFB0H等。(2) 字符串常量字符串常量是用單引號或雙引號括起來的一個或多個字符串,如ABC或“ABC”等,字符在機器內(nèi)是以ASCII碼存放,例如,B在內(nèi)存中為42H。常量可以用數(shù)值形式直接寫在匯編語言語句中,也可以預先為它定義一個名字,供程序員編程時直接引用。2.常量或表達式賦值偽指令對于程序中多次出現(xiàn)的同一個常量或表達式可以用表達式賦值偽指令給表達式

6、賦予一個新的符號,此后,程序中凡是需要用到該表達式之處就可以用這個符號名來代替了,從而給程序設計帶來很大的方便和靈活性。(1) 等值偽指令(EQU)格式:符號名 EQU 表達式功能:將表達式的值賦給符號名。例41CONT EQU 128;定義常數(shù)CONT=128 NUM EQUALPH+8 ;定義表達式NUM等于表達式的值 ADDR EQUDS:EBP+4;加段前綴的變址尋址賦以符號名ADDR 等值偽指令在匯編時不產(chǎn)生任何目標代碼,也不占用存儲單元。但在同一個程序中,不能對已定義的符號重新定義。 (2)等號偽指令格式:符號名= 表達式功能:將表達式的值賦給符號名。例42COUNT=20HABC

7、=3.ABC=ABC+6COUNT=COUNT+10H等號語句與EQU語句有同樣的功能,區(qū)別在于在同一源程序中,EQU語句不允許對符號重新定義,而等號語句允許對符號多次定義。422 變量變量用來定義存放在存儲單元中的數(shù)據(jù),變量名是存放數(shù)據(jù)的存儲單元的地址,變量的值為對應存儲單元的內(nèi)容。與常量不同的是變量的值可以在程序的運行過程中隨時修改。1變量的屬性變量有三種屬性:(1)段屬性(SEG)段屬性是指所在段的段基址,它通常放在DS、ES、SS段寄存器中。 (2)偏移屬性(OFFSET),指變量所在段中的偏移地址,即變量所在的地址與段基址之間的字節(jié)數(shù)。 (3)類型屬性(TYPE),指變量占用存儲單元

8、的字節(jié)數(shù)。若占用一個字節(jié),稱為字節(jié)變量,其類型為BYTE;若占用兩個字節(jié),稱為字變量,其類型為WORD;若占用四個字節(jié),稱為雙字變量,其類型為DWORD;此外還有六字節(jié)、八字節(jié)和十字節(jié)變量,它們分別占用3個字存儲單元、4個字存儲單元和5個字存儲單元,其類型為FWORD、QWORD和TBYTE。2變量定義偽指令變量定義偽指令是為數(shù)據(jù)分配存儲單元,并給這個存儲單元取一個名字,即變量名。格式:變量名DB/DW/DD/DF/DQ/DT表達式1,表達式2,功能:為變量分配1個字節(jié)/字/雙字/長字/4字/10字節(jié)存儲單元,表達式可以是數(shù)值表達式、地址表達式、字符串、?、用逗號隔開的上述各項或n DUP(表

9、達式)。(1) 數(shù)值變量定義語句例4.3 NUMDB100,45H;將64H,45H賦給字節(jié)變量NUMSUMDW3456H;將3456H賦給字變量SUMTOTALDDH;將賦給雙字變量TOTAL變量NUM、SUM和TOTAL在存儲單元中的存放格式如圖4.1所示。數(shù)據(jù)存放時低字節(jié)存放在低地址,高字節(jié)存放在高地址。(2) 字符串變量定義語句定義字符串變量可以用DB偽指令,它為字符串中每個字符分配一個字節(jié)存儲單 元,在存儲單元中存放的是字符的ASCII碼。DW偽指令也可以定義字符串變量,即給兩個字符組成的字符串分配兩個字節(jié)存儲單元。例4.4ABCDBABCDEF ;將字符串賦給變量ABCDATEDW

10、AB,CD ;給AB,CD字符串各分配兩個節(jié)存儲單元。變量ABC、DATE在存儲單元中的存放格式如圖4.2所示。低地址低地址NUM 64 ABCA 45 BSUM 56 C 34 DTOTAL 55E 44F 33DATE B 22A高地址DC高地址圖4.1 數(shù)值變量存儲格式圖4.2 字符串變量存儲格式(3)?偽指令 ?語句也是為數(shù)據(jù)項分配存儲單元,但是存儲單元中不預置確定的值,常用來預留存儲單元。例4.5FIRSTDB?;分配一個字節(jié)單元SECONDDW?,?,?;分配三個字單元(4)重復數(shù)據(jù)定義偽指令(DUP) DUP(Duplication)是重復數(shù)據(jù)定義操作,用帶DUP的表達式可以為若

11、干重復數(shù)據(jù)分配存儲單元,DUP表達式也可以嵌套。例4.6D1DB5 DUP(0);定義D1為5個全為0的字節(jié)單元 D2DW10 DUP(22AAH);定義D2為10個全為22AAH的字單元 D3DD20DUP(?);定義D3為20個預留的雙字單元 D4DB3 DUP(10H,2DUP(80H);定義D4為(10H,80H,80H)重復3次共9個字節(jié)。423標號標號是可執(zhí)行語句的符號地址。用來表示指令在存儲器中的位置,標號可作為轉(zhuǎn)移指令的目標操作數(shù),以決定轉(zhuǎn)移指令的目標地址。標號之后必需有一個冒號(:),標號也可以單獨占一行。1標號的屬性:(1)段屬性(SEG),段屬性是指標號所在段的段基址,它

12、通常放在DS、ES、SS段寄存器中。 (2)偏移屬性(OFFSET)。指標號所在段中的偏移地址,即標號所在的地址與段基址之間的字節(jié)數(shù)。 (3)類型屬性或距離屬性(TYPE),用來說明該標號是段內(nèi)引用還是段間引用。段內(nèi)引用時為NEAR屬性,指針占2個字節(jié);段間引用時為FAR屬性,指針占4個字節(jié)。 標號的距離屬性可以用LABEL偽指令加以改變。2用LABEL偽指令定義標號的類型屬性LABEL偽指令為當前存儲單元定義一個指定類型的變量或標號。如果LABEL定義的是變量,其類型可以是BYTE、WORD或DWORD;如果定義的是標號,其類型可以是NEAR或FAR,隱含的類型為NEAR。語句格式如下:變量

13、名或標號 LABEL類型(1) 與變量連用LABEL與變量連用,用來給下一條語句中的變量取一個新的名字,并可重新定義它的類型。例4.7 B-ARRAYLABELBYTEW-ARRAYDW50DUP(?) 這兩條語句給100個字節(jié)的數(shù)組定義了兩個不同類型的變量名:字節(jié)類型變量B-ARRAY和字類型變量W-ARRAY。這樣在后續(xù)的語句中,如果以字類型訪問該變量,應使用字變量名,即W-ARRAY;若以字節(jié)類型訪問該變量,應使用字節(jié)變量名,即B-ARRAY。例如: MOVW-ARRAY+2,0;把該數(shù)組的第3、第4個字節(jié)置0MOVB-ARRAY+2,0;把該數(shù)組的第3個字節(jié)置0定義堆棧時,LABEL語

14、句也經(jīng)常用到。例4.8STACKSEGMENTDW30 DUP(?)TOP LABELWORDSTACKENDS這里定義了一個由30個字組成的堆棧,棧底取名為TOP,其類型定義為字。(2) 與標號連用LABEL與標號連用時用來給指令地址定義一個新的標號,并可改變其類型屬性。例4.9DISTFARLABELFARDISTNEAR:MOVAX,BX+SI 這里第二條語句用冒號隱含定義了DISTNEAR為NEAR屬性,第一條LABEL語句給第二條語句的標號取一個新的標號名DISTFAR,并將屬性改為FAR。DISTFAR和DISTNEAR有相同的邏輯地址,但它們的類型屬性不同,可作為程序轉(zhuǎn)移或調(diào)用時

15、不同情況下的入口。當在段內(nèi)轉(zhuǎn)移時用,可使用標號名DISTNEAR,在段間轉(zhuǎn)移時用,可使用標號名DISTFAR,但實際上是指向同一條指令。424表達式表達式是由常量、變量、寄存器、標號以及連接它們的運算符組成。表達式的運算是在匯編時由匯編程序完成的,表達式的運算的結果作為操作數(shù)參加指令規(guī)定的操作。MASM宏匯編允許使用的表達式有兩種類型:數(shù)值型表達式和地址表達式。1.數(shù)值表達式 數(shù)值表達式的結果是數(shù)值。例如:MOVAX,(NUM*6+10H)/5指令中源操作數(shù)是一個表達式,其運算結果是一個數(shù)值,指令執(zhí)行后AX中是該表達式的值。2.地址表達式 地址表達式的結果是一個存儲單元的地址。當這個地址中存放

16、的是數(shù)據(jù)時,稱為變量;當這個地址中存放的是指令時,則稱為標號。例如:MOVAX,ES:BX+SI+100H。指令中源操作數(shù)是地址表達式,其結果是一個存儲單元的地址。425運算符運算符分為算術運算符、邏輯運算符、關系運算符、屬性運算符、數(shù)值返回運算符和其它運算符等。1 算術運算符 算術運算符包括:+(加)、(減)、*(乘)、/(除)和MOD(模除)、SHL(左移)和SHR(右移)。+、*、/是常用的運算符,參加運算的數(shù)和運算的結果均為整數(shù),除法運算的結果取商的整數(shù)部分,MOD模除運算只取其余數(shù)。SHL左移和SHR右移運算,相當于二進制乘法和除法運算。 2邏輯運算符 邏輯運算符包括AND(與)、O

17、R(或)、異或(XOR)、NOT(非)四種。用于對常量進行按位操作。注意,這四種運算符與邏輯指令的助記符是一樣的,但它們在語句中的為置是不同的。表達式中的邏輯運算符是只出現(xiàn)在指令的操作數(shù)部分,是由匯編程序匯編時完成運算;而邏輯指令是中的助記符是出現(xiàn)在指令的操作碼部分,其運算是在指令執(zhí)行時進行的。 例4.10ORAL,BH OR 80HMOVAL,CL AND B3.關系運算符關系運算符包括GT(大于)、GE(大于等于)、LT(小于)、LE(小于等于)、EQ(等于)、NE(不等于)共六種。關系運算符用于對兩個操作數(shù)進行比較運算,結果為邏輯值。若關系成立結果為真,用全“1”表示;結果為假,用全“0

18、”表示。例4.11MOVAX,10EQ1010B;10=1010B為真,(AX)=0FFFFHMOVBX,20H GT32;20H大于32為假,(BX)=04屬性運算符屬性運算符有PTR和THIS兩種。它們可以臨時改變原操作數(shù)的類型屬性,一般對存儲器操作數(shù)使用。例4.12DATA1DB10,11,12,13,14,15,16 ADDWORDPTRDI,100;指明目標操作數(shù)是字類型JMPDWORD PTRBX;指明為段間轉(zhuǎn)移MOVEAX,DWORD PTR DATA1;修改DATA1為雙字型變量ALPHA EQU THIS BYTE;將變量ALPHA的類型定義為字節(jié)POINT EQU THIS

19、 FAR;將標號POINT定義為FAR5數(shù)值返回運算符數(shù)值返回運算符包括SEG(返回段地址)、OFFSET(返回偏移地址)、TYPE(返回類型字節(jié)數(shù))、LENGTH(返回變量單元數(shù))和SIZE(返回變量總字節(jié)數(shù))。它們不改變原操作數(shù)的屬性,只是取操作數(shù)的某一屬性,返回的結果是一個數(shù)值。(1) SEG運算符SEG運算符加在變量名或標號之前,返回的數(shù)值是該變量或標號所在段的段基址。例如:MOVAX,SEG VAR1如果變量VAR1所在段的段基址為2000H,則該指令執(zhí)行后AX的內(nèi)容為2000H。(2) OFFSET運算符OFFSET運算符加在變量名或標號之前,返回的數(shù)值是該變量或標號所在段的偏移地

20、址。例如:MOVBX,OFFSET NEXT如果變量NEXT在段內(nèi)的偏移地址為100H,則該指令執(zhí)行后BX的內(nèi)容為100H。(3)TYPE運算符 TYPE運算符加在變量名之前,返回的數(shù)值是該變量的類型字節(jié)數(shù),如:DB為1,DW為2,DD為4,DQ為8,DT為10;當TYPE加在標號之前,返回的數(shù)值是這個標號的類型屬性值,如:NEAR為1,F(xiàn)AR為2。 例4.13A1DB5,6,7,A2DW1234H,3456HA3DDHSFLABEL FARSN:MOVBL,TYPEA1;等效于MOVBL,1MOVBH,TYPEA2;等效于MOVBH,2MOVDLTYPEA3;等效于MOVDL,4MOVDH,

21、TYPESF;等效于MOVDH,2(4)LENGTH運算符該運算符加在變量名之前,返回的數(shù)值是該變量中所定義的元素個數(shù)。如果變量是用重復數(shù)據(jù)操作符DUP說明的,則返回DUP前面的數(shù)值,如果沒有DUP說明,則返回的值總是1。例4.14B1DB100H DUP(0)B2DW20H DUP(0)B3DW4321H,3859HB4DBABCDEFMOVBX,LENGTH B1;等效于MOV BX,100HMOVCX,LENGTH B2;等效于MOV CX,20HMOVDX,LENGTH B3;等效于MOV DX,1MOVAX,LENGTH B4;等效于MOV AX,1(5)SIZE運算符該運算符加在變

22、量名之前,返回的數(shù)值是該變量所雜燴的字節(jié)總數(shù)。它等于LENGTH和TYPE兩個運算符返回的乘積。例如,對于上例中所定義的變量B1、B2、B3、B4,SIZE的返回值如下所示:例4.15MOVBX,SIZE B1;(BX)=100HMOVCX,SIZE B2;(CX)=40HMOVDX,SIZE B3;(DX)=2MOVAX,SIZE B4;(AX)=16其它運算符(1)字節(jié)高低分離運算符HIGH和LOW運算符分別用于從16位運算對象中分離出高字節(jié)和低字節(jié)。MASM6.0 用HIGHWORD和LOWWORD運算符,從32位符號常量中分離出高字和低字。例4.16MOVAL,LOW1234H;(AL

23、)=34HMOVAH,HIGH1234H;(AH)=12HVAREQU1234ABCDHMOVAX,HIGHWORD VAR;(AX)=1234H(2)運算符的優(yōu)先級順序上述運算符可以同時出現(xiàn)在表達式中,其優(yōu)先級順序由高到低如下所示:( ), , ,LENGTH,WIDTH,SIZE,MARKPTR,OFFSET,SEG,TYPE,THIS,CS:,DS:,SS:,ES:HIGH,LOW+,*,/,MOD,SHL,SHREQ,NE,LT,LE,GT,GENOTANDOR,XORSHORT43 80X86宏匯編語言的偽指令80X86宏匯編語言(MASM)提供了多種偽指令,主要有變量定義、符號定義

24、、段定義、段分配、過程定義、模塊定義、結構定義、宏定義等。上一節(jié)已經(jīng)介紹了部分偽指令,在這一節(jié)里,我們介紹其它常用的偽指令,還有另外一些,需要時讀者可查閱有關資料。431簡化的段定義和完整的段定義在匯編語言程序設計中,存儲器的物理地址是由段地址和偏移地址組合而成的,匯編程序在把源程序轉(zhuǎn)換為目標程序時,必須確定標號和變量的偏移地址,并且需要把有關信息通過目標模塊傳送給連接程序,以便連接程序把不同的段和模塊連接在一起形成一個可執(zhí)行程序。為此需要用段定義偽操作。 在MASM5.0以上的匯編語言的版本中,段的定義有簡化的段定義和完整的段定義兩種偽指令。簡化的段定義使用指定的存儲模式編程,給程序設計帶來

25、極大的方便。簡化的段定義常用偽指令如下:1MODEL偽指令格式如下:.MODEL存儲模式,語言類型,操作系統(tǒng)類型,堆棧類型方括號內(nèi)為可選項。.MODEL偽指令確定了程序的存儲模式。當使用簡化段定義的源程序格式時,必須有該語句,且位于所有簡化段定義語句之前。(1)存儲模式存儲模式是指用戶程序的數(shù)據(jù)和代碼的存放格式,以及它們占用內(nèi)存的大小。常用的存儲模式有以下7種:TINY微型模式。程序中的數(shù)據(jù)和代碼放在同一個64KB段內(nèi),其數(shù)據(jù)和代碼都是近訪問。這也就是.COM文件的格式,COM程序必須從0100H存儲單元開始。這種模式一般用于小程序。SMALL小型模式。獨立的代碼段(64KB字節(jié)內(nèi))和獨立的程

26、序段(64KB字節(jié)內(nèi))。數(shù)據(jù)和代碼都是近訪問,一般程序默認的都是該模式。MEDIUM中型模式。一個數(shù)據(jù)段(64KB字節(jié)內(nèi)),多個代碼段。這樣,數(shù)據(jù)是近訪問,代碼可以是遠訪問。COMPACT壓縮模式。一個代碼段(64KB字節(jié)內(nèi)),多個數(shù)據(jù)段。這樣,對于代碼的訪問是近程的,而數(shù)據(jù)是遠程的。LARGE大型模式。多個代碼段,多個數(shù)據(jù)段。對于代碼和數(shù)據(jù)的訪問都是遠程的。HUGE與LARGE模式相同,其差別是允許數(shù)據(jù)段的大小超過64KB。FLAT平展模式。用于創(chuàng)建一個32位的程序,它只能運行在32位80X86CPU上。DOS下不能使用FLAT模式。MASM6.0支持該模式。(2)語言類型語言類型是高級語言

27、接口選項,是指該匯編語言程序作為某種高級語言程序的過程而為該高級語言程序所調(diào)用時,應該用如C、BASIC、FORTRAN、PASCAL等加以說明。(3)操作系統(tǒng)類型 操作系統(tǒng)類型選項是說明運行于那個操作系統(tǒng)之下,OSDOS是當前唯一支持的選項,默認是OSDOS。 (4)堆棧類型 該選項可用NEARSTACK或FARSTACK來說明。其中,NEARSTACK是該選項的默認堆棧類型。NEARSTACK是堆棧段和數(shù)據(jù)段是同一個段。 FARSTACK堆棧段和數(shù)據(jù)段是不同的段。當存儲模式為TINY、SMALL、MEDIUM和FLAT時,默認項是NEARSTACK;當存儲模式為COMPACT、LARGE和

28、HUGE時默認項是FARSTACK。例如:.MODELSMALL,C.MODELLARGE,PASCAL,OSDOS,F(xiàn)ARSTACK2段定義偽指令簡化的段定義偽指令都可以用來表示一個段的開始,同時也說明前一個段的結束。.CODE定義代碼段.DATA定義數(shù)據(jù)段.DATA?.STACK長度定義堆棧段,長度缺省為1KB.STARTUP指示程序開始.CONST定義常數(shù)段.X86選擇80X86的指令系統(tǒng).EXIT0程序結束,返回操作系統(tǒng)當使用簡化段偽指令時,必須在簡化段偽指令之前先使用.MODEL偽指令定義存儲模式,然后再用簡化的段定義偽指令。3處理器選擇偽指令MASM宏匯編在能夠匯編指定處理器的指令

29、,可采用下述偽指令:.8086可用來匯編8086/8088處理器的指令,這是缺省模式。.286、.286C、.286P可用來匯編286系列處理器的指令。其中.286、.286C可用于匯編非特權(實地址方式)80286處理器指令;.286P可用來匯編80286處理器的所有指令(包括保護方式)。.386、386C、.386P可用來匯編386系列處理器的指令。其中.386、.386C可用于匯編非特權(實地址方式)80386處理器指令;.386P可用來匯編80386處理器的所有指令(包括保護方式)。.486.、486C、486P可用來匯編486系列處理器的指令。其中.486、.486C可用于匯編非特權

30、(實地址方式)80486處理器指令;.486P可用來匯編80486處理器的所有指令(包括保護方式)。.586.、586C、586P可用來匯編Pentium系列處理器的指令。其中,.586、.586C可用于匯編非特權(實地址方式)Pentium處理器指令;.586P可用來匯編Pentium處理器的所有指令。.686.、.686P可用來匯編Pentium Pro到Pentium 4處理器的指令。其中,.686可用于匯編實地址方式Pentium Pro到Pentium 4處理器指令;.686P可用來匯編Pentium Pro到Pentium 4處理器的所有指令。.MMX可用來匯編MMX指令。.MMX

31、、.686和.686P是MASM6.12引入的。.K3D可用來匯編AMD處理器的3D指令,是MASM6.13引入的。.XMM可用來匯編SSE指令和SSE2指令,是MASM6.15引入的。需要說明的是,80386以上處理器選擇偽指令在源程序中的位置不一樣可有不同的含義。如果處理器選擇偽指令放在.MODEL偽指令前面,段就定義成32位。如果希望處理器使用16位的段,則應在.MODEL偽指令的后面使用處理器選擇偽指令。4等價名的使用MASM5.0宏匯編語言中,規(guī)定了幾個等價名代替真實名。例如,段等價名可以用代替簡化段定義偽指令前面的小數(shù)點。這樣,CODE就代表.CODE定義的段名;DATA就代表.D

32、ATA、.DATA?、.CONST和.STACK.可共享的段組名。5段序定義偽指令MASM宏匯編可以按照源程序中各個段出現(xiàn)的次序來排列目標文件中各段的先后次序,也可以按照段名的字母順序來排列次序。缺省是按照段出現(xiàn)的次序來排列,程序員可以用偽指令來定義段序,這些偽指令是:.ALPHA按照字母順序?qū)Χ芜M行排序。.SEG 按照段出現(xiàn)的順序?qū)Χ芜M行排序。完整段定義語句中,默認按此順序。.DOSSEG按照DOS定義的標準段序?qū)Χ闻判?,順序為:代碼段、數(shù)據(jù)段、堆棧段。采用.MODEL偽指令的簡化段定義格式默認按此順序。 6簡化段定義結構舉例例4.17.MODELSMALL ;定義小型內(nèi)存模式.486 ;可

33、以匯編486指令.STACK200 ;定義堆棧段,長度為200個字節(jié).DATA ;定義數(shù)據(jù)段開始XXDW6789H,4321HYYDW0AB00H,00FFHZZDD?,?.CODE ;代碼段開始.STARTUP ;程序開始MOVEAX,XXMULYYMOVZZAXMOVZZ+4,EDX.EXIT0;程序結束,返回DOS。相當于MOV AX,4C00H和INT 21H兩條END ;匯編結束例4.18將數(shù)據(jù)區(qū)的信息顯示在屏幕上。.MODELSMALL.586.STACK20H.DATAMSGDBTHIS IS A DISPLAY BUFFER$;顯示的信息.CODE.STARTUPMOVDX,O

34、FFSET MSG ;信息緩沖區(qū)首地址送DXMOVAH,9 ;將數(shù)據(jù)區(qū)的信息顯示在屏幕上INT21H ;DOS顯示功能調(diào)用.EXIT0 ;返回END ;匯編結束432完整的段定義偽指令完整的段定義偽指令適用于MASM和TASM。1完整的段定義結構舉例例419DATASEGSEGMENT;數(shù)據(jù)段定義 BLOCKDB1000DUP(?)DATASEGENDS;數(shù)據(jù)段結束STACKSEGSEGMENT;堆棧段定義 DW100DUP(?)STACKSEGENDS;堆棧段結束EXTRASEGSEGMENT;附加段定義 DB 100DUP(?)EXTRASEGENDS;附加段結束CODESEGSEGMEN

35、T;代碼段定義 ASSUMECS:CODESEG,DS:DATASEG,ES:EXTRASEG ASSUMESS:STACKSEG;分配段地址寄存器START:MOVAX,DATASEG MOVDS,AX MOVAX,EXTRASEG MOVES,AX MOVAX,STACKSEG MOVSS,AX : : MOVAH,4CH INT21HCODESEGENDS;代碼段結束 ENDSTART2段定義偽指令格式:段名SEGMENT 定位類型,組合類型,字長選擇,類別名:段名ENDS 任何邏輯段總是從SEGMENT語句開始,以ENDS語句結束。偽指令SEGMENT和ENDS不可以缺省,而且總是成對

36、出現(xiàn)。段名是必選項,同一個段的開始和結束的段名應是相同的。方括號中的項是可選項。(1)定位類型(ALIGN TYPE)定位類型表示對段的起始邊界的要求。有以下幾種選擇:PAGE(頁):表示段從頁的邊界開始。256個字節(jié)為一頁。PARA(節(jié)):表示段從節(jié)的邊界開始。一節(jié)為16個字節(jié),PARA通常為隱含。DWORD(雙字):表示段從4的倍數(shù)地址開始。WORD(字):表示段從偶數(shù)地址開始。BYTE(字):表示段可以從任何地址開始。(2)組合類型(COMBINE TYPE)組合類型表示多個程序模塊連接時,本模塊與其它模塊的同名段如何組合,可以有如下幾種選擇:PRIVATE:這是隱含選擇,表示該段與其它

37、段無組合關系,每段都有自己的段基址。PUBLIC:該段可與其它模塊中的同名段在滿足定位類型的前提下,從低地址到高地址連接起來,組合成一個較大的邏輯段。COMMON:表示產(chǎn)生一個覆蓋段。即當兩個段連接時,把本段與其它段也用COMMON說明的同名段置成相同的起始地址,共享相同的存儲區(qū),共享存儲區(qū)的長度由其中最大的段確定。STACK:表示該段為堆棧段。連接程序?qū)巡煌K中具有STACK屬性的同名段連接成一個大的堆棧段,連接后的堆??臻g是連接前各模塊預留的堆??臻g之和。程序裝入后,DOS自動初始化SS和SP,使SS的內(nèi)容為堆棧段的段基址,SP的內(nèi)容為堆??臻g的字節(jié)數(shù),使SS:SP自動指向棧頂。連接程

38、序要求.EXE文件的匯編源程序必須有堆棧段,否則連接時將發(fā)出警告信息:Warning no stack segmemt,但并不表示源程序有錯誤,只是提醒用戶注意。AT表達式:表示本段可定位在表達式所指示的節(jié)邊界上。(3)字長選擇字長選擇用于定義段中使用的偏移地址和寄存器的字長。有兩種字長可供選擇。USE16:段字長為16位,最大段長為64KB;USE32:段字長為32位,最大段長為4GB。若字長選擇缺省,確認為USE32。(4)類別名類別名表示邏輯段的類別,類別名是用戶定義的,必須用單引號括起來,長度不超過40個字符。類別名是可選項。習慣上,數(shù)據(jù)段的類別名用DATA,代碼段的類別名用CODE,

39、堆棧段的類別名為STACK。連接程序把不同模塊中類別名相同的同名段組織成一類,放在相鄰的存儲區(qū)中。3段分配偽指令格式:ASSUME段寄存器名:段名,段寄存器名:段名,。功能:該語句通知匯編程序源程序中定義的段由那個段寄存器尋址。段寄存器可以是、CS、DS、ES、SS、FS和GS。說明:(1)格式中,ASSUME是偽指令名,是語句中的關鍵字,不可缺省。段寄存器后面必須有冒號,如果分配的段名不止一個,則應用逗號分開。段名是指用SEGMENT/ENDS偽指令定義過的段名。ASSUME語句是非執(zhí)行語句,要求放在代碼段內(nèi)段定義語句之后。(2)ASSUME語句僅僅約定了對邏輯段進行尋址操作時使用哪個段寄存

40、器,而段寄存器的初值還必須在程序中用指令設置。例如用以下兩條語句可以設置數(shù)據(jù)段寄存器的初值,設DATA為數(shù)據(jù)段名:使用SEG運算符求出段基址,然后裝入DS段寄存器。例如:MOVAX,SEG DATAMOVDS,AX直接把段名賦給段寄存器,例如: MOVAX,DATAMOVDS,AX(3)DOS把一個可執(zhí)行的程序(EXE文件)調(diào)入內(nèi)存之后,自動地把程序代碼段的基址賦給了CS,也就是說,對CS的賦值是由DOS系統(tǒng)自動完成的,程序員不能干預。433其它偽指令在匯編語言中,為了指示程序中指令和數(shù)據(jù)在相應段中的偏移地址,可使用定位偽指令和當前位置計數(shù)器。1定位偽指令格式:ORG表達式ORG偽指令用來指定

41、該語句之后的程序段或數(shù)據(jù)塊的起始地址的偏移地址。例如:ORG 1000H;ADD1變量的偏移地址從1000H開始ADD1DB2,3,45HORG1020HADD2DW0080H,0098H;變量ADD2的偏移地址從1020H開始通常ORG偽指令可以出現(xiàn)在程序的任何位置上。2當前位置計數(shù)器$在匯編語言中,可以用$表示當前位置計數(shù)器的現(xiàn)行值。例420DATASEGMENTSEGDBWELCOMECOUNTEQU$SEGDATAENDS其中,$表示當前的偏移地址,SEG表示上一條語句中變量SEG的偏移地址,$SEG表示兩個偏移地址之差,正好是以變量SEG為首地址的連續(xù)字節(jié)數(shù),即SEG為首地址的字符個

42、數(shù)。3 程序結束偽指令ENDEND偽指令作為匯編語言源程序的結束語句,一般放在源程序的最后一行。一個程序模塊只允許有一個END語句。格式:END標號其中,標號是該程序中的第一條可執(zhí)行語句的標號。44匯編語言程序設計的方法程序有順序、循環(huán)、分支和子程序四種基本結構形式。順序結構程序是指完全按照指令排列的順序逐條執(zhí)行的程序,這是最常見的也是最簡單的一種結構形式。在程序設計中,單純一種結構的程序并不多見,大多數(shù)都是多種結構的組合。本節(jié)主要舉例說明分支、循環(huán)和子程序的程序設計方法。441分支程序設計分支程序可以用轉(zhuǎn)移指令實現(xiàn)也可以用MASM6.X的偽指令實現(xiàn)。1用轉(zhuǎn)移指令實現(xiàn)分支用條件轉(zhuǎn)移指令實現(xiàn)分支

43、時,條件轉(zhuǎn)移指令通常安排在比較指令、加減指令和邏輯運算指令后面使用,根據(jù)標志寄存器的狀態(tài),決定是否轉(zhuǎn)移。例421把連續(xù)存放在DAT中的三個數(shù),按遞減順序排列。分析:為了實現(xiàn)遞減排列,可以對三個數(shù)兩兩進行比較,比較后的大數(shù)放在前面。程序流程圖如圖4.3所示。 圖4.3 三數(shù)排序流程圖程序如下:.MODELSMALL.486.STACK.DATADAT DW-36,64,125.CODE.STARTUPMOVBX,OFFSETDATMOVAX,BXCMPAX,BX+2JGENEXT1;AB?XCHGAX,BX+2;交換A,BMOVBX,AXNEXT1:MOVAX,BX+2CMPAX,BX+4JGE

44、NEXT2;BC?XCHGAX,BX+4;交換B,CMOVBX+2,AXNEXT2:CMPBX,AXJGENEXT3;AB?XCHGBX,AX;交換A,BMOVBX+2,AXNEXT3:.EXIT0END2用MASM6.X的偽指令實現(xiàn)分支MASM6.X引入了條件控制偽指令,類似于高級語言中分支語句的相應功能。這些偽指令在匯編時自動展開,生成相應的比較和條件轉(zhuǎn)移指令序列,實現(xiàn)分支結構,簡化了分支結構的編程。分支語句主要用.IF偽指令來實現(xiàn),條件控制格式如下:.IF條件表達式;條件成立(表達式的值非0),執(zhí)行語句1語句1.ELSE IF條件表達式;前面IF條件不成立(值為0),并且當前ELSEIF

45、條;件為真,執(zhí)行語句2語句2.ELSE;前面IF條件不成立,執(zhí)行語句n語句n.ENDIF;分支結束其中方括號部分為可選。條件表達式允許的操作符及功能說明如下:= =等于!=不等于>大于>=大于等于<小于<=小于等于&&邏輯與|邏輯或!邏輯非&位測試( )改變優(yōu)先級CARRAY?CF=1?OVERFLOW?OF=1?PARITY?PF=1?SIGN?SF=?ZERO?ZF=1? 其中,&&的優(yōu)先級高于|和!,位測試運算符的用法為:“數(shù)值表達式&數(shù)值”,相當于執(zhí)行TEST指令和相應的條件轉(zhuǎn)移指令。例422編程實現(xiàn)將鍵盤輸入的字

46、符、數(shù)字轉(zhuǎn)換成十六進制數(shù)。.MODELTINY.CODE.STARTUPMOVAH,1INT21H;從鍵盤輸入字符.IFAL>=A&&AL<=FSUBAL,37H.ELSEIFAL>=a&&A<=fSUBAL,57H.ELSESUBAL,30H.ENDIF.EXITEND442循環(huán)程序設計在程序設計中,常常有一段程序需要反復執(zhí)行若干次,這通常用循環(huán)的方法來實現(xiàn)。循環(huán)結構是根據(jù)某一條件成立與不成立重復執(zhí)行循環(huán)體。循環(huán)結構程序通常由四個部分組成:循環(huán)初始部分、循環(huán)工作部分、修改部分和循環(huán)控制部分。循環(huán)初始部分是循環(huán)開始的必要準備,如設置循環(huán)次

47、數(shù)、設置地址指針和地址計數(shù)器、設置常數(shù)和寄存器清0等。循環(huán)工作部分是重復執(zhí)行的程序代碼??梢允琼樞蚪Y構、分支結構或循環(huán)結構的程序段。修改部分是對循環(huán)條件的修改,為執(zhí)行下一次循環(huán)做準備。循環(huán)控制部分判斷循環(huán)條件是否滿足,循環(huán)是否繼續(xù)執(zhí)行。根據(jù)循環(huán)控制部分在程序中的位置不同,分為“先循環(huán),后判斷”和“先判斷,后循環(huán)”兩種結構。圖4.4是兩種循環(huán)程序的結構。 圖4.4循環(huán)程序的結構循環(huán)程序可以用循環(huán)指令實現(xiàn)還可以MASM6.X的循環(huán)偽指令實現(xiàn)。1.用循環(huán)指令實現(xiàn)循環(huán)結構借助于80X86循環(huán)控制指令,如:LOOP、LOOPE、LOOPNE、JCXZ以及重復操作前綴REP、REPE、REPNE等,可以方

48、便地實現(xiàn)循環(huán)。例4.23從鍵盤輸入20個字符,按鍵入次序?qū)ふ易帜疙樞蜃畲蟮淖址⑶绎@示輸出(區(qū)別大小寫)。分析:大寫字符AZ的ASCII碼為41H5AH,小寫字母az的ASCII碼為61H7AH,大小寫字母的ASCII碼值相差20H,因此在判斷ASCII碼值的大小寫時,小寫字符ASCII碼減去20H參與比較。程序流程如圖4.5所示。 圖4.5 例423程序流程圖程序如下:.MODEL SMALL.DATABUFDB21,?,21DUP(?)BLOCKDB0AH,0DH,?,$.CODE.STARTUPMOVDX,OFFSETBUF;鍵入字符MOVAH,0AHINT 21HLEABX,BUF+

49、2MOVCX,BUF+1MOVAL,BX;緩沖區(qū)第一個字符送ALANDAL,B;小寫字母ASCII碼減20HMOVSI,BX;緩沖區(qū)第一個字符地址送SIAGAIN:INCBXMOVDL,BX;緩沖區(qū)字符送DLANDDL,BCMPAL,DL;比較兩字符大小JAENEXTXCHGAL,DL;大數(shù)存AL中MOVSI,BX;大數(shù)地址送SINEXT:LOOPAGAINMOVDL,SI;最大字符送DLMOVBLOCK+2,DLMOVDX,OFFSET BLOCK;顯示輸出MOVAH,9INT21H.EXITEND例424將內(nèi)存首地址為BLOCK開始的10個帶符號的字節(jié)數(shù)按由小到大的次序排列。程序流程如圖4.6所示。Incount為內(nèi)循環(huán)變量,excount為外循環(huán)變量。 圖4.6例424程序流程如圖程序如下:.MODELSMALL.DATABLOCKDB66H,88H,33H,22H,00H,40H,50H,60H,70H,80H.CODE.STARTUPMOVDI,9;循環(huán)次數(shù)送DILOOP1:MOVCX,DI;設置循環(huán)次數(shù)MOVBX,0LOOP2:MOVAL,BLOCKBXCMPAL,BLOCKBX+1;比較兩個數(shù)大小JGENEXTXCHGAL,BLOCKBX+1;大數(shù)存AL中MOVBLOCKBX,ALNEXT:INC

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論