全局变量和局部变量

全局变量的定义:
.data
wHour            dw        ?    
;定义了一个初始化的word类型变量,名称为wHour.
wMinute         dw         10    ;定义了名为wMinute的word类型变量,值为10
_hWnd           dd      ?    ;定义了双子类型的变量_hWnd
word_Buffer        dw        100 dup(1,2)    ;定义了一组字,以0001,0002,0001,0002的顺序在内存中重复100遍,一共200个字。
szBuffer        byte    1024 dup (?)    ;定义了1024个字节的缓冲区
szText            db        'Hello,world!'        ;定义了个字符串,一共占用了12个字节。

局部变量:在进入子程序的时候,通过修改堆栈指针ESP来预留出需要的空间,在用ret指令返回主程序之前,同样通过修复ESP丢弃这些空间,这些变量就随之无效了。缺点是无法定义含有初始化值的变量,对局部变量的初始化一般在子程序中由指令来完成。局部变量定义如:
local    loc1[
1024]:byte        ;定义了一个1024字节长的局部变量loc1
local    loc2                ;定义了名为loc2的局部变量,类型默认是DWORD
local    loc3:WNDCLASS        ;定义了一个WNDCLASS数据结构,名为loc3

一个很典型的例子:
TestProc    proc
            local    
@loc1:dword,@loc2:word
            local    
@loc3:byte
            
            
mov eax,@loc1
            
mov ax,@loc2
            
mov al,@loc3
            
ret
            
TestProc    endp
反汇编就成了下面的指令:
push ebp
mov ebp,esp
add esp, FFFFFFF8
;上面三句是使用局部变量所必须的指令,用于局部变量的准备工作,执行了CALL后,CPU把返回的地址压入堆栈,再转移到子程序执行,ESP在程序的执行过程中可能会随时用到,所以不可能用ESP做指针来存取局部变量。在初始化之前,先用一句push ebp把原来的ebp保存起来,然后把esp的值放到ebp中,供存取局部变量做指针用,再下面就是要在堆栈中预留空间了,由于堆栈是向下增长的,所以要在esp中加一个负值,FFFFFFF8就是-8。慢着!一个DWORD+一个word+byte不是7吗?为什么是8呢?因为80386以dword为界对齐时存取内存速度最快,所以宁可浪费一个字节。
mov eax,dword ptr [ebp-04]
mov ax,word ptr [ebp-06]
mov al,byte ptr [ebp-07]
leave
;因为程序开始的时候已经有一句mov ebp,esp,所以要返回的时候只要先mov esp,ebp,然后再pop ebp,就可以了,可以用一个leave指令来代替这两条指令就行。
ret
posted @ 2009-04-02 15:10  小试锋芒  阅读(580)  评论(0编辑  收藏  举报