程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 學 Win32 匯編 [15]: LOOP 與標號

學 Win32 匯編 [15]: LOOP 與標號

編輯:Delphi

Loop 是反復執行;

  從哪反復? 這要用到 "標號";

  反復幾次? 把反復的次數告訴 ECX 寄存器即可.

  笨辦法計算 3 * 8 = 24

; Test15_1.asm 
.386 
.model flat, stdcall 
 
include  Windows.inc 
include  kernel32.inc 
include  masm32.inc 
include  debug.inc 
includelib kernel32.lib 
includelib masm32.lib 
includelib debug.lib 
 
.data 
   val dd 3 
.code 
main proc 
   xor eax, eax 
   add eax, val 
   add eax, val 
   add eax, val 
   add eax, val 
   add eax, val 
   add eax, val 
   add eax, val 
   add eax, val 
   PrintDec eax ;24 
   ret 
main endp 
end main 

  使用 LOOP 和標號:

; Test15_2.asm 
.386 
.model flat, stdcall 
 
include  Windows.inc 
include  kernel32.inc 
include  masm32.inc 
include  debug.inc 
includelib kernel32.lib 
includelib masm32.lib 
includelib debug.lib 
 
.data 
   val dd 3 
.code 
main proc 
   xor eax, eax 
   mov ecx, 8 
L1:          ;命名為 "L1" 的標號 
   add eax, val 
   loop L1    ;反復到指定標號; 每次反復 ecx 會減 1, 直到 ecx 為 0 才向下執行 
 
   PrintDec eax ;24 
   ret 
main endp 
end main 

 數組求和的例子:

; Test15_3.asm 
.386 
.model flat, stdcall 
 
include  Windows.inc 
include  kernel32.inc 
include  masm32.inc 
include  debug.inc 
includelib kernel32.lib 
includelib masm32.lib 
includelib debug.lib 
   
.data 
   ddArr dd 1,2,3,4,5 
.code 
main proc 
   lea edi, ddArr       ;把數組起始地址給一個寄存器 
   mov ecx, lengthof ddArr ;把數組元素數(將要反復的次數)給 ECX 
   xor eax, eax 
L1: 
   add eax, [edi]       ;edi 中的地址將不斷變化, 通過 [edi] 獲取元素值 
   add edi, type ddArr   ;獲取下一個元素的地址 
   loop L1 
   
   PrintDec eax ;15 
   ret 
main endp 
end main 

  復制字符串的例子:

; Test15_4.asm 
.386 
.model flat, stdcall 
 
include  Windows.inc 
include  kernel32.inc 
include  masm32.inc 
include  debug.inc 
includelib kernel32.lib 
includelib masm32.lib 
includelib debug.lib 
   
.data 
   szSource db 'Hello World!', 0    ;定義源字符串 
   szDest  db sizeof szSource dup(0) ;定義相同大小的目的字符串 
.code 
main proc 
   mov esi, 0           ;這裡選擇使用 esi 做數組索引 
   mov ecx, sizeof szSource ;這是要循環的次數 
L1: 
   mov al, szSource[esi]   ;mov 的操作數不允許兩個都是變量, 用 al 中轉一下 
   mov szDest[esi], al    ; 
   inc esi             ;調整索引 
   loop L1 
   
   PrintString szDest      ;Hello World! 
   ret 
main endp 
end main 

 如果僅僅是復制字符串, 可以使用聲明在 masm32.inc 中的 szCopy 函數:

; Test15_5.asm 
.386 
.model flat, stdcall 
 
include  Windows.inc 
include  kernel32.inc 
include  masm32.inc 
include  debug.inc 
includelib kernel32.lib 
includelib masm32.lib 
includelib debug.lib 
   
.data 
   szSource db 'Hello World!', 0 
   szDest  db sizeof szSource dup(0) 
.code 
main proc 
   invoke szCopy, addr szSource, addr szDest 
   PrintString szDest ;Hello World! 
   ret 
main endp 
end main 

  關於 @@、@B、@F:

; 如果懶得給標號取名, 可以使用 @@ 做標號; 
; @B 表示前面最近的一個標號、@F 表示後面最近的一個標號; 
; 使用 @@ 可以把前面 3*8=24 的例子修改如下: 
 
; Test15_6.asm 
.386 
.model flat, stdcall 
 
include  Windows.inc 
include  kernel32.inc 
include  masm32.inc 
include  debug.inc 
includelib kernel32.lib 
includelib masm32.lib 
includelib debug.lib 
 
.data 
   val dd 3 
.code 
main proc 
   xor eax, eax 
   mov ecx, 8 
@@: 
   add eax, val 
   loop @B 
   PrintDec eax ;24 
   ret 
main endp 
end main 

  關於全局標號:

; 上面例子中的標號都是局部標號; 
; 如果一個標號定義在子過程之外, 那它就是全局標號了. 
; 能不能在子過程中定義全局標號呢? 後面加兩個 : 就是了. 
 
; Test15_7.asm 
.386 
.model flat, stdcall 
 
include  Windows.inc 
include  kernel32.inc 
include  masm32.inc 
include  debug.inc 
includelib kernel32.lib 
includelib masm32.lib 
includelib debug.lib 
 
.data 
   val dd 3 
.code 
 
MyProc proc 
Label1::          ;是 Label1:: 而不是 Label1: 
   PrintText 'MyProc' 
   ret 
MyProc endp 
 
main proc 
   PrintText 'main' 
   jmp Label1 ;jmp 是無條件跳轉指令 
   ret 
main endp 
end main 




  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved