使用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

  在这里要注意的是,指定类型的参数访问并不会去检测长度是否溢出,看下面一段代码: [codesyntax lang="asm"]
.data
bTest1         db          12h
wTest2         dw          1234h
dwTest3        dd          12345678h
   ……
.code
   mov        al, bTest1
   mov        ax, word ptr bTest1
   mov        eax, dword ptr bTest1
   ……
[/codesyntax]   上面的程序片断,每一句执行后寄存器中的值是什么呢? 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汇编中经常用到的技巧。 [buy] 获得所有教学视频、课件、源代码等资源打包 [/buy] [Downlink href='http://urlxf.qq.com/?YrYFFfM']视频下载[/Downlink]
原文地址:https://www.cnblogs.com/LoveFishC/p/3847137.html