博客開通。。第一篇文章:8086彙編學習筆記(原創)

1.   寄存器

1.   通用寄存器組

       (1)   AX-累加器。算數運算的主要寄存器,用於存放操作數和或運算結果;另外,外設操作指令都是用AX存放數據。

       (2)   BX-基地址寄存器。用於存放操作數的偏移地址。

       (3)   CX-計數寄存器。用於循環指令、移位指令及串操作指令的計數控制。

       (4)   DX-數據寄存器。在乘除法運算中,與AX組合在一起存放雙字型數據;DX還用於存放外設操作數的端口地址。

       (5)   SI-源變址寄存器。作爲串操作的源操作數地址指針,也可用於存放操作數的偏移地址。

       (6)   DI-目的變址寄存器。作爲串操作的目的操作數地址指針,也可用於存放操作數的偏移地址。

       (7)   BP-棧基地址寄存器。用於存放堆棧中的操作數的偏移地址。

       (8)   SP-棧頂指針。用於記載棧頂的當前位置(偏移地址)。

2.   標誌寄存器

       (1)   條件標誌位

CF-進位標誌。記錄加法運算的進位,或者減法運算的借位值。

ZF-零標誌。記錄運算結果是否爲0

SF-符號標誌。記錄運算結果的正負情況。

OF-溢出標誌。記錄運算結果是否超出有符號數的表示範圍。

PF-奇偶標誌。記錄字節型運算結果中1的個數的奇偶性。

AF-輔助進位標誌。記錄加/減法運算中最後4位向前有無進/借位。

       (2)   控制標誌位

TF-單步中斷允許標誌。又稱跟蹤標誌,表示系統當前是否允許單步中斷。

IF-外中斷屏蔽標誌。表示系統當前是否允許可屏蔽外中斷。

DF-方向標誌。表示串操作按增量方向(0)還是按減量方向(1)進行。

3.   段寄存器組

       (1)   CS-代碼段段地址寄存器,或稱指令段段地址寄存器。

       (2)   DS-數據段段地址寄存器。

       (3)   ES-附加段段地址寄存器。

       (4)   SS-堆棧段段地址寄存器。

4.   指令指針

       (1)   IP-專門用於存放下一條指令所在的偏移地址。它與CS配合使用,用來確定程序的下一條指令在內存的哪個字節。

2.   基本指令

1.   MOV指令

【格式】MOV d1d2

【功能】d2操作數的值,放到d1操作數指定的位置。

【注意事項】

       (1)   目的操作書d1是數據送往的地點,不允許是立即尋址方式。

       (2)   如果d1是使用通用寄存器的寄存器尋址方式,則源操作數可以立即數、寄存器尋址或內存型尋址方式中的任何一種。

       (3)   d1是段寄存器時,d2不能是立即數,也不能是另一個段寄存器,只能是通用寄存器或內存型尋址方式

       (4)   不允許兩個操作數都是內存型尋址方式。

       (5)   如果兩個操作數中都有確定的類型,則兩者的類型必須相同,即要麼都是8位的字節型,要麼都是16位的字型。

       (6)   如果兩個操作數中只有一個可以確定的類型,則另一個操作數的類型按可確定類型的一個操作數同型處理;當一個操作數是寄存器,另一操作數是變量,且兩者類型不同時,變量可以臨時改變類型,保持與寄存器類型一致。

       (7)   如果d1是寄存器間接尋址或者基址變址尋址方式,d2是不超過255的立即數,這時兩個操作數的類型都不能確定,需要在d1操作數的前面用BYTEPTR或者WORDPTR指明操作是字節型還是字型。

       (8)   指令中的內存型操作數可以使用段跨越。

       (9)   MOV指令不影響所有標誌位的值。

2.   ADD指令

【格式】ADD d1d2

【功能】把目的操作數d1與源操作數d2相加,結果放入目的操作數中。加法運算不改變源操作數d2的值。

【注意事項】作爲雙操作數指令,ADD指令在語法規定上大部分與MOV指令是一樣的,但也有它特別的地方

       (1)   MOV指令中的注意事項⑴⑵⑷~⑻。

       (2)   兩個操作數都不允許是段寄存器。

       (3)   ADD指令本身並不區分相加的兩個數是無符號數還是帶符號數,因爲相加的結果在儲存形式上是一樣的。

       (4)   該指令將根據運算結果設置標誌寄存器中的各條件標誌位。

3.   SUB指令

【格式】SUB d1d2

【功能】用目的操作數d1作爲被減數,源操作數d2作爲減數,把兩者相減的差送回目的操作數d1中。運算不改變源操作數d2的值。

4.   MUL 指令

【格式】MUL d

【功能】完成無符號數的乘法運算。根據操作數d的類型分兩種情況:如果d是字節型,則把AL的值與d相乘,16位的積放到AX中;如果d是字型,則把AX的值與d相乘,32的積放到DXAX中,DX放積的高16位,AX放低16位。

【注意事項】

       (1)   MUL指令只能完成無符號數乘法運算,如果是帶符號數則需要用另外的指令。

       (2)   兩個乘數的位數必須相同,如不同則需要轉換,或怍適當處理,運算結果的位數是乘數的兩倍。

       (3)   指令中的操作數d不允許是立即數,只能用寄存器或內存型尋址方式,但不能是段寄存器。

       (4)   操作數d必須有確定的類型,當使用內存型尋址方式且不能確定類型時,必須用BYTE PTRWORD PTR僞指令加以說明,並且可以使用段跨越。

5.   DIV指令

【格式】DIV d

【功能】完成無符號數的除法運算。根據操作數d的類型分兩種情況:如果d是字節型,則用AX的值作爲被除數,指令中的操作數d作爲除數,除法運算結果包括商和餘數兩部分,字節型的商放到AL中,字節型的餘數放到AH中;如果d是字型,則用DX的值作爲高16位,AX的值作爲低16位,組成32位的被除數,操作數d作爲除數,計算結果,字型的商放到AX中,字型的餘數放到DX中。

