單元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 ; AL = 10h mov al,[var1] ; AL = 10h alternate format
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 ; error mov ax,count ; error mov eax,count ; 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 ax,bx ;將兩個16位元暫存器的內容互相交換 xchg ah,al ;將兩個0位元暫存器的內容互相交換 xchg var1,bx ;將16位元的記憶體運算元與 BX 互相交換 xchg eax,ebx ;將兩個32位元暫存器的內容互相交換 xchg var1,var2 ; 錯誤: 兩個都是記憶運算元
直接位移運算元 我們可將某個移位值加到一個變數名稱上,因而建立直接位移運算元。 這讓程式設計員 可以針對沒有明確標籤的記憶體位址進行存取的動作。 .data arrayB BYTE 10h,20h,30h,40h .code mov al,arrayB+1 ; AL = 20h mov al,[arrayB+1] ; 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] 有其他問題??
評估一下 . . . (續) Yes: 在MOVZX指令之前將0移動至BX暫存器裡 下列的編碼怎麼樣?? 有任何的缺少嗎? .data myBytes BYTE 80h,66h,0A5h 下列的編碼怎麼樣?? 有任何的缺少嗎? movzx ax,myBytes mov bl,[myBytes+1] add ax,bx mov bl,[myBytes+2] add ax,bx ; AX = sum Yes: 在MOVZX指令之前將0移動至BX暫存器裡
下一章 資料轉移指令 加法與減法 資料相關的運算子和指引 間接定址 JMP和LOOP指令
加法與減法 INC及DEC指令 ADD及SUB指令 NEG指令 建立算術運算式 算術運算影響的旗標 零值旗標 符號旗標 進位旗標 溢位進旗
INC及DEC指令 INC 目的地 DEC 目的地 運算元也許是暫存器或記憶體 INC 目的地 邏輯: 目的地 目的地 + 1 DEC 目的地 邏輯: 目的地 目地的 – 1
INC和DEC範例 .data myWord WORD 1000h myDword DWORD 10000000h .code inc myWord ; 1001h dec myWord ; 1000h inc myDword ; 10000001h mov ax,00FFh inc ax ; AX = 0100h inc al ; AX = 0000h
換你... 在每一個指令執行後,請顯示出目的地運算元的值: .data myByte BYTE 0FFh, 0 .code mov al,myByte ; AL = mov ah,[myByte+1] ; AH = dec ah ; AH = inc al ; AL = dec ax ; AX = FFh 00h FEFF
ADD和SUB指令 ADD 目的地,來源 SUB目地的 ,來源 和MOV指令的規則相同 邏輯: 目的地 目地的 + 來源 Logic: 目的地 目地的 – 來源 和MOV指令的規則相同
ADD及SUB範例 .data var1 DWORD 10000h var2 DWORD 20000h .code ; ---EAX--- mov eax,var1 ; 00010000h add eax,var2 ; 00030000h add ax,0FFFFh ; 0003FFFFh add eax,1 ; 00040000h sub ax,1 ; 0004FFFFh
NEG (否定)指令 顛倒運算元的符號(即轉變為2’s補數)。 運算元可以是暫存器或記憶體運算元。 .data valB BYTE -1 valW WORD +32767 .code mov al,valB ; AL = -1 neg al ; AL = +1 neg valW ; valW = -32767 假使AX包含 –32,768 並且我們對它執行NEG指令, 將會得到一個有效的結果嗎?
NEG指令和旗標 使用NEG指令來執行下面的程式: SUB 0,operand 任何的非零運算元引起要設定的進位旗標 .data valB BYTE 1,0 valC SBYTE -128 .code neg valB ; CF = 1, OF = 0 neg [valB + 1] ; CF = 0, OF = 0 neg valC ; 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 ; EAX = -26 mov ebx,Yval sub ebx,Zval ; EBX = -10 add eax,ebx mov Rval,eax ; -36
換你... 將下面的意思轉換成組合語言。 不能變更 Xval, Yval, or Zval : Rval = Xval - (-Yval + Zval) 假設所有的值皆被標示成doublewords. mov ebx,Yval neg ebx add ebx,Zval mov eax,Xval sub eax,ebx mov Rval,eax
算術運算影響的旗標 ALU有反映算術行動結果的一些狀態旗標。 必要的旗標: MOV指令不會影響到任何旗標。 建立目的地運算元的內容 零值旗標 – 當目的地等於零的時候設定 符號旗標 – 當目的地是負數的時候設定 進位旗標 – 當未被標示的值超出範圍時設定 溢位旗標 – 當被標示的值超出範圍時設定 MOV指令不會影響到任何旗標。
觀念圖 你能使用像如此的圖形表達在組合語言觀念之間的關係。 CPU ALU 條件跳躍 算術 & bitwise 操作 狀態旗標 分岐邏輯 部份 執行 執行 ALU 條件跳躍 算術 & bitwise 操作 附加在 被使用 提拱 影響 狀態旗標 分岐邏輯 你能使用像如此的圖形表達在組合語言觀念之間的關係。
零值旗標 (ZF) 零值旗標是設定於目的地運算元其操作結果為零的時候。 記得... 當它等於1的時候設定旗標。 當它等於0的時候清除旗標。 mov cx,1 sub cx,1 ; CX = 0, ZF = 1 mov ax,0FFFFh inc ax ; AX = 0, ZF = 1 inc ax ; AX = 1, ZF = 0 記得... 當它等於1的時候設定旗標。 當它等於0的時候清除旗標。
符號旗標 (SF) 符號旗標是設定於目的地運算元其結果為負數的時候。 當其結果為實數時則被清除。 mov cx,0 sub cx,1 ; CX = -1, SF = 1 add cx,2 ; CX = 1, SF = 0 目的運算元的最大有效位元呈現設定 狀態,則符號旗標將呈現設定狀態。 mov al,0 sub al,1 ; AL = 11111111b, SF = 1 add al,2 ; AL = 00000001b, SF = 0
標示與未標示的整數 硬體的觀念 所有CPU指令中,標示與未標示的整數操作完全一構 CPU是無法分辨出是否有標示 你,程式設計師,獨自負責在每個命令使用每個正確的資料類型 Added Slide. Gerald Cahill, Antelope Valley College
溢位及進位旗標 硬體觀念 如何那增加指令和 CF : 附屬的指令如何修正和 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 ax,00FFh add ax,1 ; AX= SF= ZF= CF= sub ax,1 ; AX= SF= ZF= CF= add al,1 ; AL= SF= ZF= CF= mov bh,6Ch add bh,95h ; BH= SF= ZF= CF= mov al,2 sub al,3 ; AL= SF= ZF= CF= 0100h 0 0 0 00FFh 0 0 0 00h 0 1 1 01h 0 0 1 FFh 1 0 1
溢位旗標 (OF) 當有號數算術運算的結果使目的運算元溢位或欠位時,溢位旗 標將呈現設定狀態 ; Example 1 mov al,+127 add al,1 ; OF = 1, AL = ?? ; Example 2 mov al,7Fh ; OF = 1, AL = 80h add al,1 這兩個範例在二進位的標準是相同的,因為7Fh等於+127。 要決定目的地運算元的值, 在十六進位中通常是比較容易去計算的。
概略的做法 當要增加二個整數時,記得溢位旗標只設定在… 兩個正值運算元在相加後的總數是負數時 兩個負值運算元在相加後的總數是正數時 溢位旗標的值是多少? mov al,80h add al,92h ; OF = mov al,-2 add al,+127 ; OF = 1
換你 . . . 在執行後給定旗標的值是多少? mov al,-128 neg al ; CF = OF = 1 1 mov ax,8000h add ax,2 ; CF = OF = mov ax,0 sub ax,2 ; CF = OF = mov al,-5 sub al,+125 ; OF = 1 1 0 0 1 0 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 bVal ; ESI = 00404000 mov esi,OFFSET wVal ; ESI = 00404001 mov esi,OFFSET dVal ; ESI = 00404003 mov esi,OFFSET dVal2 ; ESI = 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節)。
小 Endian 次序 小 endian 次序提及英代爾在記憶儲存整數的方式. 多位元組整數被儲存在反面的次序中,藉由被儲存在最低的位址的最沒有重要的位元組 舉例來說, doubleword 12345678h 將會被儲存當做: 當整數從記憶到暫存器被裝載的時候,位元組再自動地進入他們的正確位置之內被顛倒.
PTR運算子範例 .data myDouble DWORD 12345678h mov al,BYTE PTR myDouble ; AL = 78h mov al,BYTE PTR [myDouble+1] ; AL = 56h mov al,BYTE PTR [myDouble+2] ; AL = 34h mov ax,WORD PTR myDouble ; AX = 5678h mov ax,WORD PTR [myDouble+2] ; AX = 1234h
PTR運算子(續) PTR 也能用來結合一個更小的資料類型的要素並且移動他們進入一個更大的運算元之內。 CPU必須自動的顛倒位元組。 .data myBytes BYTE 12h,34h,56h,78h .code mov ax,WORD PTR [myBytes] ; AX = 3412h mov ax,WORD PTR [myBytes+2] ; AX = 7856h mov eax,DWORD PTR myBytes ; EAX = 78563412h
換你 . . . 寫下每個目的地運算元的值: .data varB BYTE 65h,31h,02h,05h varW WORD 6543h,1202h varD DWORD 12345678h .code mov ax,WORD PTR [varB+2] ; a. mov bl,BYTE PTR varD ; b. mov bl,BYTE PTR [varW+2] ; c. mov ax,WORD PTR [varD+2] ; d. mov eax,DWORD PTR varW ; e. 0502h 78h 02h 1234h 12026543h
TYPE運算子 TYPE 運算子會回傳變數的單一元素的大小,其單位是位元組。 .data var1 BYTE ? var2 WORD ? var3 DWORD ? var4 QWORD ? .code mov eax,TYPE var1 ; 1 mov eax,TYPE var2 ; 2 mov eax,TYPE var3 ; 4 mov eax,TYPE var4 ; 8
LENGTHOF運算子 LENGTHOF 運算子會計算陣列中的元素數目,而此數目是由與標籤位於同一行的若干個 值所定義。 .data LENGTHOF byte1 BYTE 10,20,30 ; 3 array1 WORD 30 DUP(?),0,0 ; 32 array2 WORD 5 DUP(3 DUP(?)) ; 15 array3 DWORD 1,2,3,4 ; 4 digitStr BYTE "12345678",0 ; 9 .code mov ecx,LENGTHOF array1 ; 32
SIZEOF運算子 SIZEOF 運算子所回傳的值,等於 LENGTHOF 乘以 TYPE 的值。 .data SIZEOF byte1 BYTE 10,20,30 ; 3 array1 WORD 30 DUP(?),0,0 ; 64 array2 WORD 5 DUP(3 DUP(?)) ; 30 array3 DWORD 1,2,3,4 ; 16 digitStr BYTE "12345678",0 ; 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 ; 6 mov ebx,SIZEOF array ; 12
跨越倍數排成一行(2 of 2) 在下列的例子中,排列只識別第一字公告.在先前的幻燈片中比較在這裡被 LENGTHOF 和 SIZEOF 歸還的價值和那些在先前的幻燈片中比較在這裡被 LENGTHOF 和 SIZEOF 歸還的價值和那些: .data array WORD 10,20 WORD 30,40 WORD 50,60 .code mov eax,LENGTHOF array ; 2 mov ebx,SIZEOF array ; 4
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 mov al,[esi] ; AL = 30h
間接運算元(2之2) 使用 PTR 澄清記憶運算元的大小屬性. PTR 應該在這裡被使用嗎? add [esi],20 .data myCount WORD 0 .code mov esi,OFFSET myCount inc [esi] ; error: ambiguous inc WORD PTR [esi] ; ok PTR 應該在這裡被使用嗎? add [esi],20 yes, because [esi] could point to a byte, word, or doubleword
陣列 間接的運算元對穿越排列是理想的。注意那暫存器在支架一定要是增量被一價值與那相配排列類型。 .data arrayW WORD 1000h,2000h,3000h .code mov esi,OFFSET arrayW mov ax,[esi] add esi,2 ; or: add esi,TYPE arrayW add ax,[esi] add esi,2 add ax,[esi] ; AX = sum of the array ToDo:為 doublewords 的排列修正這一個例子。
索引運算元 為 doublewords 的排列修正這一個例子一個被編入索引的運算元把一個常數加入一個暫存器產生一個有效的位址。有二種 notational 表格: [label + reg] label[reg] .data arrayW WORD 1000h,2000h,3000h .code mov esi,0 mov ax,[arrayW + esi] ; AX = 1000h mov ax,arrayW[esi] ; alternate format add esi,2 add ax,[arrayW + esi] etc. 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] ; 04 mov bx,arrayW[esi*TYPE arrayW] ; 0004 mov edx,arrayD[esi*TYPE arrayD] ; 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 66 B8 0000 mov ax,0 00000004 B9 00000005 mov ecx,5 00000009 66 03 C1 L1: add ax,cx 0000000C E2 FB loop L1 0000000E 當loop被裝配的時候,現在的地點=0000000 E(下一個指令的抵銷). -5(FBh)被加到現在的地點,導致一次跳躍到地點 00000009 : 00000009 0000000E + FB
習題. . . 如果相關抵銷在一個被符號的位元組中被編碼, (a)最大的可能向後地跳躍? (b)最大的可能向前地跳躍? -128 +127
習題 . . . AX的終值是多少? 10 迴圈次數是多少? 4,294,967,296 mov ax,6 mov ecx,4 L1: inc ax loop L1 AX的終值是多少? 10 迴圈次數是多少? mov ecx,0 X2: inc ax loop X2 4,294,967,296
巢狀迴圈 如果你需要在一個迴圈裡面把一個迴圈編碼,你一定要保存外部的迴圈計算器的 ECX 價值在下列的例子中,外部的迴圈執行 100 次,和內部的迴圈 20 次. .data count DWORD ? .code mov ecx,100 ; set outer loop count L1: mov count,ecx ; save outer loop count mov ecx,20 ; set inner loop count L2: . . loop L2 ; repeat the inner loop mov ecx,count ; restore outer loop count loop L1 ; repeat the outer loop
總計一個整數排列 下列的密碼計算 16 位元整數排列的總數. .data intarray WORD 100h,200h,300h,400h .code mov edi,OFFSET intarray ; address of intarray mov ecx,LENGTHOF intarray ; loop counter mov ax,0 ; zero the accumulator L1: add ax,[edi] ; add an integer add edi,TYPE intarray ; point to next integer loop L1 ; repeat until ECX = 0
習題. . . 如果你正在總計 doubleword 排列,你將會在先前幻燈片上的計畫改變什麼?
複制字串 下列的密碼複印從來源到目標的字串: .data source BYTE "This is the source string",0 target BYTE SIZEOF source DUP(0) .code mov esi,0 ; index register mov ecx,SIZEOF source ; loop counter L1: mov al,source[esi] ; get char from source mov target[esi],al ; store it in the target inc esi ; move to next character loop L1 ; repeat for entire string good use of SIZEOF
習題. . . 重寫在先前的幻燈片中被顯示的計畫,使用間接的位址不願編入索引位址.
摘要 資料轉移 運算元類型 算術 運算子 JMP 和 LOOP –分岐指令 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