您好,欢迎访问三七文档
当前位置:首页 > IT计算机/网络 > 数据库 > 汇编言语――变量、数据段
1变量定义2变量的内存分配返回章目录1变量定义1.1变量名变量的名字是它的外包装,是用来区分不同的存储区域的标识符号,是一种标识符。不同的语言对标识符命名的规定有所不同,但大体上都把“以字母开头的字母数字串”作为基本规定。8088的汇编语言还允许用下面的特殊符号作为标识符的构成符号:8088的汇编语言还允许用下面的特殊符号作为标识符的构成符号:?@$%_标识符是一个或多个符号构成的符号串,汇编语言对标识符命名的完整规定是:(1)可用符号包括字母、数字和特殊符号“?”、“@”、“$”、“%”、“–”。(2)不允许用数字作为第一个符号。(3)名字的长度没有严格限制,但一般不超过10个符号。(4)最少由一个符号构成,可以是字母、“_”或“@”。(5)汇编语言不区分字母的大小写。1.2变量定义的方法变量的实质是存放数据的内存区域,所谓变量定义就是告诉汇编程序,在翻译时从某个地址起预留一定数量的内存空间,并在其中填上初值,还要建立变量与地址间的对应关系。所以变量定义是伪指令而不是指令。【格式】变量定义的基本格式是:变量名类型初值表【说明】(1)类型部分只能出现DB、DW、DD、DQ、DT这几种内部保留字,用以说明初值表中的每个数据占几个字节,对应关系如下:DB──字节型,每个数据占1字节;DW──字型,每个数据占2字节;DD──双字型,每个数据占4字节;DQ与DT很少用,不作说明。2)初值表是用逗号分隔的若干个数据项,每个数据项的值是变量的一个初值项,占据“类型”规定的字节数,所以初值表一方面说明变量的初值是多少,另一方面也指明了变量占多少字节的存储空间。(3)对于DW和DD类型,每个数据项的存储遵照“高字节在高地址,低字节在低地址”的原则。(4)每个数据项的书写方法可以是任何数制的整数或者由整数构成的计算式,也可以是字符,如果用整数书写,可以是无符号数,也可以是带符号数。(5)当类型是DB时,初值表可以是任意长度的字符串,而DW类型只允许长度不超过2的字符串。(6)如果初值表需要填写若干个相同的值,可以用下面的形式表示把一个值重复若干次:重复次数DUP(数据项)(7)初值表中可以用问号“?”作为初值项,含义是用户程序不设定初值,而由汇编程序安排,对此汇编程序将在翻译时把这类初值项都以数值0填充。(8)任何段中都可以写变量定义,也允许把指令与变量定义写在一个段内,但通常是把程序所用到的所有变量集中在一个段内进行定义,而把指令写在另一个段中。习惯上把定义变量的段称为数据段,写指令的段称为代码段或指令段。【例1】 说明data段中定义的各变量的类型及初值情况,以及每个变量占据的内存字节数。dataSEGMENTd1DB1d2DW1234Hd3DD12345678Hd4DB'1','2','3'd5DB'123'd6DB30DUP(0)d7DB1,3DUP(2),'3',-3,1001Bd8DB1,2,3,4,5,6DB7,8,9,10d9DW'12','AB'd10DW3-5dataENDS【解】(1)变量d1是字节型,初值是01H,占1字节。(2)变量d2是字型,初值是1234H,占连续的2个字节,并且地址号大的字节中放12H,地址号小的字节中放34H。(3)变量d3是双字型,初值是12345678H,占连续的4个字节,按地址由小到大的次序,4个字节中的内容依次是78H、56H、34H、12H。(4)变量d4是字节型,共占3个字节,可视为字节型数组,按地址由小到大,3个字节中的值依次是31H、32H、33H。(5)变量d5是字节型,共占3个字节,初值情况与变量d4的完全相同,所以d4与d5的变量定义只是在写法上不同而已。(6)变量d6是字节型,共占30个字节,每个字节中都是0,其中用到了把初值0重复30次的写法。(7)变量d7是字节型,共占7个字节,各字节的初值按地址由小到大的次序依次是01H、02H、02H、02H、33H、0FDH、09H,把各种写法混合在一个变量的定义中使用。(8)变量d8是字节型,共占10个字节,分别把1到10按地址由小到大依次填到这10个字节中,写法上把一个变量定义分作两行写,这是初值表中数据项很多一行写不完而转行的写法。(9)变量d9是字型,由2个数据项构成,分别被当作3132H和4142H看待,共占4个字节,按地址由小到大依次是32H、31H、42H、41H。(10)变量d10是字型,初值是一个可由汇编程序直接计算的计算式,计算结果-2用补码形式填写到2字节内存中,高地址中是0FFH,低地址中是0FEH。1.3变量的三个基本属性任何变量表面上都以一个标识符的形式出现,也就是它的名字,每个变量都有三个数据与之相对应,这就是变量的三属性。1.3.1段属性变量的段属性也就是变量所在段的段地址。变量定义必须写在一个段的范围之内,每个段在程序进入内存时被操作系统安排一个确定的段地址。在编写程序时可以用段的名字指出某处要使用段地址,而这个段中的所有变量都统一地以这个段地址作为逻辑地址中的段部分。如果在编写程序时需要使用某个变量的段地址,一种方法是用该变量所在段的段名。比如,对例5.1中定义的变量d1,如果要把它的段地址取到寄存器AX中,可以写作:MOVAX,data取段地址的另一种方法是在变量名的前面加上保留字SEG。比如,下面的写法与上述指令的功能完全相同:MOVAX,SEGd1保留字SEG是伪指令,用于告诉汇编程序上述指令的源操作数是变量d1所在段的段地址,而不是变量d1中存放的数据。这两条指令中的源操作数都是立即寻址方式,操作数在指令当中。这与指令“MOVAX,d1”有着本质差异,后者的源操作数是直接寻址方式,操作数在内存当中,是“MOVAX,[d1]”的变形。1.3.2偏移属性变量的偏移属性也就是变量所在的段内偏移地址。在第2章中已经说明,偏移地址表示段内某一位置到段起始地址的距离,偏移地址为0表示就在段的起始处。一个段中可以定义多个变量,每个变量占据一定的内存空间,到段起点的距离也就不一样,所以一个段内的各个变量都具有不同的偏移地址。在编写程序时,指令中使用某变量就是按照它的偏移地址到所在段中取出数据,或把数据存到相应内存。如果在编写程序时需要使用变量的偏移地址,一种方法是在变量名的前面加上保留字OFFSET。比如,把例5.1中的变量d1的偏移地址取到寄存器AX中,写作:MOVAX,OFFSETd1这条指令中的源操作数是把伪指令OFFSET加在变量d1的前面,表示取d1的偏移地址,是立即寻址方式,操作数就在指令当中。请注意与前面所提到的取段地址和取值的写法进行对比。取偏移地址的另一种方法是用汇编语言中的一条专用指令。【指令格式】 LEAd1,d2【功能】把源操作数d2的偏移地址取到目的操作数d1中。【说明】(1)这是一条数据传递类指令,不影响标志位。(2)该指令专用于取源操作数的偏移地址,所以源操作数d2一定是内存型寻址方式,可以是内存型操作数5种寻址方式中的任何一种。(3)当d2是变量名形式的直接寻址方式时,变量名两边的方括号可以省略。(4)目的操作数d1一定是寄存器型,且必须是16位的字型通用寄存器,不能是段寄存器。LEA指令专门用于取偏移地址,而MOV指令中把变量名字的前面加上伪指令OFFSET作为源操作数,也可以取出偏移地址。这两种取偏移地址的方法在很多时候可以相互替代,但它们也有一些不同的地方,有必要把两者进行对比:(1)寻址方式不同。用OFFSET后接变量名的形式出现的操作数是立即寻址方式,LEA指令中的源操作数是内存型寻址方式。下面两条指令都可以把例5.1中的变量d1的偏移地址取到寄存器AX中,执行效果是一样的,可以相互代换。MOVAX,OFFSETd1LEAAX,[d1](2)LEA指令在功能上比OFFSET更强。通过例5.2中的几条语句的语法正误对比,可以准确地掌握两者的差别。【例2】设buf是一个变量,偏移地址是10H,BX=1000H,SI=200H,判断下列各语句的正确性,对正确的指令说明其功能。(1)MOVAX,OFFSETbuf(2)MOVAX,OFFSETbuf+3(3)MOVAX,OFFSET[BX](4)MOVAX,OFFSET[BX+3](5)MOVAX,OFFSETbuf[BX](6)MOVAX,OFFSETbuf[BX][SI](7)LEAAX,buf(8)LEAAX,[buf](9)LEAAX,[buf+3](10)LEAAX,[BX+buf](11)LEAAX,[BX+3](12)LEAAX,[BX+SI](13)LEAAX,[BX+SI+buf]【解】(1)正确,常规用法,把buf的偏移地址10H作为立即数送到AX中。(2)正确,把“OFFSETbuf”作为立即数,是10H,与另一个立即数3相加,结果13H送到AX中。(3)错误,应该写作MOVAX,BX。(4)错误,应该先用MOV指令把BX的值送到AX中,再用ADD指令把AX的值加3。(5)正确,把“OFFSETbuf”作为立即数看待,是10H,源操作数是把BX的值加上立即数10H,得到1010H,再以1010H为偏移地址,与BX对应的缺省段寄存器DS一起构成逻辑地址,到内存中寻找操作数。该指令汇编的结果相当于MOVAX,[BX+10H]。(6)正确,把“OFFSETbuf”作为立即数看待,是10H,该指令相当于MOVAX,[BX+SI+10H]。(7)正确,常规用法,把buf的偏移地址10H送到AX中。(8)正确,与(7)的功能完全相同,是两种不同的写法。(9)正确,计算出源操作数的偏移地址13H,送到AX中。(10)正确,计算出源操作数的偏移地址1013H,送到AX中。(11)正确,计算出源操作数的偏移地址1003H,送到AX中。(12)正确,计算出源操作数的偏移地址1200H,送到AX中。(13)正确,计算出源操作数的偏移地址1210H,送到AX中。1.3.3类型属性类型属性也就是变量的类型,变量在定义时必须用DB、DW等伪指令说明类型。说明变量的类型,一方面告诉汇编程序在翻译时把该变量定义中的每个数据项用几个字节存放,另一方面说明该变量的使用方法。MOV等双操作数指令中的两个操作数必须是同一种类型。汇编程序在翻译时要进行类型检查。当一个操作数是寄存器,另一个是变量时,两者的类型一致是正常情况,当两者类型不同时,汇编程序将以寄存器的类型为准进行翻译,并提出警告(Warning);当目的操作数是变量,源操作数是立即数时,就以变量定义时的类型为准。如果有必要,使用变量时可以临时改变类型,后面将以具体例子说明使用方法。2变量的内存分配2.1内存图内存图表示的内容有两个方面。一方面是存储器,通常由若干个叠放在一起的小方框表示,每个方框代表一个字节。虽然每个字节有自己确定的物理地址,但是,由于编写程序时使用的是逻辑地址,而逻辑地址到物理地址的转换由计算机自动实现,所以画变量分配的内存图时,一般标以各字节的偏移地址,段地址部分被省略。在表示一个字节的小方框内填上数值,表示该字节中的内容。填写数值时可以用各种数制、各种写法,但用十六进制数会有助于理解。另一方面,内存图还要表示变量名与偏移地址的对应关系,把变量的名字写在对应的方框的边上。图5.1是一个内存图的实例。图5.1总体上分为三部分,中间是表示内存各字节的方框,各方框的右边标以偏移地址,左边则标出变量的名字。从图中可以看到:变量名字var1标在代表偏移地址为0的方框的左边,表示变量var1是从段的最前面开始安排的;变量var2标在偏移地址3处,一方面表示var2从偏移地址3开始安排;另一方面还表明变量var1占据偏移地址为0到2的3个字节;类似地,变量var3的起始偏移地址是5,所以变量var2占2个字节。从图中还可以清楚地看到每个变量的取值情况。从图5.1中无法看出3个变量的类型,这一点可以通过在变量名的下面标上类型加以弥补。从另一个角度看,不标类型还说明变量是不注重类型的。换句话说,源程序翻译成机器语言之后,指令中没有变量而只有偏移地址,类型是通
本文标题:汇编言语――变量、数据段
链接地址:https://www.777doc.com/doc-4312823 .html