Transcript Chapter 4
單元4:資料轉移、定址和算術 章節概念 • • • • • 資料轉移指令 加法與減法 資料相關的運算子和指引 間接定址 JMP和LOOP指令 直接位移指令 • • • • • • • 運算元型別 命令運算元表示法 直接記憶運算元 MOV 指令 整數的補零/符號擴展 XCHG 指令 直接位移指令 運算元型別 • 三種類型的指令運算 • 立即 – 一個連續整數 (8, 16, or 32 bits) • value is encoded within the instruction • 暫存器 – the name of a register • register name is converted to a number and encoded within the instruction • 記憶體 – reference to a location in memory • memory address is encoded within the instruction, or a register holds the address of a memory location 命令運算元表示法 直接記憶體運算元 • 變數名稱參照 (reference) 的是資料區段中的位移值。 • 程式碼會含有能使用記憶體運算元的位址,來解參 照 (dereference) 該運算元的指令。 .data var1 BYTE 10h .code mov al,var1 mov al,[var1] alternate format ; AL = 10h ; AL = 10h MOV 指令 • 指令會將資料從來源運算元複製到目的運算元。 語法: MOV 目的地 , 來源 • 兩個運算元必須具有相同的大小。 • CS、EIP 及 IP 不可以當作目的運算元。 • 兩個運算元不能都是記憶體運算元。 • 一個立即值不能搬移至區段暫存器。 .data count BYTE 100 wVal WORD 2 .code mov bl,count mov ax,wVal mov count,al mov al,wVal mov ax,count mov eax,count ; error ; error ; error 換你 . . . 解釋為什麼下列的MOV指令都是有錯誤的?? : .data bVal BYTE 100 bVal2 BYTE ? wVal WORD 2 dVal DWORD 5 .code mov ds,45 mov esi,wVal mov eip,dVal mov 25,bVal mov bVal2,bVal 不被允許直接向DS移動 大小不同 EIP 不能當目的地的 立即的數值是不能當目的地的 兩個運算元都是記憶體是不被允許的 整數的補零 當你複製小的運算元到大的運算元時, 這個MOVZX指令會將它的剩 餘各位元填上零值。 mov bl,10001111b movzx ax,bl ; 整數的補零 目的地一定是一個暫存器. 符號擴展 ,它會複製 來源運算元的內容到目的運算元,並且不論目的運 算元是 16 位元或 32 位元,都會將它 的剩餘各位元填上符號位 元。 mov bl,10001111b movsx ax,bl ; 符號的擴展 目的地一定要是暫存器. XCHG 指令 XCHG將兩個運算元的內容互相 交換. 其中一個運算元一定是一 個暫存器. 沒有立即的運算元是被充許的. .data var1 WORD 1000h var2 WORD 2000h .code xchg xchg xchg xchg ax,bx ah,al var1,bx eax,ebx xchg var1,var2 ;將兩個16位元暫存器的內容互相交換 ;將兩個0位元暫存器的內容互相交換 ;將16位元的記憶體運算元與 BX 互相交換 ;將兩個32位元暫存器的內容互相交換 ; 錯誤: 兩個都是記憶運算元 直接位移運算元 我們可將某個移位值加到一個變數名稱上,因而建立直接位移運 算元。 這讓程式設計員 可以針對沒有明確標籤的記憶體位址進行存取 的動作。 .data arrayB BYTE 10h,20h,30h,40h .code mov al,arrayB+1 mov al,[arrayB+1] ; AL = 20h ; alternative notation Q:為何 arrayB+1 不產生 11h? 直接位移運算元(內容) 我們可將某個移位值加到一個變數名稱上,因而建立直接位移運 算元。 這讓程式設計員 可以針對沒有明確標籤的記憶體位址進行存取 的動作。 .data arrayW WORD 1000h,2000h,3000h arrayD DWORD 1,2,3,4 .code mov ax,[arrayW+2] ; AX = 2000h mov ax,[arrayW+4] ; AX = 3000h mov eax,[arrayD+4] ; EAX = 00000002h ;下列的陳述必須集合嗎? mov ax,[arrayW-2] mov eax,[arrayD+16] ; ?? ; ?? 當執行的時候會發生什麼事?? 換你. . . Write a program that rearranges the values of three doubleword values in the following array as: 3, 1, 2. .data arrayD DWORD 1,2,3 • 步驟1: 將第1個值複製到EAX裡接著在第二個位置交換這個值 mov eax,arrayD xchg eax,[arrayD+4] • 步驟2: Exchange EAX with the third array value and copy the value in EAX to the first array position. xchg eax,[arrayD+8] mov arrayD,eax 評估一下 . . . • 我們想寫一個可以增加下列三個位元組的程式: .data myBytes BYTE 80h,66h,0A5h • 你對下列編碼的評估是什麼? mov al,myBytes add al,[myBytes+1] add al,[myBytes+2] • 你對下列編碼的評估是什麼? mov ax,myBytes add ax,[myBytes+1] add ax,[myBytes+2] • 有其他問題?? 評估一下 . . . (續) .data myBytes BYTE 80h,66h,0A5h • 下列的編碼怎麼樣?? 有任何的缺少嗎? movzx mov add mov add ax,myBytes bl,[myBytes+1] ax,bx bl,[myBytes+2] ax,bx ; AX = sum Yes: 在MOVZX指令之前將0移動至BX暫存器裡 下一章 • • • • • 資料轉移指令 加法與減法 資料相關的運算子和指引 間接定址 JMP和LOOP指令 加法與減法 • • • • • INC及DEC指令 ADD及SUB指令 NEG指令 建立算術運算式 算術運算影響的旗標 • • • • 零值旗標 符號旗標 進位旗標 溢位進旗 INC及DEC指令 • INC ( 遞增 ) 和 DEC ( 遞減 ) 指令分別會將其單一運算元 加 1 和減 1。 • 運算元也許是暫存器或記憶體 • INC 目的地 • 邏輯: 目的地 目的地 + 1 • DEC 目的地 • 邏輯: 目的地 目地的 – 1 INC和DEC範例 .data myWord WORD 1000h myDword DWORD 10000000h .code inc myWord dec myWord inc myDword mov inc mov inc ax,00FFh ax ax,00FFh al ; 1001h ; 1000h ; 10000001h ; AX = 0100h ; AX = 0000h 換你... 在每一個指令執行後,請顯示出目的地運算元的值: .data myByte .code mov mov dec inc dec BYTE 0FFh, 0 al,myByte ah,[myByte+1] ah al ax ; ; ; ; ; AL AH AH AL AX = = = = = FFh 00h FFh 00h FEFF ADD和SUB指令 • ADD 目的地,來源 • 邏輯: 目的地 目地的 + 來源 • SUB目地的 ,來源 • Logic: 目的地 目地的 – 來源 • 和MOV指令的規則相同 ADD及SUB範例 .data var1 DWORD 10000h var2 DWORD 20000h .code mov eax,var1 add eax,var2 add ax,0FFFFh add eax,1 sub ax,1 ; ; ; ; ; ; ---EAX--00010000h 00030000h 0003FFFFh 00040000h 0004FFFFh NEG (否定)指令 顛倒運算元的符號(即轉變為2’s補數)。 運算元可以是暫存器或記憶體運算元。 .data valB BYTE -1 valW WORD +32767 .code mov al,valB neg al neg valW ; AL = -1 ; AL = +1 ; valW = -32767 假使AX包含 –32,768 並且我們對它執行NEG指令, 將會得到 一個有效的結果嗎? NEG指令和旗標 使用NEG指令來執行下面的程式: SUB 0,operand 任何的非零運算元引起要設定的進位旗標 .data valB BYTE 1,0 valC SBYTE -128 .code neg valB neg [valB + 1] neg valC ; CF = 1, OF = 0 ; CF = 0, OF = 0 ; CF = 1, OF = 1 建立算術運算式 HLL 編輯者將數學的表達轉變成組合語言 你也可以做的到.。範例: Rval = -Xval + (Yval – Zval) Rval DWORD ? Xval DWORD 26 Yval DWORD 30 Zval DWORD 40 .code mov eax,Xval neg eax mov ebx,Yval sub ebx,Zval add eax,ebx mov Rval,eax ; EAX = -26 ; EBX = -10 ; -36 換你... 將下面的意思轉換成組合語言。 不能變更 Xval, Yval, or Zval : Rval = Xval - (-Yval + Zval) 假設所有的值皆被標示成doublewords. mov neg add mov sub mov ebx,Yval ebx ebx,Zval eax,Xval eax,ebx Rval,eax 算術運算影響的旗標 • ALU有反映算術行動結果的一些狀態旗標。 • 建立目的地運算元的內容 • 必要的旗標: • • • • 零值旗標 – 當目的地等於零的時候設定 符號旗標 – 當目的地是負數的時候設定 進位旗標 – 當未被標示的值超出範圍時設定 溢位旗標 – 當被標示的值超出範圍時設定 • MOV指令不會影響到任何旗標。 觀念圖 CPU 部份 執行 執行 ALU 條件跳躍 算術 & bitwise 操作 附加在 影響 被使用 提拱 狀態旗標 分岐邏輯 你能使用像如此的圖形表達在組合語言觀念之間的關係。 零值旗標 (ZF) 零值旗標是設定於目的地運算元其操作結果為零的時候。 mov sub mov inc inc cx,1 cx,1 ax,0FFFFh ax ax ; CX = 0, ZF = 1 ; AX = 0, ZF = 1 ; AX = 1, ZF = 0 記得... • 當它等於1的時候設定旗標。 • 當它等於0的時候清除旗標。 符號旗標 (SF) 符號旗標是設定於目的地運算元其結果為負數的時候。 當其結果為實數時則被清除。 mov cx,0 sub cx,1 add cx,2 ; CX = -1, SF = 1 ; CX = 1, SF = 0 目的運算元的最大有效位元呈現設定 狀態,則符號旗標 將呈現設定狀態。 mov al,0 sub al,1 add al,2 ; AL = 11111111b, SF = 1 ; AL = 00000001b, SF = 0 標示與未標示的整數 硬體的觀念 • 所有CPU指令中,標示與未標示的整數操作完全一構 • CPU是無法分辨出是否有標示 • 你,程式設計師,獨自負責在每個命令使用每個正確的資 料類型 Added Slide. Gerald Cahill, Antelope Valley College 溢位及進位旗標 硬體觀念 • 如何那增加指令和 CF : • OF = (MSB 實行) XOR (進入 MSB 之內的進位) • CF = (MSB 實行) • 附屬的指令如何修正和 CF : • NEG 來源而且把它加入目的地 • OF = (MSB實行) XOR (進入 MSB 之內的進位) • CF = INVERT (MSB實行) MSB = 最大有效位元 XOR =互斥邏輯閘 NEG =否定 進位旗標 (CF) 進位旗標可以指出無號整數的溢位狀態 (目地的運算元太大或太小) mov al,0FFh add al,1 ; CF = 1, AL = 00 ; Try to go below zero: mov al,0 sub al,1 ; CF = 1, AL = FF 換你 . . . 從下列程式中,表示出目的地運算位的值、符號旗標的值、 零值旗標的值、進位旗標的值 mov add sub add mov add ax,00FFh ax,1 ax,1 al,1 bh,6Ch bh,95h mov al,2 sub al,3 ; AX= 0100h ; AX= 00FFh ; AL= 00h SF= 0 ZF= 0 CF= 0 SF= 0 ZF= 0 CF= 0 SF= 0 ZF= 1 CF= 1 ; BH= 01h SF= 0 ZF= 0 CF= 1 ; AL= FFh SF= 1 ZF= 0 CF= 1 溢位旗標 (OF) 當有號數算術運算的結果使目的運算元溢位或 欠位時,溢位旗 標將呈現設定狀態 ; Example 1 mov al,+127 add al,1 ; Example 2 mov al,7Fh add al,1 ; OF = 1, AL = ?? ; OF = 1, AL = 80h 這兩個範例在二進位的標準是相同的,因為7Fh等於 +127。 要決定目的地運算元的值, 在十六進位中通 常是比較容易去計算的。 概略的做法 • 當要增加二個整數時,記得溢位旗標只設定在… • 兩個正值運算元在相加後的總數是負數時 • 兩個負值運算元在相加後的總數是正數時 溢位旗標的值是多少? mov al,80h add al,92h ; OF = 1 mov al,-2 add al,+127 ; OF = 0 換你 . . . 在執行後給定旗標的值是多少? mov al,-128 neg al ; CF = 1 OF = 1 mov ax,8000h add ax,2 ; CF = 0 OF = 0 mov ax,0 sub ax,2 ; CF = 1 OF = 0 mov al,-5 sub al,+125 ; OF = 1 下一章 • • • • • 資料轉移指令 加法與減法 資料相關的運算子和指引 間接定址 JMP和LOOP指令 資料相關的運算子和指引 • • • • • • OFFSET運算子 PTR運算子 TYPE運算子 LENGTHOF運算子 SIZEOF運算子 LABEL指引 OFFSET運算子 • OFFSET 運算子會回傳資料標籤的位移。位移代表的 是標籤到資料區段起始點的距離,其 單位是位元組。 • 在保護模式下位移有 32 位元 • 在實體位址模式下位移只有 16 位元 在保護模式下的程式我們只有撰寫一部份 (我們使用的是平 坦式記憶體模式) OFFSET範例 讓我們假定資料部份從00404000h 開始: .data bVal BYTE ? wVal WORD ? dVal DWORD ? dVal2 DWORD ? .code mov esi,OFFSET mov esi,OFFSET mov esi,OFFSET mov esi,OFFSET bVal wVal dVal dVal2 ; ; ; ; ESI ESI ESI ESI = = = = 00404000 00404001 00404003 00404007 Relating to C/C++ 被OFFSET送回的的值是一個指標。 比較C++語言寫的編碼和程式語言寫的編碼: ; C++ 版本: char array[1000]; char * p = array; .data array BYTE 1000 DUP(?) .code mov esi,OFFSET array ; ESI is p PTR運算子 使用 PTR 運算子,來置換一個運算元已被宣告的空間大小值。 這只有在你想要 存取的變數的空間大小屬性與當初宣告該變數 的大小屬性不同時才須要用到。 .data myDouble DWORD 12345678h .code mov ax,myDouble ; error – why? mov ax,WORD PTR myDouble ; loads 5678h mov WORD PTR myDouble,4321h ; saves 4321h 當儲存資料在記憶的時候,小 endian 次序被使用的取消(參 考第3.4.9節)。 rd 小 Endian 次序 • 小 endian 次序提及英代爾在記憶儲存整數的方式. • 多位元組整數被儲存在反面的次序中,藉由被儲存在 最低的位址的最沒有重要的位元組 • 舉例來說, doubleword 12345678h 將會被儲存當做: word byte offset 78 5678 78 0000 myDouble 34 當整數從記憶到暫存器被裝載的時 +1 0001 myDouble 候,位元組再自動地進入他們的正 確位置之內被顛倒. 0002 myDouble + 2 12 0003 myDouble + 3 56 1234 PTR運算子範例 .data myDouble DWORD 12345678h mov mov mov mov mov al,BYTE al,BYTE al,BYTE ax,WORD ax,WORD PTR myDouble PTR [myDouble+1] PTR [myDouble+2] PTR myDouble PTR [myDouble+2] ; ; ; ; ; AL AL AL AX AX = = = = = 78h 56h 34h 5678h 1234h PTR運算子(續) PTR 也能用來結合一個更小的資料類型的要素並且移動他們 進入一個更大的運算元之內。 CPU必須自動的顛倒位元組。 .data myBytes BYTE 12h,34h,56h,78h .code mov ax,WORD PTR [myBytes] mov ax,WORD PTR [myBytes+2] mov eax,DWORD PTR myBytes ; AX = 3412h ; AX = 7856h ; EAX = 78563412h 換你 . . . 寫下每個目的地運算元的值: .data varB BYTE 65h,31h,02h,05h varW WORD 6543h,1202h varD DWORD 12345678h .code mov ax,WORD PTR [varB+2] mov bl,BYTE PTR varD mov bl,BYTE PTR [varW+2] mov ax,WORD PTR [varD+2] mov eax,DWORD PTR varW ; ; ; ; ; a. 0502h b. 78h c. 02h d. 1234h e. 12026543h TYPE運算子 TYPE 運算子會回傳變數的單一元素的大小,其單 位是位元組。 .data var1 BYTE ? var2 WORD ? var3 DWORD ? var4 QWORD ? .code mov eax,TYPE mov eax,TYPE mov eax,TYPE mov eax,TYPE var1 var2 var3 var4 ; ; ; ; 1 2 4 8 LENGTHOF運算子 LENGTHOF 運算子會計算陣列中的元素數目,而此數目是 由與標籤位於同一行的若干個 值所定義。 .data byte1 BYTE 10,20,30 array1 WORD 30 DUP(?),0,0 array2 WORD 5 DUP(3 DUP(?)) array3 DWORD 1,2,3,4 digitStr BYTE "12345678",0 LENGTHOF ; 3 ; 32 ; 15 ; 4 ; 9 .code mov ecx,LENGTHOF array1 ; 32 SIZEOF運算子 SIZEOF 運算子所回傳的值,等於 LENGTHOF 乘以 TYPE 的值。 .data byte1 BYTE 10,20,30 array1 WORD 30 DUP(?),0,0 array2 WORD 5 DUP(3 DUP(?)) array3 DWORD 1,2,3,4 digitStr BYTE "12345678",0 SIZEOF ; 3 ; 64 ; 30 ; 16 ; 9 .code mov ecx,SIZEOF array1 ; 64 跨越倍數排成一行(1 of 2) 如果每條列(除最後)以一個逗點結束,資料公告跨越多條列。 LENGTHOF 和 SIZEOF 運算包括屬於公告的所有的列: .data array WORD 10,20, 30,40, 50,60 .code mov eax,LENGTHOF array mov ebx,SIZEOF array ; 6 ; 12 跨越倍數排成一行(2 of 2) 在下列的例子中,排列只識別第一字公告.在先前的幻燈片中 比較在這裡被 LENGTHOF 和 SIZEOF 歸還的價值和那些在 先前的幻燈片中比較在這裡被 LENGTHOF 和 SIZEOF 歸還 的價值和那些: .data array WORD 10,20 WORD 30,40 WORD 50,60 .code mov eax,LENGTHOF array mov ebx,SIZEOF array ; 2 ; 4 LABEL指引 • LABEL 指引可以讓我們插入標籤,並且在不配置任何 記憶體的情形下,給予它空間大小的屬性。 • LABEL 可以與任何一種標準的空間大小屬性搭配使用 • 替接下來要在資料區段中 宣告的變數,提供另一個名 稱和空間大小屬性。 .data dwList LABEL DWORD wordList LABEL WORD intList BYTE 00h,10h,00h,20h .code mov eax,dwList ; 20001000h mov cx,wordList ; 1000h mov dl,intList ; 00h 下一章 • • • • • 資料轉移指令 加法與減法 資料相關的運算子和指引 間接定址 JMP和LOOP指令 間接定址 • • • • 間接運算元 陣列 索引運算元 指標 間接運算元(2之1) 一個間接的運算元支撐變數的位址,通常排列或者字串.它可能 是 dereferenced. (僅僅喜歡一個指針) .data val1 BYTE 10h,20h,30h .code mov esi,OFFSET val1 mov al,[esi] ; dereference ESI (AL = 10h) inc esi mov al,[esi] ; AL = 20h inc esi mov al,[esi] ; AL = 30h 間接運算元(2之2) 使用 PTR 澄清記憶運算元的大小屬性. .data myCount WORD 0 .code mov esi,OFFSET myCount inc [esi] inc WORD PTR [esi] ; error: ambiguous ; ok PTR 應該在這裡被使用嗎? add [esi],20 yes, because [esi] could point to a byte, word, or doubleword 陣列 間接的運算元對穿越排列是理想的。注意那暫存器在支架一定要 是增量被一價值與那相配排列類型。 .data arrayW .code mov mov add add add add WORD 1000h,2000h,3000h esi,OFFSET arrayW ax,[esi] esi,2 ax,[esi] esi,2 ax,[esi] ; or: add esi,TYPE arrayW ; AX = sum of the array ToDo:為 doublewords 的排列修正這一個例子。 索引運算元 為 doublewords 的排列修正這一個例子一個被編入索引的運算 元把一個常數加入一個暫存器產生一個有效的位址。有二種 notational 表格: [label + reg] .data arrayW WORD 1000h,2000h,3000h .code mov esi,0 mov ax,[arrayW + esi] mov ax,arrayW[esi] add esi,2 add ax,[arrayW + esi] etc. label[reg] ; AX = 1000h ; alternate format ToDo:為 doublewords 的排列修正這一個例子. 索引運算元中的比例因子* 為 doublewords 的排列修正這一個例子你元。能依比例決定對 排列元素的抵銷一個間接的或編入索引運算這被藉由繁殖排列的 類型的索引做: .data arrayB BYTE 0,1,2,3,4,5 arrayW WORD 0,1,2,3,4,5 arrayD DWORD 0,1,2,3,4,5 .code mov esi,4 mov al,arrayB[esi*TYPE arrayB] mov bx,arrayW[esi*TYPE arrayW] mov edx,arrayD[esi*TYPE arrayD] ; 04 ; 0004 ; 00000004 指標 你能宣布一個包含另一個變數的抵銷的指標變數。 .data arrayW WORD 1000h,2000h,3000h ptrW DWORD arrayW .code mov esi,ptrW mov ax,[esi] ; AX = 1000h 輪流格式: ptrW DWORD OFFSET arrayW 下一章 • • • • • 資料轉移指令 加法與減法 資料相關的運算子和指引 間接定址 JMP和LOOP指令 JMP和LOOP指令 • • • • • JMP 指令 LOOP 指令 LOOP 例題 總計一個整數排列 複製字串 JMP 指令 • JMP 對標籤是一次無條件的跳躍哪一通常在相同的程序裡面. • Syntax: JMP 目標 • Logic: EIP 目標 • 例題: top: . . jmp top 在現在的程序之外的一次跳躍一定要到被稱為通用的標籤的特別類型的 標籤。(細節到第 5.5.2.3 節) LOOP 指令 • loop指令創造一個計算的loop • Syntax: LOOP 目標 • 邏輯: • ECX ECX – 1 • if ECX != 0,跳到目標 • 履行˙: • 在下列指令的抵銷和目標標籤的抵銷之間在位元組中組合 器計算距離。它叫做相關抵銷。 • 相關抵銷被加到 EIP 。 LOOP 例題 下列的loop計算整數的總數 5 + 4 + 3 +2 + 1: offset machine code source code 00000000 00000004 66 B8 0000 B9 00000005 mov mov 00000009 0000000C 0000000E 66 03 C1 E2 FB ax,0 ecx,5 L1: add ax,cx loop L1 當loop被裝配的時候,現在的地點=0000000 E(下一個指令的抵銷). -5(FBh)被加到現在的地點,導致一次跳躍到地點 00000009 : 00000009 0000000E + FB 習題. . . 如果相關抵銷在一個被符號的位元組中被編碼, (a)最大的可能向後地跳躍? (b)最大的可能向前地跳躍? (a) -128 (b) +127 習題 . . . mov ax,6 mov ecx,4 AX的終值是多少? L1: inc ax loop L1 10 迴圈次數是多少? 4,294,967,296 mov ecx,0 X2: inc ax loop X2 巢狀迴圈 如果你需要在一個迴圈裡面把一個迴圈編碼,你一定要保存外部 的迴圈計算器的 ECX 價值在下列的例子中,外部的迴圈執行 100 次,和內部的迴圈 20 次. .data count DWORD ? .code mov ecx,100 L1: mov count,ecx mov ecx,20 L2: . . loop L2 mov ecx,count loop L1 ; set outer loop count ; save outer loop count ; set inner loop count ; repeat the inner loop ; restore outer loop count ; repeat the outer loop 總計一個整數排列 下列的密碼計算 16 位元整數排列的總數. .data intarray WORD 100h,200h,300h,400h .code mov edi,OFFSET intarray mov ecx,LENGTHOF intarray mov ax,0 L1: add ax,[edi] add edi,TYPE intarray loop L1 ; address of intarray ; loop counter ; zero the accumulator ; add an integer ; point to next integer ; repeat until ECX = 0 習題. . . 如果你正在總計 doubleword 排列,你將 會在先前幻燈片上的計畫改變什麼? 複制字串 下列的密碼複印從來源到目標的字串: .data source target .code mov mov L1: mov mov inc loop BYTE BYTE "This is the source string",0 SIZEOF source DUP(0) esi,0 ecx,SIZEOF source ; index register ; loop counter al,source[esi] target[esi],al esi L1 ; ; ; ; good use of SIZEOF get char from source store it in the target move to next character repeat for entire string 習題. . . 重寫在先前的幻燈片中被顯示的計畫,使 用間接的位址不願編入索引位址. 摘要 • 資料轉移 • MOV –目的運算元 , 來源運算元 • MOVSX, MOVZX, XCHG • 運算元類型 • direct, direct-offset, indirect, indexed • 算術 • INC, DEC, ADD, SUB, NEG • Sign, Carry, Zero, Overflow flags • 運算子 • OFFSET, PTR, TYPE, LENGTHOF, SIZEOF, TYPEDEF • JMP 和 LOOP –分岐指令 The End