汇编语言程序格式二
前言
语句格式
语句基本格式
数据定义及存储器分配伪操作
伪操作格式
操作数可以是常数,或表达式
(表达式得有一个确切的结果)
例3
DATA_DW DD 320,0FFFDH
**320是一个立即数的算式,这条语句向内存中存了一个60**,一个0FFFDH。且60被扩展成32位二进制数,存在4个内存单元中,0FFFDH也是。
类似的还有 MOV AX,1001H+1002H
(注意这里的0FFFDH是一个4位16进制数,以字母开头要在前面加0)
例4
操作数?可以保留存储空间,但不存入数据
DFF DW 52
要把52转换为二进制,扩充为16位的,也就是两个字节大小,再存入内存
复制操作符来复制某个(或某些)操作数
DUP是一个操作符,和db,dw,dd等伪指令配合使用,用于进行数据的重复,
如
BUFF DB 9 DUP (?)
参考汇编中的重复指令
例5,ARRAY1是把0,1,2,?这一组重复2此
ARRAY2是定义100个字节空间但是不存数
例6
ARRAY3 DB 100 DUP (0,2 DUP(1,2),0,3)
DUP的嵌套使用
ARRAY3是(0,1,2,1,2,0,3)这一组数重复100遍。
这是一种用法,存地址
DW把变量或标号的偏移地址存入存储器
DD把16位段地址和16位偏移地址组成的地址存入存储器。第一个字为偏移地址(低地址),第二个字(高地址)为段地址。
逻辑地址=段地址+偏移地址
CS在大地址(高地址),IP在小地址(低地址)这是一只遵循的原则,就像高位在高地址一样,不管在哪里都是这样的
例7里的PAR1,PAR2等都是变量。
用LABEL伪操作来定义指令
LABEL的意义为指向下一个要被赋予地址的地方,并且并不分配内存空间。
LABEL 伪指令可以插入一个标号,并定义它的大小属性,但是不为这个标号分配存储空间。
LABEL的功能是定义变量或标号的类型,而变量或标号的段属性和偏移属性由该语句所处的位置确定。
LABEL语句与紧接着的下一条变量和标号定义语句相关。
例如
BUFFER1 LABEL WORD
BUFFER2 BD 20 DUP (?)
通常,紧接着的下一条语句定义的类型与LABEL指定的类型不同。而实际上,BUFFER1是BUFFER2的别名,两者指向内存中的同一个内存地址。换言之,同一组数据定义了两种不同的类型,在接受不同数据类型的访问时,可以指定相应的标号。如接受一个字类型数据访问时,使用BUFFER1;接受字节类型数据访问时,使用BUFFER2,否则因为数据类型不匹配,编译器编译时将出现异常。
总之,LABEL语句一定和它后面的语句相关联,也可以理解成LABEL定义了一个标号,或者变量,但是这个标号或者变量它是不占用内存空间的!他就是空指,就像一个标签。
BYTE_ARRAY LABEL BYTE
LABEL是伪操作指令,BYTE指示数据类型。
BYTE_ARRAY是名字。
BYTE_ARRAY这个变量指向这个语句的位置,变量的地址属性就是这个语句的地址。但是这个变量不占内存单元,就像一个便签。
WORD_ARRAY DW 50 DUP(?)
这是定义50个字的空间,也就是100个字节。
WORD_ARRAY和BYTE_ARRAY都指向这50的字的第一个字节!它们用于接收不同数据类型的访问。
TOS LABEL WORD
TOS没什么特别的,就是起的一个名字而已,意思是TOP OF STACK,这个标签贴在50个字的下一个存储单元。
所以要注意,BYTE_ARRAY指向50个字的第一个内存单元,而不是前一个存储单元。TOS是指向这50个字的下一个内存单元。
在这里提一嘴,堆栈是先定义一定的空间,入栈的时候先进入的元素存在大地址,也就是说堆栈是从高地址向低地址方向扩展。
TOS就是在这段空间的下一个内存单元。
这个图比较清楚
所以不用太纠结TOS的含义!反正他就是指向栈的后一个单元。
栈空的时候,SS:SP就指向TOS