zoukankan      html  css  js  c++  java
  • 学 Win32 汇编[9]: 子过程中的变量声明


    定义子过程的伪指令: PROC、ENDP
    ; Test9_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
    
    .code
        ;子过程 proc1:
        proc1 proc
            PrintText 'proc1'
        proc1 endp
        
        ;子过程 proc2:
        proc2 proc
            PrintText 'proc2'
        proc2 endp
        
        ;子过程 proc3:
        proc3 proc
            PrintText 'proc3'
        proc3 endp
    
        ret
    end proc1  ;end 后面的 proc1 是入口的子过程名; 这也就是指定主过程.
    
    ;可以把 end proc1 分别换做 end proc2 和 end proc3 尝试,
    ;如果这是一个供其他程序调用的代码文件, 那么 end 后面就不需要指定.
    

    模仿 C 语言的样子, 以后的程序结构应该这样:
    ; Test9_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
        szText db 'Hello World!', 0DH, 0AH, 0
        
    .code
    main proc
        PrintString szText  ;Hello World!
        ret
    main endp
    end main
    

    局部变量要用 local 声明, 和全局变量区别不小:
    ; Test9_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
    
    .code
    main proc
        ;局部变量中的类型不能使用缩写
        LOCAL v1: dword
        
        ;可用逗号间隔写在一行
        LOCAL v2: dword, v3: dword
        
        ;不指定类型时默认 DWORD(在 Win32 下)
        LOCAL v4
        
        ;数组
        LOCAL v5[3]: dword
        
        ;在手动初始化前, 局部变量中都是些垃圾值:
        PrintDec v1
        PrintDec v2
        PrintDec v3
        PrintDec v4
        mov eax, v5[0]
        PrintDec eax
        ret
    main endp
    end main
    

    调用子过程:
    ; Test9_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
    
    .code
    ;
    proc1 proc
        PrintDec 1
        ret
    proc1 endp
    ;
    proc2 proc
        PrintDec 2
        ret
    proc2 endp
    ;
    main proc
        PrintDec 0
        call proc2
        call proc1
        ret
    main endp
    end main
    
    ;注释:
    ;最后一行 end main 决定了子过程将被率先调用, 这样它就成了主过程
    ;然后主过程又通过 call 指令顺序调用了 proc2、proc1
    ;这样最后的显示结果将是: 0 / 2 / 1
    ;子过程应该用 ret 指令返回
    

    一个求和函数的例子:
    ; Test9_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
    
    .code
    ;求和的函数, 函数返回值在 eax
    ;sum proc v1:dword, v2:dword, v3:dword
    sum proc v1, v2, v3 ;这是上一行的简化, 其类型也是默认为 dword
        mov eax, v1
        add eax, v2
        add eax, v3
        ret
    sum endp
    ;
    main proc
        invoke sum, 11, 22, 33
        PrintDec eax  ;66
        ret
    main endp
    end main
    

  • 相关阅读:
    以多维数组的形式访问动态内存 笔记
    SQL对于 小数处理的小结
    备忘,搞不明白这是为什么
    生成3位的序列号_仅仅CASE WHEN的简单应用
    DataGridView导出数据到Excel
    Sql更新
    delphi使用RichView控件 表格保存和复制
    delphi使用RichView控件 表中选择
    delphi使用RichView控件 表格单元格合并
    delphi使用RichView控件 表格大小
  • 原文地址:https://www.cnblogs.com/del/p/1704864.html
Copyright © 2011-2022 走看看