單元 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 指令指令
.datacount BYTE 100wVal WORD 2.code
mov bl,countmov ax,wValmov count,al
mov al,wVal ; errormov ax,count ; errormov eax,count ; error
• 指令會將資料從來源運算元複製到目的運算元。 語法 : MOV 目的地 , 來源• 兩個運算元必須具有相同的大小。 • CS 、 EIP 及 IP 不可以當作目的運算元。 • 兩個運算元不能都是記憶體運算元。 • 一個立即值不能搬移至區段暫存器。
換你 換你 . . .. . .
.databVal BYTE 100bVal2 BYTE ?wVal WORD 2dVal DWORD 5.code
mov ds,45mov esi,wValmov eip,dValmov 25,bValmov bVal2,bVal
解釋為什麼下列的 MOV 指令都是有錯誤的 ?? :
不被允許直接向 DS移動大小不同EIP 不能當目的地的立即的數值是不能當目的地的兩個運算元都是記憶體是不被允許的
整數的補零
mov bl,10001111b
movzx ax,bl ; 整數的補零
當你複製小的運算元到大的運算元時 , 這個 MOVZX 指令會將它的剩餘各位元填上零值。
目的地一定是一個暫存器 .
符號擴展
mov bl,10001111b
movsx ax,bl ; 符號的擴展
,它會複製 來源運算元的內容到目的運算元,並且不論目的運算元是 16 位元或 32 位元,都會將它 的剩餘各位元填上符號位元。
目的地一定要是暫存器 .
XCHG XCHG 指令指令
.datavar1 WORD 1000hvar2 WORD 2000h.code
xchg ax,bx ; 將兩個 16 位元暫存器的內容互相交換 xchg ah,al ; 將兩個 0 位元暫存器的內容互相交換xchg var1,bx ; 將 16 位元的記憶體運算元與 BX 互相交換 xchg eax,ebx ; 將兩個 32 位元暫存器的內容互相交換
xchg var1,var2 ; 錯誤 : 兩個都是記憶運算元
XCHG 將兩個運算元的內容互相 交換 . 其中一個運算元一定是一個暫存器 . 沒有立即的運算元是被充許的 .
直接位移運算元
.dataarrayB BYTE 10h,20h,30h,40h.codemov al,arrayB+1 ; AL = 20hmov al,[arrayB+1] ; alternative notation
我們可將某個移位值加到一個變數名稱上,因而建立直接位移運算元。
這讓程式設計員 可以針對沒有明確標籤的記憶體位址進行存取的動作。
Q :為何 arrayB+1 不產生 11h?
直接位移運算元 (( 內容內容 ))
.dataarrayW WORD 1000h,2000h,3000harrayD DWORD 1,2,3,4.codemov ax,[arrayW+2] ; AX = 2000hmov ax,[arrayW+4] ; AX = 3000hmov 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.
.dataarrayD DWORD 1,2,3
• 步驟 2: Exchange EAX with the third array value and copy the value in EAX to the first array position.
• 步驟 1: 將第 1 個值複製到 EAX 裡接著在第二個位置交換這個值
mov eax,arrayDxchg eax,[arrayD+4]
xchg eax,[arrayD+8]mov arrayD,eax
評估一下 評估一下 . . . . . .
• 我們想寫一個可以增加下列三個位元組的程式 :.datamyBytes 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]
• 有其他問題 ??
評估一下 評估一下 . . . . . . (( 續續 ))
.datamyBytes BYTE 80h,66h,0A5h
• 下列的編碼怎麼樣 ?? 有任何的缺少嗎 ?
movzx ax,myBytesmov bl,[myBytes+1]add ax,bxmov bl,[myBytes+2]add ax,bx ; AX = sum
Yes: 在 MOVZX 指令之前將 0 移動至 BX 暫存器裡
下一章下一章
• 資料轉移指令• 加法與減法• 資料相關的運算子和指引 • 間接定址 • JMP 和 LOOP 指令
加法與減法
• INC 及 DEC 指令• ADD 及 SUB 指令• NEG 指令• 建立算術運算式 • 算術運算影響的旗標
• 零值旗標• 符號旗標• 進位旗標• 溢位進旗
INCINC 及及 DECDEC 指令指令
• INC ( 遞增 ) 和 DEC ( 遞減 ) 指令分別會將其單一運算元加 1 和減 1 。• 運算元也許是暫存器或記憶體
• INC 目的地• 邏輯 : 目的地 目的地 + 1
• DEC 目的地• 邏輯 : 目的地 目地的 – 1
INCINC 和和 DECDEC 範例範例
.datamyWord WORD 1000hmyDword DWORD 10000000h.code
inc myWord ; 1001hdec myWord ; 1000hinc myDword ; 10000001h
mov ax,00FFhinc ax ; AX = 0100hmov ax,00FFhinc al ; AX = 0000h
換你換你 ......
在每一個指令執行後,請顯示出目的地運算元的值 :
.datamyByte BYTE 0FFh, 0.code
mov al,myByte ; AL =mov ah,[myByte+1] ; AH =dec ah ; AH =inc al ; AL =dec ax ; AX =
FFh00hFFh00hFEFF
ADDADD 和和 SUBSUB 指令指令
• ADD 目的地 , 來源• 邏輯 : 目的地 目地的 + 來源
• SUB 目地的 , 來源• Logic: 目的地 目地的 – 來源
• 和 MOV 指令的規則相同
ADDADD 及及 SUBSUB 範例範例
.datavar1 DWORD 10000hvar2 DWORD 20000h.code ; ---EAX---
mov eax,var1 ; 00010000hadd eax,var2 ; 00030000hadd ax,0FFFFh ; 0003FFFFhadd eax,1 ; 00040000hsub ax,1 ; 0004FFFFh
NEG (NEG ( 否定否定 )) 指令指令
.datavalB BYTE -1valW WORD +32767.code
mov al,valB ; AL = -1neg al ; AL = +1neg valW ; valW = -32767
顛倒運算元的符號 ( 即轉變為 2’s 補數 ) 。
運算元可以是暫存器或記憶體運算元。
假使 AX 包含 – 32,768 並且我們對它執行 NEG 指令, 將會得到一個有效的結果嗎 ?
NEGNEG 指令和旗標指令和旗標
.datavalB BYTE 1,0valC SBYTE -128.code
neg valB ; CF = 1, OF = 0neg [valB + 1] ; CF = 0, OF = 0neg valC ; CF = 1, OF = 1
使用 NEG 指令來執行下面的程式 :
SUB 0,operand
任何的非零運算元引起要設定的進位旗標
建立算術運算式
Rval DWORD ?Xval DWORD 26Yval DWORD 30Zval DWORD 40.code
mov eax,Xvalneg eax ; EAX = -26mov ebx,Yvalsub ebx,Zval ; EBX = -10add eax,ebxmov Rval,eax ; -36
HLL 編輯者將數學的表達轉變成組合語言
你也可以做的到 . 。範例 :
Rval = -Xval + (Yval – Zval)
換你換你 ......
mov ebx,Yvalneg ebxadd ebx,Zvalmov eax,Xvalsub eax,ebxmov Rval,eax
將下面的意思轉換成組合語言。 不能變更 Xval, Yval, or Zval :
Rval = Xval - (-Yval + Zval)
假設所有的值皆被標示成 doublewords.
算術運算影響的旗標
• ALU 有反映算術行動結果的一些狀態旗標。• 建立目的地運算元的內容
• 必要的旗標 :• 零值旗標 – 當目的地等於零的時候設定• 符號旗標 – 當目的地是負數的時候設定• 進位旗標 – 當未被標示的值超出範圍時設定• 溢位旗標 – 當被標示的值超出範圍時設定
• MOV 指令不會影響到任何旗標。
觀念圖觀念圖
狀態旗標
ALU條件跳躍
分岐邏輯
算術 & bitwise 操作
部份
被使用 提拱附加在
影響
CPU
你能使用像如此的圖形表達在組合語言觀念之間的關係。
執行
執行
零值旗標 零值旗標 (ZF)(ZF)
mov cx,1sub cx,1 ; CX = 0, ZF = 1mov ax,0FFFFhinc ax ; AX = 0, ZF = 1inc ax ; AX = 1, ZF = 0
零值旗標是設定於目的地運算元其操作結果為零的時候。
記得 ...• 當它等於 1 的時候設定旗標。• 當它等於 0 的時候清除旗標。
符號旗標 符號旗標 (SF)(SF)
mov cx,0sub cx,1 ; CX = -1, SF = 1add cx,2 ; CX = 1, SF = 0
符號旗標是設定於目的地運算元其結果為負數的時候。
當其結果為實數時則被清除。
目的運算元的最大有效位元呈現設定 狀態,則符號旗標將呈現設定狀態。
mov al,0sub al,1 ; AL = 11111111b, SF = 1add al,2 ; 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)(CF)
進位旗標可以指出無號整數的溢位狀態( 目地的運算元太大或太小 )
mov al,0FFhadd al,1 ; CF = 1, AL = 00
; Try to go below zero:
mov al,0sub al,1 ; CF = 1, AL = FF
換你 換你 . . .. . .
mov ax,00FFhadd ax,1 ; AX= SF= ZF= CF=sub ax,1 ; AX= SF= ZF= CF=add al,1 ; AL= SF= ZF= CF=mov bh,6Chadd bh,95h ; BH= SF= ZF= CF=
mov al,2sub al,3 ; AL= SF= ZF= CF=
從下列程式中 , 表示出目的地運算位的值、符號旗標的值、零值旗標的值、進位旗標的值
0100h 0 0 000FFh 0 0 000h 0 1 1
01h 0 0 1
FFh 1 0 1
溢位旗標 溢位旗標 (OF)(OF)
當有號數算術運算的結果使目的運算元溢位或欠位時,溢位旗 標將呈現設定狀態; Example 1mov al,+127add al,1 ; OF = 1, AL = ??
; Example 2mov al,7Fh ; OF = 1, AL = 80hadd al,1
這兩個範例在二進位的標準是相同的,因為 7Fh 等於+127 。 要決定目的地運算元的值, 在十六進位中通常是比較容易去計算的。
概略的做法 概略的做法
• 當要增加二個整數時 , 記得溢位旗標只設定在…• 兩個正值運算元在相加後的總數是負數時• 兩個負值運算元在相加後的總數是正數時
溢位旗標的值是多少 ?mov al,80hadd al,92h ; OF =
mov al,-2add al,+127 ; OF =
1
0
換你 換你 . . .. . .
mov al,-128neg al ; CF = OF =
mov ax,8000hadd ax,2 ; CF = OF =
mov ax,0sub ax,2 ; CF = OF =
mov al,-5sub al,+125 ; OF =
在執行後給定旗標的值是多少 ?
1 1
0 0
1 0
1
下一章下一章
• 資料轉移指令• 加法與減法• 資料相關的運算子和指引 • 間接定址 • JMP 和 LOOP 指令
資料相關的運算子和指引資料相關的運算子和指引
• OFFSET 運算子• PTR 運算子• TYPE 運算子• LENGTHOF 運算子• SIZEOF 運算子• LABEL 指引
OFFSETOFFSET 運算子運算子
• OFFSET 運算子會回傳資料標籤的位移。位移代表的是標籤到資料區段起始點的距離,其 單位是位元組。• 在保護模式下位移有 32 位元• 在實體位址模式下位移只有 16 位元
在保護模式下的程式我們只有撰寫一部份 ( 我們使用的是平坦式記憶體模式 )
OFFSETOFFSET 範例範例
.databVal BYTE ?wVal WORD ?dVal DWORD ?dVal2 DWORD ?
.codemov esi,OFFSET bVal ; ESI = 00404000mov esi,OFFSET wVal ; ESI = 00404001mov esi,OFFSET dVal ; ESI = 00404003mov esi,OFFSET dVal2 ; ESI = 00404007
讓我們假定資料部份從 00404000h 開始:
Relating to C/C++Relating to C/C++
; C++ 版本 :char array[1000];char * p = array;
被 OFFSET送回的的值是一個指標。
比較 C++ 語言寫的編碼和程式語言寫的編碼 :
.dataarray BYTE 1000 DUP(?).codemov esi,OFFSET array ; ESI is p
PTRPTR 運算子運算子
.datamyDouble DWORD 12345678h.codemov ax,myDouble ; error – why?
mov ax,WORD PTR myDouble ; loads 5678h
mov WORD PTR myDouble,4321h ; saves 4321h
使用 PTR 運算子,來置換一個運算元已被宣告的空間大小值。
這只有在你想要 存取的變數的空間大小屬性與當初宣告該變數的大小屬性不同時才須要用到。
當儲存資料在記憶的時候,小 endian 次序被使用的取消( 參考第 3.4.9 節 ) 。
小 小 Endian Endian 次序次序
• 小 endian 次序提及英代爾在記憶儲存整數的方式 .• 多位元組整數被儲存在反面的次序中,藉由被儲存在最低的位址的最沒有重要的位元組
• 舉例來說, doubleword 12345678h 將會被儲存當做:
當整數從記憶到暫存器被裝載的時候,位元組再自動地進入他們的正確位置之內被顛倒 .
PTRPTR 運算子範例運算子範例
.datamyDouble DWORD 12345678h
mov al,BYTE PTR myDouble ; AL = 78hmov al,BYTE PTR [myDouble+1] ; AL = 56hmov al,BYTE PTR [myDouble+2] ; AL = 34hmov ax,WORD PTR myDouble ; AX = 5678hmov ax,WORD PTR [myDouble+2] ; AX = 1234h
PTRPTR 運算子運算子 (( 續續 ))
.datamyBytes BYTE 12h,34h,56h,78h
.codemov ax,WORD PTR [myBytes] ; AX = 3412hmov ax,WORD PTR [myBytes+2] ; AX = 7856hmov eax,DWORD PTR myBytes ; EAX = 78563412h
PTR 也能用來結合一個更小的資料類型的要素並且移動他們進入一個更大的運算元之內。
CPU 必須自動的顛倒位元組。
換你 換你 . . .. . .
.datavarB BYTE 65h,31h,02h,05hvarW WORD 6543h,1202hvarD DWORD 12345678h
.codemov 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.
寫下每個目的地運算元的值:
0502h78h02h1234h12026543h
TYPETYPE 運算子運算子
TYPE 運算子會回傳變數的單一元素的大小,其單位是位元組。
.datavar1 BYTE ?var2 WORD ?var3 DWORD ?var4 QWORD ?
.codemov eax,TYPE var1 ; 1mov eax,TYPE var2 ; 2mov eax,TYPE var3 ; 4mov eax,TYPE var4 ; 8
LENGTHOFLENGTHOF 運算子運算子
.data LENGTHOFbyte1 BYTE 10,20,30 ; 3array1 WORD 30 DUP(?),0,0 ; 32array2 WORD 5 DUP(3 DUP(?)) ; 15array3 DWORD 1,2,3,4 ; 4digitStr BYTE "12345678",0 ; 9
.codemov ecx,LENGTHOF array1 ; 32
LENGTHOF 運算子會計算陣列中的元素數目,而此數目是由與標籤位於同一行的若干個 值所定義。
SIZEOFSIZEOF 運算子運算子
.data SIZEOFbyte1 BYTE 10,20,30 ; 3array1 WORD 30 DUP(?),0,0 ; 64array2 WORD 5 DUP(3 DUP(?)) ; 30array3 DWORD 1,2,3,4 ; 16digitStr BYTE "12345678",0 ; 9
.codemov ecx,SIZEOF array1 ; 64
SIZEOF 運算子所回傳的值,等於 LENGTHOF 乘以 TYPE 的值。
跨越倍數排成一行跨越倍數排成一行 (1 of 2)(1 of 2)
.dataarray WORD 10,20,
30,40,50,60
.codemov eax,LENGTHOF array ; 6mov ebx,SIZEOF array ; 12
如果每條列(除最後)以一個逗點結束,資料公告跨越多條列。 LENGTHOF 和 SIZEOF 運算包括屬於公告的所有的列 :
跨越倍數排成一行跨越倍數排成一行 (2 of 2)(2 of 2)
.dataarray WORD 10,20
WORD 30,40WORD 50,60
.codemov eax,LENGTHOF array ; 2mov ebx,SIZEOF array ; 4
在下列的例子中,排列只識別第一字公告.在先前的幻燈片中比較在這裡被 LENGTHOF 和 SIZEOF 歸還的價值和那些在先前的幻燈片中比較在這裡被 LENGTHOF 和 SIZEOF 歸還的價值和那些 :
LABEL 指引
• LABEL 指引可以讓我們插入標籤,並且在不配置任何記憶體的情形下,給予它空間大小的屬性。
• LABEL 可以與任何一種標準的空間大小屬性搭配使用• 替接下來要在資料區段中 宣告的變數,提供另一個名
稱和空間大小屬性。
.datadwList LABEL DWORDwordList LABEL WORDintList BYTE 00h,10h,00h,20h.codemov eax,dwList ; 20001000hmov cx,wordList ; 1000hmov dl,intList ; 00h
下一章下一章
• 資料轉移指令• 加法與減法• 資料相關的運算子和指引 • 間接定址• JMP 和 LOOP 指令
間接定址間接定址
• 間接運算元 • 陣列 • 索引運算元 • 指標
間接運算元間接運算元 (2(2 之之 1)1)
.dataval1 BYTE 10h,20h,30h.codemov esi,OFFSET val1mov al,[esi] ; dereference ESI (AL = 10h)
inc esimov al,[esi] ; AL = 20h
inc esimov al,[esi] ; AL = 30h
一個間接的運算元支撐變數的位址,通常排列或者字串.它可能是 dereferenced. (僅僅喜歡一個指針)
間接運算元間接運算元 (2(2 之之 2)2)
.datamyCount WORD 0
.codemov esi,OFFSET myCountinc [esi] ; error: ambiguousinc WORD PTR [esi] ; ok
使用 PTR 澄清記憶運算元的大小屬性 .
PTR 應該在這裡被使用嗎 ?
add [esi],20
yes, because [esi] could point to a byte, word, or doubleword
陣列陣列
.dataarrayW WORD 1000h,2000h,3000h.code
mov esi,OFFSET arrayWmov ax,[esi]add esi,2 ; or: add esi,TYPE arrayWadd ax,[esi]add esi,2add ax,[esi] ; AX = sum of the array
間接的運算元對穿越排列是理想的。注意那暫存器在支架一定要是增量被一價值與那相配排列類型。
ToDo :為 doublewords 的排列修正這一個例子。
索引運算元索引運算元
.dataarrayW WORD 1000h,2000h,3000h.code
mov esi,0mov ax,[arrayW + esi] ; AX = 1000hmov ax,arrayW[esi] ; alternate formatadd esi,2add ax,[arrayW + esi]etc.
為 doublewords 的排列修正這一個例子一個被編入索引的運算元把一個常數加入一個暫存器產生一個有效的位址。有二種 notational 表格 :
[label + reg] label[reg]
ToDo :為 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
為 doublewords 的排列修正這一個例子你元。能依比例決定對排列元素的抵銷一個間接的或編入索引運算這被藉由繁殖排列的類型的索引做:
指標指標
.dataarrayW WORD 1000h,2000h,3000hptrW DWORD arrayW.code
mov esi,ptrWmov ax,[esi] ; AX = 1000h
你能宣布一個包含另一個變數的抵銷的指標變數。
輪流格式 :
ptrW DWORD OFFSET arrayW
下一章下一章
• 資料轉移指令• 加法與減法• 資料相關的運算子和指引 • 間接定址• JMP 和 LOOP指令
JMPJMP 和和 LOOPLOOP 指令 指令
• JMP 指令• LOOP 指令• LOOP 例題• 總計一個整數排列• 複製字串
JMP JMP 指令指令
top:..jmp top
• JMP 對標籤是一次無條件的跳躍哪一通常在相同的程序裡面 .
• Syntax: JMP 目標• Logic: EIP 目標• 例題 :
在現在的程序之外的一次跳躍一定要到被稱為通用的標籤的特別類型的標籤。(細節到第 5.5.2.3 節)
LOOP LOOP 指令指令• loop 指令創造一個計算的 loop
• Syntax: LOOP 目標• 邏輯 :
• ECX ECX – 1
• if ECX != 0, 跳到目標
• 履行˙ :
• 在下列指令的抵銷和目標標籤的抵銷之間在位元組中組合器計算距離。它叫做相關抵銷。
• 相關抵銷被加到 EIP 。
LOOP LOOP 例題例題
00000000 66 B8 0000 mov ax,0 00000004 B9 00000005 mov ecx,5
00000009 66 03 C1 L1: add ax,cx0000000C E2 FB loop L10000000E
下列的 loop 計算整數的總數
5 + 4 + 3 +2 + 1:
當 loop 被裝配的時候,現在的地點= 0000000 E(下一個指令的抵銷) . -5(FBh)被加到現在的地點,導致一次跳躍到地點 00000009 :
00000009 0000000E + FB
offset machine code source code
習題習題 . . .. . .
如果相關抵銷在一個被符號的位元組中被編碼 ,
(a)最大的可能向後地跳躍 ?
(b)最大的可能向前地跳躍 ?
(a) 128
(b) +127
習題習題 . . .. . .
AX 的終值是多少 ?
mov ax,6mov ecx,4
L1:inc axloop L1
迴圈次數是多少 ?mov ecx,0
X2:inc axloop X2
10
4,294,967,296
巢狀迴圈巢狀迴圈如果你需要在一個迴圈裡面把一個迴圈編碼,你一定要保存外部的迴圈計算器的 ECX 價值在下列的例子中,外部的迴圈執行 100 次,和內部的迴圈 20 次 .
.datacount DWORD ?.code
mov ecx,100 ; set outer loop countL1:
mov count,ecx ; save outer loop countmov ecx,20 ; set inner loop count
L2: ..loop L2 ; repeat the inner loopmov ecx,count ; restore outer loop countloop L1 ; repeat the outer loop
總計一個整數排列總計一個整數排列
.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
下列的密碼計算 16 位元整數排列的總數 .
習題習題 . . .. . .
如果你正在總計 doubleword 排列,你將會在先前幻燈片上的計畫改變什麼 ?
複制字串複制字串
.datasource BYTE "This is the source string",0target BYTE SIZEOF source DUP(0)
.codemov esi,0 ; index registermov ecx,SIZEOF source ; loop counter
L1:mov al,source[esi] ; get char from sourcemov target[esi],al ; store it in the targetinc esi ; move to next characterloop L1 ; repeat for entire string
good use of SIZEOF
下列的密碼複印從來源到目標的字串 :
習題習題 . . .. . .
重寫在先前的幻燈片中被顯示的計畫,使用間接的位址不願編入索引位址 .
摘要摘要
• 資料轉移 • 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 EndThe End