标签:main 15 lib includelib Win32 eax include LOOP inc
学 Win32 汇编[15]: LOOP 与标号
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 dwArr dd 1,2,3,4,5 .code main proc lea edi, dwArr ;把数组起始地址给一个寄存器 mov ecx, lengthof dwArr ;把数组元素数(将要反复的次数)给 ECX xor eax, eax L1: add eax, [edi] ;edi 中的地址将不断变化, 通过 [edi] 获取元素值 add edi, type dwArr ;获取下一个元素的地址 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
posted on 2010-04-08 17:02 万一 阅读(2655) 评论(1) 编辑 收藏
标签:main,15,lib,includelib,Win32,eax,include,LOOP,inc 来源: https://blog.51cto.com/u_14617575/2745501
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。