【注意事項】

       (1)   DIV指令只能完成無符號數除法運算,帶符號數的除法需要另外的指令。

       (2)   被除數必須是字型或雙字型,如果是其他類型則需要採取適當的方式進行處理,商和除數的類型相同,位數是被除數位數的一半。

       (3)   MUL指令注意事項(3)、⑷。

6.   CMP指令

【格式】CMP d1d2

【功能】用操作數d1減去操作數d2,把運算的情況反映到條件標誌位上,運算得到的差並不送到任何一個操作數中,即CMP指令並不改變兩個操作數的值。

【說明】

       (1)   CMP指令專門用於兩個數據的比較,數據本身可以時無符號數,也可以是帶符號數。

       (2)   CMP指令關於操作數尋址方式的要求與SUB指令完全相同。

       (3)   CMP指令對各標誌位的設定規則也與SUB指令相同。

7.   無條件跳轉指令—JMP

【格式】JMP 標號

【功能】讓計算機轉到標號所在處繼續執行。

通常情況下,標號的定義與JMP指令應該在同一個段中,這種情況下的跳轉稱爲段內跳轉,只需要改變IP的值即可實現轉移。標號定義的位置與JMP指令的位置之間沒有先後限制,JMP指令既可以實現向前跳轉,也可以用於向後跳轉。程序中還可以多處使用JMP指令轉到同一個標號。

