全局变量和局部变量
全局变量的定义:
.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
.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