当前位置:鱼C工作室 >Win32汇编 > 查看文章

使用MASM10(变量的使用)- Win32汇编语言018

使用MASM10(变量的使用)

 

让编程改变世界

Change the world by program


 

变量的使用

 

接着上一节的话题,我们继续谈变量,书本原本的数据结构我们后边介绍。

这个话题有点像C语言中的数据类型强制转换,C语言中的类型转换指的是把一个变量的内容转换成另外一种类型,转换过程中,数据的内容已经发生了变化,如把浮点数转换成整数后,小数点后的内容就丢失了。

 

在MASM中以不同的类型访问不会对变量造成影响。

例如,以db方式定义一个缓冲区:

szBuffer db 1024 dup ( )

然后

mov ax, szBuffer

编译器会报一个错:

error A2070: invalid instruction operands

 

意思是无效的指令操作,为什么呢?因为szBuffer是用db定义的,而ax的尺寸是一个word,等于两个字节,尺寸不符合。

在MASM中,如果要用指定类型之外的长度访问变量,必须显式地指出要访问的长度,这样编译器忽略语法上的长度检验,仅使用变量的地址。

 

使用的方法是: 类型 ptr 变量名

类型可以是byte, word, dword, fword, qword, real8和real10。

如:

mov ax, word ptr szBuffer

mov eax, dword ptr szBuffer

 

在这里要注意的是,指定类型的参数访问并不会去检测长度是否溢出,看下面一段代码:

.data
bTest1         db          12h
wTest2         dw          1234h
dwTest3        dd          12345678h
   ……
.code
   mov        al, bTest1
   mov        ax, word ptr bTest1
   mov        eax, dword ptr bTest1
   ……

 

上面的程序片断,每一句执行后寄存器中的值是什么呢?

mov al, bTest1 这一句很显然使 al 等于 12h,下面的两句呢,ax 和 eax难道等于 0012h 和00000012h吗?

 

实际运行结果是 3412h 和 78123412h,为什么呢?(DOS汇编基础不错的同学,应该能理解)

现在我们先来看反汇编的内容:详见视频……

 

所以说呢,刚才这个例子说明了汇编中用ptr强制覆盖变量长度的时候,实质上是只用了变量的地址而禁止编译器进行检验。

编译器并不会考虑定界的问题,程序员在使用的时候必须对内存中的数据排列有个全局概念,以免越界存取到意料之外的数据。

如果程序员的本意是类似于C语言的强制类型转换,想把bTest1的一个字节扩展到一个字或一个双字再放到ax 或 eax中,高位保持0而不是越界存取到其他的变量,要肿么办呢?

 

80386处理器提供的 movzx 指令可以实现这个功能,例如:

movzx ax,bTest1 ; ax == 0012h

movzx eax,bTest1 ; eax == 00000012h

movzx eax,cl ; eax == 000000(cl)

movzx eax,ax ; eax == 0000(ax)

 

用movzx指令进行数据长度扩展是Win32汇编中经常用到的技巧。


为您推荐

报歉!评论已关闭.