win32汇编: 变量的尺寸和数量 以及获取变量的地址

来源:互联网 发布:店铺招牌制作软件 编辑:程序博客网 时间:2024/04/29 14:05
一。变量的尺寸和数量


sizeof 伪指令可以取得变量,数据类型或数据结构以字节为单位的长度
lengthof可以取得变量中数据的项数(只能是变量名)

sizeof 和 lengthof 的计算结果 编译器直接生成数值


如果把 Hello和World分两行定义,szHello是这样定义的:
szHello db 'Hello',0ah,0ahdb 'World',0


那么 sizeof szHello是多少呢?
注意!是7,而不是13.MASM中变量只认一行。
而后一行 db 'World',0 实际上是另一个没有名称的数据定义。
获取字符串长度 :strlen


二.获取变量的地址
对于全局变量和局部变量是不同的。
对于全局变量,它的地址在编译的时候已经由编译器确定了,它的用法大家都不陌生:
mov 寄存器,offset 变量名
offset 是取变量地址的操作符 伪指令
对于局部变量:
局部变量是存在栈里面的,它是用ebp来做指针操作的(高地址,栈低指针),假设ebp的值是40100h,那么第一个局部变量的地址使ebp-4及400FCh
ebp随着程序的执行环境不同可能不同,所以编译的时候还不确定。

(ebp栈低指针(高地址),esp栈顶指针(低地址))
80386处理器有一条取指针地址的指令:
lea指令: 
lea ax,[ebp-4]


如果要在invoke 伪指令的参数中用到 一个局部变量的地址(传递一个指针变量进去),这时参数是不能写入lea的,用offset又是不对的。MASM对此有一个专用的伪操作符addr,格式为 addr 局部变量名或者 全局变量名
addr后跟全局变量名的时候,用法和offset是相同的。
当addr后面跟局部变量名的时候,编译器自动用lea指令先把地址取到eax中,然后用eax来代替变量地址使用。
(注意)addr伪指令只能在invoke参数中使用。
原理:
invoke Test,eax,addr szHello


反汇编:
lea eax,[ebp-4]push eax     ;参数addr szHellopush eax     ;参数 eaxcall Test


这里有一个问题就是 第一个eax 推进栈之前,addr 的计算结果eax把它覆盖了
所以,当在invoke中使用addr 伪操作符时,它的前面不能用eax,否则会被覆盖掉,addr参数后面可以加。

原创粉丝点击