8.   以單個標誌位爲條件的跳轉指令—JZ指令(Jump if ZF Set

【格式】JZ 標號

【功能】如果ZF標誌位的值是1,則轉到標號所在處繼續執行,否則按正常順序執行下一條指令。

9.   JNZ指令(Jump if ZF Not Set

【格式】JNZ 標號

【功能】如果ZF標誌位的值是0,則轉到標號所在處繼續執行,否則按正常順序執行下一條指令。

10.  JC指令(Jump if CF Set

【格式】JC 標號

【功能】如果CF標誌位的值是1,則轉到標號所在處繼續執行,否則按正常順序執行下一條指令。

11.  JNC指令(Jump if CF Not Set

【格式】JNC 標號

【功能】如果CF標誌位的值是0,則轉到標號所在處繼續執行,否則按正常順序執行下一條指令。

12.  JS指令(Jump if SF Set

【格式】JS 標號

【功能】如果SF標誌位的值是1,則轉到標號所在處繼續執行,否則按正常順序執行下一條指令。

13.  JNS指令(Jump if SF Not Set

【格式】JNC 標號

【功能】如果SF標誌位的值是0,則轉到標號所在處繼續執行,否則按正常順序執行下一條指令。

14.  JO指令(Jump if OF Set

【格式】JO 標號

【功能】如果OF標誌位的值是1,則轉到標號所在處繼續執行,否則按正常順序執行下一條指令。

15.  JNO指令(Jump if OF Not Set

【格式】JNC 標號

【功能】如果OF標誌位的值是0,則轉到標號所在處繼續執行,否則按正常順序執行下一條指令。

16.  JE指令—等於跳轉(Jump if Equal

【格式】JE 標號

【功能】如果ZF1,則轉到標號處繼續執行,否則按正常順序執行下一條指令。這是JZ的另一種寫法

17.  JNE指令—不等於跳轉

【格式】JNE 標號

【功能】如果ZF0,則轉到標號處繼續執行,否則按正常順序執行下一條指令。是JNE的另一種寫法

18.  JA指令—無符號數大於跳轉(Jump if Above

【格式】JA 標號

【功能】如果ZFCF都是0,則轉到標號處繼續執行,否則按正常順序執行下一條指令。

JA指令完全等同的寫法是JNBEJump if Not Below nor Above

19.  JNA指令—無符號數小於或等於跳轉(Jump if Not Above

【格式】JNA 標號

【功能】如果ZF1,或者CF1,則轉到標號處繼續執行,否則按正常順序執行下一條指令。

JNA指令完全等同的寫法是JBEJump if Below or Equal

20.  JB指令—無符號數小於跳轉(Jump if Below

【格式】JB 標號

【功能】如果CF1,則轉到標號處繼續執行,否則按正常順序執行下一條指令。

JB指令完全等同的寫法有JNAE(Jump if Not Above nor Equal)JC

21.  JNB指令—無符號數大於或等於跳轉(Jump if Not Below

【格式】JNB標號

【功能】如果CF0,則轉到標號處繼續執行,否則按正常順序執行下一條指令。

JNB指令完全等同的寫法有JAEJump if Above or Equal)和JNC

22.  JG指令—帶符號數大於跳轉(Jump if Great

【格式】JG標號

【功能】如果ZF0並且SFOF值相同,則轉到標號處繼續執行,否則按正常順序執行下一條指令。

JG指令完全等同的寫法是JNLEJump if Not Less nor Equal

23.  JGE指令—帶符號數大於或等於跳轉(Jump if Great or Equal

【格式】JGE標號

【功能】如果SFOF值相同,則轉到標號處繼續執行,否則按正常順序執行下一條指令。

JGE指令完全等同的寫法是JNLJump if Not Less

24.  JL指令—帶符號數小於跳轉(Jump if Less

【格式】JL標號

【功能】如果SFOF值不同,則轉到標號處繼續執行,否則按正常順序執行下一條指令。

JL指令完全等同的寫法是JNGEJump if Not Great nor Equal

25.  JLE指令—帶符號數小於或等於跳轉(Jump if Less

【格式】JLE標號

【功能】如果SFOF值不同,或者ZF1,則轉到標號處繼續執行,否則按正常順序執行下一條指令。

JLE指令完全等同的寫法是JNGJump if Not Great

26.  JCXZ指令(Jump if CX is Zero

【格式】JCXZ標號

【功能】如果CX=0,則轉到標號處繼續執行,否則按正常順序執行下一條指令。

27.  LOOP—計數器型循環

【格式】LOOP 標號

【功能】先把寄存器CX的值減1,在判斷若減1後的CX值不是0,則轉到標號所在的指令繼續執行,否則按正常順序執行下一條指令。

【說明】

       (1)   這是把CX當作遞減計數器使用,LOOP指令包含了把CX1的功能,不需要另外寫CX1的指令。

       (2)   LOOP屬於條件跳轉指令,但跳轉不依賴於任何標誌位,僅僅根據CX1後的值是否爲0;與其他條件跳轉一樣,跳轉的距離不能超過前後128字節。

       (3)   LOOP指令構成的循環,通常是先將CX中放預訂的循環次數,然後是循環體,並在循環體的第1條指令處定義一個標號,循環體的後面時LOOP指令,跳轉到前面定義的標號處。

       (4)   由於是對CX先減1後判斷,若執行LOOP指令時CX的值時0,則減1後變成0FFFFH,不爲0,則會轉到標號處,所以如果CX中預先放的值是0,循環體將會執行65536次,爲預防這樣的情況出現,通常先用JCXZ指令判斷一下CX值是否爲0,不爲0時再進如循環部分。

28.  帶進位CF的加法

【格式】ADC d1d2

【功能】把目的操作數d1,源操作數d2以及進位標誌CF的值相加,結果送回d1中。

【說明】這條指令與ADD指令相比,僅僅是參與加法運算的加數多了CF,如果執行該指令時CF的值時0,就與ADDd1d2在效果上完全相同。ADC指令與ADD指令在對操作數的尋址方式要求上,以及運算結果對標誌位的設置方法上都是一樣的。該指令主要用於多字節整數相加。

29.  1指令

【格式】INC d

【功能】把操作數d1後的結果送回d中,

【說明】

       (1)   這是一條單操作數指令,要求操作數d必須是寄存器或內存型尋址方式,並且不能是段寄存器。如果是內存型尋址方式,必須能夠確定d的類型。d本身不能確定類型時,在d的前面加上BYTE PTRWORD PTR指明類型。

       (2)   該指令對條件標誌位的影響是:SFZF根據實際情況設置,對CF沒有影響,對於OF,當執行前操作數是字節型的7FH或是字型的7FFFH時,執行後把OF1,其餘情況都把OF0

       (3)   INC指令可以用來把操作數的值加1,它與ADD d1的差別主要在於對標誌位CF的影響上。

30.  帶借位CF的減法

【格式】SBB d1d2

【功能】用目的操作數d1減去源操作數d2,再減去CF的值,結果送到d1中。

除了多減一個CF的值外,SBB指令與SUB指令在對操作數的尋址方式要求上,以及對標誌位的影響上是一樣的。這條指令主要用於多字節型整數的減法。

31.  求補操作

【格式】NEG d

【功能】對操作數d按位取反後再加1,結果送回d中。

【說明】

       (1)   這條指令的功能就是求補函數,它並不考慮操作數d是否帶符號,只是按“取反加1”的規則處理。

       (2)   對操作數尋址方式的要求與INCDEC指令的要求相同。

       (3)   對標誌位的影響:SFZF按實際情況設置:若執行前d=0。則執行後CF0,否則CF1;若執行前d是字節型的80H或字型的8000H,則執行後OF1,其餘情況都將使OF0

32.  帶符號數乘法

【格式】IMUL d

【功能】帶符號數的乘法指令。當d是字節型時,把AL×d的結果放到AX中;當d是字型時,把AX×d的結果放到DXAX構成的雙字中,DX放高16位,AX放低16位。不論操作數d中的數據來源如何,都當作帶符號數。

33.  帶符號數除法

【格式】IDIV d

【功能】帶符號數的除法指令。當d是字節型時,用AZ/d,商放在AL中,餘數放在AH中;當d是字型時,用DXAX組成的雙字作爲被除數,除以d的商放在AX中,餘數放在DX中。不論操作數d中的數據來源如何,都當作帶符號數。如果商超出數據的有效範圍,將作爲除法溢出處理,在屏幕上顯示“Divide Overflow”字樣,並結束程序的執行。

34.  字節型符號擴展

【格式】CBW

【功能】AL中的帶符號數進行符號擴展,當AL<0時,AH被賦值爲0FFH,否則AH被置爲0。該指令不影響所有標誌位。

35.  字型符號擴展

【格式】CWD

【功能】AX中的帶符號數進行符號擴展,當AX<0時,DX被賦值爲0FFFFH,否則DX被置爲0。該指令不影響所有標誌位。

36.  交換指令

【格式】XCHG d1d2

【功能】把操作數d1d2的值交換。該指令不影響所有標誌位。

【說明】交換指令XCHG要求兩個操作數中不能有立即尋址方式,不能有段寄存器,也不允許兩個都是內存型尋址方式。

37.  查錶轉換

【格式】XLAT

【功能】這是一條隱含操作數指令,把字型寄存器BX的值與字節型的AL相加,結果作爲內存的偏移地址,以DS爲段,到內存中取出一字節送到AL中。該指令不影響所有標誌位。

38.  邏輯與

【格式】AND d1d2

【功能】把兩個操作數按二進制形式,相應位進行邏輯與運算,結果放到操作數d1中。

【說明】對操作數d1d2的尋址方式的要求與MOVADD等典型雙操作數指令的要求完全相同。運算結果將影響到標誌寄存器的各條件標誌位,具體設置情況是:CFOF總是被清0;運算結果的最高位複製到SF中;若運算結果各位都是0ZF1,否則ZF0

AND指令主要用於把目的操作數的指定位清0

39.  邏輯或

【格式】OR d1d2

【功能】把兩個操作數按二進制形式,相應位進行邏輯或運算,結果放到操作數d1中。

【說明】對操作數d1d2的尋址方式的要求以及對標誌位的影響與AND指令完全相同。

OR指令主要用於把目的操作數的指定位置1

40.  邏輯非

【格式】NOT d

【功能】把操作數d按二進制形式,每位取反,結果放回操作數d中。

【說明】對操作數d的尋址方式的要求與INC等典型單操作數指令一樣,可以是寄存器尋址或內存型尋址方式,不能是段寄存器。操作數必須有確定的類型,可以使用段跨越。

41.  邏輯異或

【格式】XOR d1d2

【功能】把兩個操作數按二進制形式,相應位進行邏輯異或運算,結果放到操作數d1中。

【說明】對操作數d1d2的尋址方式的要求以及對標誌位的影響與AND指令完全相同。

XOR指令主要用於對目的操作數的指定位取反。

42.  位測試

【格式】TEST d1d2

【功能】把兩個操作數按二進制形式,相應位進行邏輯與運算,按結果設置條件標誌位,結果不送回目的操作數。

【說明】對操作數d1d2的尋址方式的要求以及對標誌位的影響與AND指令完全相同。

TEST指令通常用於檢測指定位上是0還是1TEST指令總是與JZJNZ指令配合使用。

43.  LEA——取變量的偏移地址

【格式】LEA d1d2

【功能】把源操作數d2的偏移地址取到目的操作數d1中。

【說明】

       (1)   這是一條數據傳遞類指令,不影響標誌位。

       (2)   該指令專用於取源操作數的偏移地址,所以源操作數d2一定是內存型尋址方式,可以是內存型操作數5種尋址方式中的任何一種。

       (3)   d2是變量名形式的直接尋址方式時,變量名兩邊的方括號可以省略。

目的操作數d1一定是寄存器型,且必須是16位的字型通用寄存器,不能是段寄存器。

44.  PUSH指令

【格式】PUSH d

【功能】先把SP的值減去2,然後把操作數d指明的字型數據放入以SS爲段地址、SP爲偏移地址所對應的內存單元中。

【說明】

       (1)   這是單操作數指令,操作數d可以是包括段寄存器在內的任何字型寄存器,或者內存型尋址方式,但不能是立即尋址,當使用內存型尋址方式時可以使用段跨越。

       (2)   PUSH指令的功能包括移動棧頂和存入數據兩部分,兩部分連續完成,密不可分。

       (3)   操作數d進棧是以減2以後的SP的值作爲偏移地址,但程序中不允許出現[SP]的寫法。

       (4)   PUSH指令會導致棧頂指針的移動,如果用PUSH指令把很多數據進棧,使SP不斷減2,就有可能超出棧的有效範圍。

45.  POP指令

【格式】POP     d

【功能】從SS爲段地址、SP爲偏移地址對應的內存中取出一個字型數據,送到操作數d的指定的位置,然後把SP的值加2。對操作數d的尋址方式要求與PUSH指令相同。

46.  PUSHFPOPF指令

【格式】PUSHF

【功能】把SP的值減2,並把16位的標誌寄存器送入SSSP所指向的內存,即把標誌寄存器入棧

 

【格式】POPF

【功能】把棧頂的一個16位的字型數據送入標誌寄存器,並把SP的值加2

47.  CALL指令

【格式】CALL    子程序名

        【功能】調用子程序指令

       (1)   如果被調用的子程序是NEAR類型,則先把當前指令指針IP的值入棧,這會使SP的值減2,然後把IP改成子程序的第1條指令的偏移地址。

       (2)   如果被調用的子程序是FAR類型,則先把當前CS寄存器的值入棧,再把IP入棧,如果會使SP的值減4,然後把CSIP改爲子程序第1條指令的邏輯地址。

48.  RET指令

【格式】RET

【功能】這是子程序返回指令,必須寫在子程序的指令序列之中。根據所在的子程序的類型不同,RET指令的功能也分爲兩種情況:

       (1)   如果RET所在的子程序是NEAR類型,則從堆棧中出棧一個字(當然,SP會加2),送給IP

       (2)   如果RET所在子程序是FAR類型,則先從堆棧中出棧一個字送到IP,在出棧一個字送到CS,棧頂指SP的值加4

【格式】RET n

【功能】完成RET指令的功能後,把SP的指令加n結果送回SP

49.  CLC指令

【格式】CLC

【功能】對CF標誌位清0

50.  STC指令

【格式】STC

【功能】對CF標誌位置1

51.  CMC指令

【格式】CMC

【功能】對CF標誌位的原值取反。

52.  邏輯左移

【格式】SHL d1d2

【功能】把操作數d1的各個二進制位依次向左移動d2位,移動造成右邊的空位填0,結果放回操作d1中。

【說明】

       (1)   操作數d1必須是通用寄存器或內存型尋址方式,必須有確定的類型,可以是字節型,也可以是字型,並且對內存型尋址方式可以使用段跨越。

       (2)   操作數d2表示移位的位數,只能是立即數或者寄存器CL,當移動位數超過1位時,必須把移動位數放在CL中,以CL作爲d2操作數。

       (3)   操作數d1各位移動情況從最高位起,將有d2位移到操作數d1之外,除了最後移出的一位放到標誌位CF中之外,其餘各位均被丟棄,移動造成右邊的空位用0填充。

       (4)   移動後d1中的數據是在其原值的後面加了d20,即把原數值擴大了2d2倍,當擴大後的值超過表示範圍時,超過d1類型(字節或字)規定位數的高位部分會自動丟失。

       (5)   該指令對其餘標誌位的影響情況是:移動後的結果爲0ZF1,否則ZF0;移動後d1最高位的值會複製到SF上;如果移動前後d1的最高位不同則OF1,否則OF0

53.  算術左移

【格式】SAL d1d2

【說明】這是一條與SHL完全相同的指令,該指令與SHL指令是同一條機器指令的不同寫法。

54.  邏輯右移

【格式】SHR d1d2

【功能】把操作數d1的各個二進制位依次向右移動d2位,移動造成左邊的空位填0,結果放回操作數d1中。

【說明】

       (1)   對兩個操作數的語法限制以及對標誌位的設置情況都與SHL指令相同,見SHL指令說明的(1),(2)和(5)。

       (2)   SHR指令在位的移動方向上與SHL指令剛好相反,其他方面則很類似,向右移出的最後一位放到CF中,右移造成左邊的空位以0填充。

       (3)   移動後的值是把d1中的原值作爲無符號數,除以2d2的商。

55.  算數右移

【格式】SAR d1d2

【功能】把操作數d1的各個二進制位依次向右移動d2位,移動造成左邊的空位填d1原值的最高位,結果放回操作數d1中。

【說明】SAR指令的功能基本上與SHR的一樣,僅僅是移動造成的空位填充方式不同,如果操作數d1移動前最高位是1,則移動造成的空位以1填充,否則以0填充。

56.  循環左移

【格式】ROL d1d2

【功能】把操作數d1的各個二進制位向左移動d2位,從d1左端移出的每一位再依次移到右端空出的位上,最後移出的一位還要送到CF中。

57.  循環右移

【格式】ROR d1d2

【功能】把操作數d1的各個二進制位向右移動d2位,從右端移出的各位再依次移到d1左端空出的位上,最後移出的一位還要送到CF中。

58.  帶進位的循環左移

【格式】RCL d1d2

【功能】把操作數d1的各位與CF聯合在一起,構成9個或者17個二進制位,向左移懂d2位,從左端移出的各位再依次移到右端空出的位上。

59.  帶進位的循環右移

【格式】RCR d1d2

【功能】把操作數d1的各位與CF聯合在一起,構成9個或者17個二進制位,向右移動d2位,從右端移出的各位再依次移到左端空出的位上。

60.  專用指令設置DF——CLDSTD

【格式】CLD

【功能】把標誌位DF0

【格式】STD

【功能】把標誌位DF1

61.  LODS指令——從串中取出數據

【格式】LODSBLODSW

【功能】

       (1)   LODSB進行字節型串操作,從內存中DSSI所確定的邏輯地址處取出一個字節的數據,送到AL中。當DF=0時,令SI=SI+1,DF=1時,令SI=SI+1

       (2)   LODSW進行字型串操作,從內存中DSSI所確定的邏輯地址處取出一個字型數據,送到AX中。當DF=0時,令SI=SI+2;當DF=1時,令SI=SI-2

62.  STOS指令——往串中存入數據

【格式】STOSBSTOSW

【功能】

       (1)   STOSB進行字節型操作,把AL的值送往內存中由ESDI所確定的內存中。當DF=0時,令DI=DI+1,當DF=1時,令DI=DI-1

       (2)   STOSW進行字型串操作,把AX的值送往內存中由ESDI所確定的內存中。當DF=0時,令DI=DI+2,當DF=1時,令DI=DI-2

63.  MOVS指令——串複製

【格式】MOVSBMOVSW

【功能】

       (1)   MOVSB進行字節型串複製,把DSSI所指向的一個字節型數據送往ESDI所指向的內存中。當DF=0時,令SI=SI+1DI=DI+1;當DF=1時,令SI=SI+1DI=DI-1

       (2)   MOVSW進行字型串複製,把DSSI所指向的一個字型數據送往ESDI所指向的內存中。當DF=0時,令SI=SI+2DI=DI+2;當DF=1時,令SI=SI-2,DI=DI-2

64.  CMPS指令——串比較

【格式】CMPSBCMPSW

【功能】

       (1)   CMPSB進行字節型串比較,把DSSI所指向的一個字型數據與ESDI所指向的一個字相減,相減結果反映到條件標誌位上。當DF=0時,令SI=SI+2DI=DI+2;當DF=1時,令SI=SI-2DI=DI-2

65.  SCAS指令——串掃描

【格式】SCASBSCASW

【功能】

       (1)   SCASBAL與字節型串中數據比較,用AL減去ESDI所指向的一個字節型數據,相減結果反映到條件標誌位上。當DF=0時,令SI=SI+1DI=DI+1;當DF=1時,令SI=SI+1DI=DI-1

       (2)   SCASWAX與字型串中數據比較,用AX減去ESDI所指向的一個字型數據,相減結果反映到條件標誌位上。當DF=0時,令SI=SI+2DI=DI+2;當DF=1時,令SI=SI-2,DI=DI-2

66.  REP前綴

【功能】當CX的值不是0時,重複執行後面的串操作指令,每執行一次,把CX的值減1,直到CX=0爲止。

67.  REPZREPNZ前綴

【功能】帶有REPZ前綴的串指令按下列方式執行:

       (1)   CX=0,則結束指令的執行,否則轉(2

       (2)   CX=CX-1

       (3)   執行一次串指令。

       (4)   ZF=0,則結束指令的執行,否則轉(2

       (5)   REPNZ的功能與REPZ僅在第(4)項不同,REPZ是在ZF=1時控制串操作重複執行,而REPNZ則是在ZF=0時控制串操作重複執行。

68.  LOCAL

【格式】LOCAL 標號1,標號2

【功能】用於告訴彙編程序,在宏展開時,對宏體中出現的“標號1”、“標號2”等標號定義,代換爲特殊的各不相同的標號。彙編程序在遇到用LOCAL說明的標號時,會代以??0000??0001?0002……等特殊的標識符,以保證宏體中的標號定義在每次宏展開時各不相同,避免重複定義的情況。

69.  有規律變化的重複

【格式】REPT n

       

        ENDM

【說明】把一組源代碼重複n次。格式中的REPTENDM是彙編語言保留字,是重複彙編的起止標誌。REPT後面的n必須是一個常量或常量標識符,表示重複次數,省略號部分是被重複的源程序代碼。

70.  無規律變化的重複

【格式】IRP     形參,<實參表>

       

        ENDM

【功能】IRPENDM是重複彙編的起止標誌,省略號表示被重複的一組指令或僞指令,形式參數是這一組指令中可變化的部分。如果實參表中有n個參數項,彙編程序將把這一組指令或僞指令重複n次,每一次用實參表中的一個參數項代替形參。

71.  控制外設的指令

【格式】IN d1d2

【功能】從d2指明的外設端口中讀取1字節或2字節數據,送到操作數d1指出的地方。

【說明】

       (1)   8088系統限制d1只能是ALAX。當外設端口號不超過255時,d2操作數可直接寫端口號碼,是外設的直接尋址方式;端口號超過255時,必須先把端口號放在DX中,以DX作爲d2操作數,這是外設的簡介尋址方式。

       (2)   d1AL時,該指令從指定的端口中讀1字節數據;當d1AX時,CPU將從d2對應的端口讀一字節數據到AL,從下一個端口號讀一字節數據到AH,即總共讀取16位數據送到AX中。

【格式】OUT d1d2

【功能】把操作數d2指明的1字節或2字節數據送到d1對應的外設端口中。

【說明】

       (1)   d2只能是ALAX。當外設端口號不超過255時,d1操作數可直接寫端口號碼;端口號超過255時,必須先把端口號放在DX中,以DX作爲d1操作數。

       (2)   d2AL時,該指令把AL中的8位數據送往d指定的外設端口;當d2AX時,該指令把AL中的8位數據送到d1對應的端口,把AH中的8位數據送往下一端口,即把16位數據送到d1對應的端口及下一端口中。

72.  與中斷有關的指令

【格式】INT n

【功能】產生一次n號中斷請求。由於這是中斷指令,屬於內中斷,具有最高級別,CPU必然響應,因此改指令將導致一次n號中斷處理過程。

【說明】

       (1)   指令格式中的n是一個立即數,用以代表中斷號,有效範圍是0255

       (2)   調用中斷服務子程序。

       (3)   指令格式中的n只要求在0255之間,沒有其他的限制。

【格式】IRET

【功能】從棧中彈出3個字,第一個彈出的送到IP,第2個到CS,第3個到PSW

【說明】這是專門爲中斷服務程序設計的一條指令,通常是中斷服務程序的最後一條指令,它的功能與中斷響應時硬件自動完成的動作相對應,從而保證不論是硬中斷還是軟中斷,在中斷服務結束後,CPU都能回到正確的位置繼續執行。

【格式】CLI

【功能】把標誌寄存器IF標誌位清0,使CPU不響應可屏蔽外中斷。

【格式】STI

【功能】把標誌寄存器的IF標誌位置1,允許CPU響應可屏蔽外中斷

3.   常用僞指令

1.   OFFSET

【功能】把保留字OFFSET加在變量名字的前面,表示取該變量的偏移地址。

例如:MOV       BXOFFSET disp

2.   SEG

【功能】SEG僞指令放在某個變量的前面,表示取該變量所在段的段地址。

例如:MOV       AXSEG disp

3.   ASSUME

【格式】ASSUME  R1:S1,R2:S2,…

【功能】ASSUME僞指令佔一行,用於指出後續程序中所使用的變量、標號等標識符在涉及到邏輯地址的段地址部分時,用哪個段寄存器作爲缺省段地址。

【說明】

       (4)   【格式】中的Ri代表段寄存器名。必須是DSESSSCS四個之一,Si時段地址,只能是一個段名或者“SEG 變量名”的形式。

       (5)   RiSi是一組對應關係,表示Si段中的標識符都使用Ri作爲缺省段寄存器。

       (6)   ASSUME可以一次指定多個對應關係,其間用逗號分隔。這種寫法實際上是多個ASSUME的簡寫形式。

       (7)   在一個完整程序中,ASSUME僞指令在程序中最少出現一次,用於知名CS與哪一個段相對應。此時,CS對應的段必須是結束僞指令“END標號”中標號所在段,從而確定程序的第一條指令在哪個段的哪個位置,稱作程序的入口地址。

       (8)   可以用ASSUME僞指令指定兩個或兩個以上的段寄存器作爲同一個段中標識符的缺省段寄存器。當數據定義與指令寫在同一個段中時,就會出現以CSDS甚至ES一起作爲一個段的缺省段寄存器的情況。此時,有關數據的操作(取值、存數等)優先以DS作爲段寄存器。

       (9)   ASSUME可以在程序的不同行上出現多次,並且可以對一個段寄存器進行兩次或兩次以上的對應關係指定。當程序中用ASSUME指定了一個段寄存器是某個段的缺省段寄存器後,在程序的後續行中一直有效,除非再次使用ASSUME僞指令改變該段寄存器與段的對應關係。

4.   PTR

【格式】類型    PTR 操作數

功能用於指定操作數類型的僞指令,它需要與類型保留字配合使用。

5.   ORG

【格式】ORG     地址表達式

【功能】ORG僞指令可以改變段中個變量定義時原有的次序,按指定情況安排各變量的偏移地址。

6.   $

【功能】$時彙編語言中的一個特殊符號,代表彙編程序在處理到$所在的位置時當前安排的偏移地址值。程序中出現的$可以作爲常量看待,但是不同位置上的$,其代表的值是不同的。與一般的數據不同的是,通常所說的常量(數值)是沒有類型的,包括“OFFSET 變量名”也沒有類型,但$所表示的數據一定是字型。$一般作爲字型變量定義時的一個初值使用。

7.   =EQU

【格式】標識符=數值表達式

【功能】定義常量

【格式】標識符  EQU     符號串

【功能】符號定義

4.   條件標誌位的設置規則

1.   CF—進位和借位標誌

CF主要用於記載兩個數據相加或相減時,最高位向外的進位或借位情況,如果有進位或借位則CF被置爲1,否則置0。參與運算的數據可以是16位的,也可以是8位的。

2.   SF—符號標誌

SF用於記載兩個有符號數運算結果的符號位。執行加減法運算時,運算結果的最高位的值會被複制到SF中。

3.   OF—溢出標誌

如果兩個帶符號數進行加法和減法運算,結果超出了帶符號數的表示範圍,則OF將被置爲1,這種現象稱爲有符號數加減法運算溢出,沒有超出範圍則OF被置爲0

4.   ZF—零標誌

ZF的設置比較簡單,如果運算結果位0,則ZF被置爲1,如果不爲0ZF被置爲0

5.   MOVADDSUBMULDIV指令對標誌位的影響

       (1)   MOV指令不影響任何標誌位,各標誌位在MOV指令執行前是什麼值,執行後仍然保持原值。

       (2)   ADD指令和SUB指令對標誌位的設置情況在前面已經說明。

       (3)   MUL指令對ZFSF無定義,這是指指令執行後對這兩個標誌位的值有影響,但它們的值沒有明確的定義,這與無影響是不同的;對於CFOF,如果乘積的高一半位0,即字節型乘法的結果AH=0或者字型乘法的結果DX=0,則CFOF都被置0,否則兩個標誌位都被置爲1。這一設置規則可以用來檢查字節相乘的積是字節還是字,或者檢查字相乘的積是字還是雙字。

       (4)   DIV指令對4個條件標誌位都無定義(注意,不是無影響)

5.   變量

1.      彙編語言對標識符命名的完整規定是:

       (1)   可用符號包括字母、數字和特殊符號“?”、“@”、“$”、“%”、“_”。

       (2)   不允許用數字作爲第一個符號。

       (3)   名字的長度沒有嚴格的限制,但一般不超過10個符號。

       (4)   最少由一個符號構成,可以是字母、“ _”或“@”。

       (5)   彙編語言不區分字母的大小寫。

2.      變量定義方法

【格式】變量定義的基本格式是:

變量名    類型       初值表

【說明】

       (1)   類型部分只能出現DBDWDDDQDT這幾種內部保留字,用以說明初值表中的每個數據佔幾個字節,對應關係如下:

DB——字節型,每個數據佔1個字節;

DW——字型,每個數據佔2字節;

DD——雙字型,每個數據佔4字節;

DQDT不作說明。

       (2)   初值表是用逗號分隔的若干個數據項,每個數據項的值是變量的一個初值項,佔據“類型”規定的字節數,所以初值表一方面說明變量的初值是多少,另一方面也指明瞭變量佔多少字節的存儲空間。

       (3)   對於DWDD類型,每個數據項的存儲遵照“高字節在高地址,低字節在低地址”的原則。

       (4)   每個數據項的書寫方法可以是任何數制的整數或者由整數構成的計算式,也可以時字符,如果用整數書寫,可以是無符號數,也可以是帶符號數。

       (5)   當類型是DB時,初值表可以是任意長度的字符串,而DW類型只允許長度不超過2的字符串。

       (6)   如果初值表需要填寫若干個相同的值,可以用下面形式表示把一個值重複若干次:

重複次數      DUP(數據項)

       (7)   初值表中可以用問號“?”作爲初值項,含義是用戶程序不設定初值,而由彙編程序安排,對此彙編程序將在翻譯時把這類初值項都以數值0填充。

       (8)   任何段中都可以寫變量定義,也允許把指令與變量定義寫在一個段內,但通常時把程序所用到的所有變量集中在一個段內進行定義,而把指令寫在另一個段中。習慣上把定義變量的段稱爲數據段,寫指令的段稱爲代碼段或指令段。

3.      變量的三個屬性

       (1)   段屬性

取變量的段地址MOV   AXSEG d1

       (2)   偏移屬性

取變量的偏移地址MOV AXOFFSET d1

取變量的偏移地址的另一種方法時用彙編語言中的一條專用指令:LEA

這兩種取偏移地址方式的不同

   尋址方式不同。用OFFSET後接變量名的形式出現的操作數是立即尋址方式,LEA指令中的源操作數是內存型尋址方式。

   LEA指令在功能上比OFFSET更強。

       (3)   類型屬性

4.      彙編程序在爲變量安排內存時遵照下面的規則:

             (1)     同一段內的變量具有相同的段地址。

             (2)     按照段中變量定義的次序,依次對各變量分配偏移地址。

             (3)     除非有其它僞指令說明,段內的第一個變量被分配在偏移地址爲0處。

             (4)     一個變量佔據內存的字節數由其類型和初值表中的項數決定。

             (5)     除非有其他僞指令說明,一個變量分配完後,緊接着分配下一個變量。

6.   單字符和字符串的輸入輸出

1.   Dos1號子功能-單字符輸入

【功能】從鍵盤讀取一個按鍵的ASCII碼值。

【入口參數】AH中放子功能號1

【出口參數】AL中是按鍵的ASCII碼。

【說明】

       (1)   該功能只要求在執行INT 21H指令時AH的值是1,而不論AH在何時、以何種指令被賦的值,這一點對所有DOS系統功能調用都是一樣的。

       (2)   調用時,計算機的屏幕上將出現一個閃爍的光標,等待操作人員按鍵;當有鍵被按下後,取出該鍵的ASCII值放入AL

       (3)   Pascal中的read標準過程不同,該功能只需要按一個鍵即可,而不像read一直要等到操作人員按下回車鍵。

       (4)   每次只讀取一個按鍵,並且按下的符號會顯示在屏幕上,退格鍵、回車鍵等特殊按鍵也會被當作有效輸入。下面是幾個特殊按鍵與AL中讀取結果的對應關係:按ESC鍵-AL=1BH,按回車鍵-AL=0DH,按退格鍵-AL=08H

       (5)   如果讀回車鍵的ASCII碼值是0,表示按下的是一個擴展ASCII範圍的鍵,這時可再讀一次,以獲得該鍵的擴展ASCII值。

       (6)   調用後不改變除AL外的其他寄存器的值,包括AH中的1

2.   DOS2號子功能-單字符輸出

【功能】在屏幕上光標當前所在位置顯示一個字符,並把光標向後移一格。

【入口參數】AH中放子功能號2DL中放待輸出字符的ASCII值。

【出口參數】

【說明】

       (1)   該子功能在執行時不論DL中數據的來源如何,都當做是一格ASCII值,經過內部轉換變成相應字符的形狀顯示在屏幕上。

       (2)   該子功能調用會改變寄存器AL的值,所以必要時其中的值可放在另一寄存器或內存中臨時保存,其他寄存器的值都不受影響。

       (3)   有些特殊的ASCII值可以控制計算機產生特定的效果。比如,當DL中放入7並調用該子功能時,計算機的喇叭會發出“嘀”的一聲響,而屏幕上並沒有任何字符輸出。部分特殊效果與ASCII值的對應關係:07H-發出嘀的一聲,08H-光標在同一行上向左移動一格,0AH-光標在同列上向下移動一行,0DH-光標移到所在行的最左端。

3.   字符串輸出

【入口參數】AH=9,是DOS的子功能號

        DS:DX=待輸出字符串的首字符的邏輯地址

【說明】

       (1)   被輸出的字符串的長度不限,但必須連續存放在內存的某個地方,且以ASCII值爲24H的字符‘$’結束,中間可以含有回車符、換行符、響鈴符等特殊功能符號,存放字符串的起始邏輯地址必須放在指定的寄存器DSDX中。

       (2)   $’符本身不輸出到屏幕。

       (3)   調用結果是把字符串中的各個字符從光標當前所在位置起,依次顯示在屏幕上,直至遇到‘$’爲止,光標停在最後一個輸出符號的後面。

       (4)   如果程序中需要輸出‘$’,只能用2號子功能實現。

       (5)   9號子功能調用將影響AL的內容,不改變其餘寄存器及標誌位寄存器的值。

字符串輸入

【入口參數】AH=0AH,是DOS的子功能號10

        DSDX=輸入緩衝區的起始邏輯地址

【出口參數】DOS10號子功能在輸入緩衝區中填寫實際輸入情況,即根據鍵盤輸入情況,對圖5.3中的“實際輸入字符數”和“輸入串的各個字符”部分進行填寫。

【說明】

       (1)   輸入緩衝區是一段連續的內存區,首地址必須在調用10子功能前放到指定的寄存器DSDX中。

       (2)   10號子功能在調用時等待操作員從鍵盤上按鍵,直到按下回車鍵爲止,按鍵情況會顯示在屏幕上,最後按下的回車鍵會導致回車操作。如果在按回車鍵之前發現輸入有錯誤,可以使用退格鍵或向左的箭頭進行修改。

       (3)   輸入緩衝區的最前面一個字節的值由用戶程序填寫,用以指出允許輸入的最大字符數。該值是字節型無符號數,有效範圍是0255,最後按的回車鍵也計算在內。當已輸入len1-1個字符後就只能按回車鍵了,按其他鍵都會被認爲是不正確的輸入而不被機器認可,並且喇叭還會發出“嘀”的一聲響以示警告。如果len1=1,表示只能按1個鍵,這個鍵只能是回車鍵,按其他鍵都會有“嘀”的一聲警告;如果len1=0,表示一個鍵都不能按,包括回車鍵在內的任何按鍵都會被拒絕並且發出“嘀”的警告聲,但機器又在等待輸入這一矛盾將導致無限期等待,即死機。

7.   堆棧和子程序

1.   定義堆棧段的方法

【格式】

        段名    SEGMENT STACK

                DW      nDUP(?)

        段名    ENDS

【說明】

       (1)   保留字STACK是堆棧段的專用符號,SEGMENT後面的保留字STACK表明這個段專供堆棧使用。

       (2)   段定義中用“DW        n DUP(?)”說明堆棧所用內存區的大小爲2n字節,其中n是一個常量。可根據程序需要,調節堆棧段的大小。

       (3)   按基本格式定義的棧是一個空棧,棧中沒有存放有效數據。

       (4)   爲了使SSSP在程序執行時取得正確的值,必須在源程序中寫一條僞指令:
ASSUME                SS
:堆棧段段名
但不需要像DSES一樣在程序中用指令進行賦值。

2.   進棧
PUSH指令

3.   出棧
POP指令

4.   PUSHFPOPF指令

5.   定義子程序的方法

子程序名        PROC    類型

                指令序列

子程序名        ENDP

6.   參數傳遞的方法

       (1)   通用寄存器傳值。

       (2)   通用寄存器傳地址。

       (3)   標誌寄存器傳遞邏輯型數據。

       (4)   用數據段中已定義的變量存放參數。

       (5)   用堆棧傳遞。

8.  

1.      宏定義

【格式】宏名 MACRO [形式參數表]

                   宏體

                   ENDM

【說明】

       (1)   “宏名”是一個標識符,一個程序中可以定義多個宏,對每一個宏必須以不同的標識符命名,且宏名不能與變量、標號、段名等標識符同名。

       (2)   彙編語言規定,宏定義的起始標記MACRO前面必須寫宏的名字,而結束標記ENDM的前面卻不允許寫任何內容,寫在起止標記之間的部分稱爲宏體,宏體部分通常是一段程序中需要重複使用的指令。序列。

       (3)   宏定義僅僅是告訴彙編程序,將來宏調用時複製的對象是什麼,宏定義中的程序段並不是程序的一部分,也就是說,如果程序中定義了一個宏而沒有調用它,彙編程序將忽略宏定義。

       (4)   宏定義可以寫在程序的任何地方,但習慣上總是把宏定義寫在程序的最前面。

       (5)   形式參數可以在宏體中的任何位置。

       (6)   宏的形式參數可以作爲一個標識符的一部分,這時,必須用符號“&”把形式參數與標識符的其餘部分分開。

2.      帶標號的宏——LOCAL

9.   常駐內存技術

【駐留方法】在AH中放32H,在DX中放需要駐留的程序的節長度,然後以INT 21H指令調用DOS的結束並駐留子功能。

【說明】

       (1)   駐留前要告訴DOS,駐留程序的長度是多少。方法是把駐留長度放在DX中,長度單位是“節”而不是字節,1節等於16個字節。如果需要駐留的程序長度是n字節,則DX的值可通過下面的計算式算得:
                DX=
n/10H+1+10H
其中(你/10H+1是計算出駐留程序需要多少“節”,加1是爲了預防駐留程序以字節計算的長度不是10的整倍數。再加16節是因爲每個程序在調用內存時,操作系統都爲它安排了一個稱爲“程序段前綴(PSP)”的專用內存區,並且放在程序的前面,這個程序段前綴的長度是256字節,剛好16節,它必須與需要駐留的程序一起駐留在內存。

10. 修改中斷向量技術

【設置中斷向量】

入口參數:AH=25H

          AL=中斷號

             DSDX=新的中斷服務程序的入口地址

調用:INT 21H

 
發佈了28 篇原創文章 · 獲贊 0 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章