文档章节

学 Win32 汇编[15]: LOOP 与标号

涂孟超
 涂孟超
发布于 2014/09/26 15:33
字数 791
阅读 10
收藏 0

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

 
 
 
 
 

 

 

  

本文转载自:http://www.cnblogs.com/del/archive/2010/04/08/1707543.html

涂孟超
粉丝 12
博文 2011
码字总数 14107
作品 0
深圳
程序员
私信 提问
win32汇编和x64汇编?

win32汇编升到winx64汇编,转型容易吗?我指的是会win32汇编,还学x64汇编吗?我是初学,能不能直接学x64汇编语言,请推荐本书?

IIOWE
2014/10/01
894
3
为什么破解要学win32汇编?

听说破解要学win32汇编,写壳也要用win32汇编?为什么呢?不学不能学破解吗?

IIOWE
2014/10/02
2.6K
13
ARM汇编中的ldr和adr的区别及其在uboot中相关源码的分析

ARM汇编中的ldr和adr的区别及其在uboot中相关源码的分析 ARM汇编有ldr指令以及ldr、adr伪指令,它们都可以将标号表达式作为操作数,下面通过分析一段代码以及对应的反汇编结果来说明它们的区...

长平狐
2013/06/03
102
0
ARM汇编中的标号

ARM汇编中的标号 标号(LABEL)是为一组机器指令所起名字,表示程序中的指令或者数据地址的符号。标号可有可无,只有当需要用符号地址来访问该语句时,才给此语句赋予标号。通过在目标地址的前...

长平狐
2013/06/03
99
0
Win32汇编开发环境介绍和RadAsm简明教程

Win32汇编开发环境介绍和RadAsm简明教程 现在很多朋友都在学习汇编语言,一方面汇编语言是大学计算机课程的必修课,另一方面则是为了从其它语言转到汇编语言来,无论什么原因,我认为学习汇编...

nothingfinal
2009/08/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

PCB设计-Allegro软件入门系列-铺铜操作(下)

铺铜是PCB很常见的操作,PCB的敷铜一般都是覆地铜,增大地线面积,有利于地线阻抗降低,使电源和信号传输稳定,在高频的信号线附近敷铜,可大大减少电磁辐射干扰,起屏蔽作用。 本讲讲解啊一...

demyar
11分钟前
1
0
如何通过WASI SDK 在Linux上编译ZXing C++

Mozilla在今年三月份的时候公布了WASI。WASI的目标就是让WebAssembly在任何地方都可以运行,而不仅仅像现在这样只能运行在Node.js和Web浏览器中。WASI目前依然处于初级阶段,这篇文章分享下如...

yushulx
12分钟前
1
0
.Net界面开发神器—DevExpress官方汉化包免费下载!还在等什么?

点击获取DevExpress v19.1.7新版试用下载 DevExpress Localization Service允许您创建一组自定义的附属程序集,要将语言包添加到程序集中,请查看本文中为大家列出的对应版本的汉化包,下载并...

FILA6666
13分钟前
2
0
php生成二维码

        header('Content-Type: image/png');        //清除缓冲区,防止之前面不知道的情况下被加头部信息导致不显示图片内容        ob_clean();        $...

横着走的螃蟹
18分钟前
2
0
伪类和伪元素

伪类和伪元素 伪类和伪元素,对于绝大多数同学来说,都是耳熟能详的名字,但确实又有很多人搞不清楚它们之间的区别,以致于混淆概念。而当概念都混淆的时候,也往往意味着你不会经常使用它,...

不负好时光
20分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部