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
    

  • 相关阅读:
    SVN服务器搭建(一)
    排序算法二:冒泡排序
    【LeetCode】136. Single Number
    【LeetCode】217. Contains Duplicate
    【LeetCode】189. Rotate Array
    【LeetCode】122. Best Time to Buy and Sell Stock II
    【LeetCode】26. Remove Duplicates from Sorted Array
    【LeetCode】20. Valid Parentheses
    【LeetCode】680. Valid Palindrome II
    【LeetCode】345. Reverse Vowels of a String
  • 原文地址:https://www.cnblogs.com/del/p/1704864.html
Copyright © 2011-2022 走看看