80x86只提供几种底层的数据类型,供各机器指令操作。这些数据类型如下:
●“字节”(byte)—存放任意的8位数值。
●“字”(word)—存放任意的16位数值。
●“双字”(double word,又称dword)—存放任意的32位数值。
●“四字”(quad word,又称qword)—存放任意的64位数值。
●“32位实数”(real32,又称real4)—存放32位单精度浮点数。
●“64位实数”(real64,又称real8)—存放64位双精度浮点数。
注意: 80x86汇编器一般都支持十字节(tbyte,即ten byte)和“real80/real10(80位实数)”,但我们不打算用这些数据类型,因为大部分现代64位高级语言编译器并不使用它们。不过,个别C/C++编译器以“long double”数据类型来支持real80的数值;Swift也在Intel机器上支持real80值,它用的是float80数据类型。
HLA汇编器由于有高级语言的特性,会提供相当多的单字节数据类型,包括字符型、有符号整型、无符号整型、布尔型和枚举类型。用汇编语言编写应用程序时,要是有这么多种数据类型,再带上HLA提供的类型检查功能,该多好。然而依据本意,我们真正需要的是为字节变量分配存储空间,或为较大的数据结构分配一个字节块。HLA的byte类型足以应付8位变量及数组的声明。
在HLA的static部分可以这么声明byte变量:
要为字节块分配存储空间,可用下列的HLA语法:
这些HLA声明将创建未初始化的变量。从技术上讲,HLA总是将static变量初始化为0,因此,它们并非未初始化。这里主要是指代码并没有将byte变量显式初始化为某值。不过,让HLA使用类似下面的语法,可以在操作系统把程序调入内存时将字节变量初始化到某个值:
MASM一般在.data节中用db或byte指示性语句,为字节或字节变量数组分配存储空间。单个字节的声明可采用下面两种等效方式中的一种:
这两个声明都创建未初始化的变量—实际初始化为0,就像HLA中那样。db/byte中的“?”操作数域通知汇编器:我们不想显式声明此变量为某个值。
要声明一个字节块的变量,可用下列语法:
要创建初始值非零的变量,可以用类似下面的语法:
要想创建元素值不等的字节型数组,只需在db/byte指示的操作数域列出这些值,其间以逗号分隔即可:
GNU的Gas汇编器在.data节中使用.byte指示性语句声明字节变量。该指示性语句的一般形式如下:
Gas不提供显式形式来创建未初始化的变量,如果需要创建这种变量,应对其设置操作数0。下面是Gas中的两个实际变量声明:
Gas也未提供显式的指示性语句来声明字节变量数组,但可以像下面那样通过.rept/.endr指示性语句创建.byte指示性语句的多个拷贝:
注意: 如果想把数组元素初始化为不同的值,应提供一个用逗号分隔各值的清单。
这里是在Gas里声明数组的一些示例:
在汇编语言中访问字节变量
要访问字节变量,只需在80x86寻址模式中使用声明变量时的名字即可。举个例子,假如有一个字节变量名为byteVar,另一个字节数组名为byteArray,可以使用如下mov指令将变量值送入寄存器AL—这些示例都被假定为32位代码:
对于16位长的变量,HLA使用word数据类型,MASM使用dw或word指示性语句,而Gas使用.int指示性语句。这些指示性语句除了所声明的变量尺寸不同外,其用法与字节变量的声明并无区别。例如:
对于32位变量,HLA使用dword数据类型,MASM使用dd或dword指示性语句,而Gas使用.long指示性语句。例如: