《汇编语言》学习笔记6——伪指令
1.伪指令又称伪操作,即不能像汇编指令一样生成可执行的二进制机器代码,而是在汇编程序对汇编语言源程序进 行汇编(编译)期间,由汇编程序执行。它与C中的说明性语言的含义类似,起到说明作用,用来指出程序分段、数据定义、存储分配、程序开始和结束等信息,这 些信息在汇编(编译)完成后就不用了。但程序中没伪指令,则系统就无法完成编译。
2.段定义伪指令:用来定义各种类型的段
1.格式:段名 SEGMENT [类型参数] ...... 段名 ENDS
1.其中SEGMENT和ENDS必须成对出现,表示段的开始和结束。一般的,段名和段的意义一致,便于识别。
2.段名实际就是段地址,在汇编过程中,系统给出具体的地址值,一个段必须有一个名字来标识。
3.参数是可选项(可有可无),用于指出段的边界、段的组合、类别标识,一般用于多模块程序设计中。
2.类型参数
1.定位类型
PARA 该段的起始地址必须为小段的首地址,即起始地址的16进制数最低位为0
BYTE 该段可以从任意地址开始
WORD 该段必须从字边界开始,即起始地址为偶数
DWORD 该段必须从双字边界开始,即起始地址的16进制数为最低应为4的倍数
PAGE 该段必须从页边界开始,即起始地址的16进制数最低两位为00(能被256整除)
若不指定定位类型,系统默认为PARA
2.组合类型
PRIVATE 该段为私有段,连接时不与其他同名段合并
PUBLIC 连接时可与其他模块中的同名段按顺序连接成一个段
COMMON 表示该段与其他模块中的同名段有相同的起始地址,如果连接将产生覆盖,连接后段的长度为同名段中的最长者
STACK 表示该段为堆栈段
AT 表达式 该段直接定位在表达式指出的位置上
若不指定组合类型,默认为PRIVATE
3.类型标识:在引号中给出段的类型名。在连接时,类别标识相同的段放在连续的存储区中。(如:"STACK"用啦标识该段为堆栈段)
4.END:结束标记,若碰到伪指令END则停止编译
3.ASSUME伪指令:用于指明段寄存器与段的对应关系
1.格式:ASSUME 段寄存器:段名,[段寄存器:段名,段寄存器:.....]【[]中标识可选项】
2.除了代码段寄存器CS不能用MOV指令赋值外,其他段寄存器都可用MOV指令进行初始化。注意:段地址(即段名)不能直接传送给段寄存器,要用一个寄存器作为中介转存一下。若在编写源程序时,只有数据段和代码段,则只需要给出数据段段寄存器DS赋值即可。
4.数据定义伪指令
1.程序中用到的存储单元个数、类型、内容、和名称等需要在数据段中定义
2.作用定义存储单元的类型,并确定该单元的内容
3.格式:[存储单元名] DB(或DW、DD) 操作数
其中:
1.存储单元名可有可无
2.数据定义伪指令
DB 定义字节单元
DW 定义字单元
DD 定义双字单元
DQ 定义四字单元
DT 定义十字节单元
3.操作数用于指出存储单元的内容,即该单元的值。一个数据定义伪指令可以给多个存储单元赋值
1.注意:确定存储单元的内容要与存储单元的属性一致
2.操作数是常数或表达式
1.一次定义多个存储单元,字母打头的16进制数要在前面加0,"?"代表空单元【xx DB 12,0,0E4 定义3个字节单元初始化分别为十进制12,0和16进制E4 YY DW 5,?,6*3 定义3个字单元初始化分别为5,空,6*3的值】
2.用DUP()子句重复定义相同操作数【MSN DB 5 DUP(?) 定义5个字节空单元,即循环定义5次,每次定义一个字节空单元】,格式:数字 DUP(操作数) 数字表示循环的次数,操作数表示单元值
3.DUP()子句可以嵌套
例:BUF DB 2 DUP(96,2 DUP(1,4),8)
分析:先进外层循环(执行两次):定义一个字节单元并初始化为96,此时进到内层循环(执行两次):定义两个字节单元并初始化为1,4。重复执行然后跳出内层循环,定义一个字节单元并初始化为8。然后在重复执行外层循环,最后跳出。【一次在内存中的存储:{60(十进制96)、{01、04、(内层一次循环)}{01、04、(内层二次循环)}08、(外层一次循环)}{60、01、04、01、04、08(外层二次循环)}】
3.操作数是字符串
1.定义字符及字符串,要用单引号括起来【x DB 'A','B'】。由于字符串又ASCII码表示,存入的是该字符的ASCII码,则字符串应用DB伪指令定义,DW定义只能是两个字符以内,且两个字符看成一个字。【x1 DB 'A','B'和x2 DW 'AB'的存储结果是不同的,x1:A、B x2:B、A】
2.定义字符必须用DB。(DB定义的存储单元为字节单元,一个单元保存一个字符。DW定义的单个字符要占两个字节单元。)
5.其他伪指令
1.赋值伪指令:EQU、=
1.可以用EQU定义一个符号来代表表达式或数。 格式:符号 EQU 数/表达式
2.=也可以给表达式赋值。 格式:符号 =数/表达式
3.=允许对一个符号多次重复定义,EQU不允许重复定义
2.模块定义伪指令:程序可定义为多个模块,用LINK连接。模块可用模块定义伪指令,定义名称和结束标识。
1.格式:[NAME 模块名] ...... END 起始标号
1.NAME伪指令可缺省,若缺省则以该模块的源程序名作为模块名,END伪指令不能缺省,其后的起始标号可是程序第一条汇编指令的标号START,或是主过程名。用来指出程序的起始地址,也是对代码段寄存器CS初始化的依据。
3.地址计数器$:表示当前的偏移地址值
1.在数据段的存储单元定义中使用:ABC DW 1,2,$+3,4 ABC+0字单元存放1,ABC+2字单元存放2,ABC+4字单元存放7(4+3,因为$当前为4),ABC+6字单元存放4
2.$不能用于字节单元定义伪指令DB中
3.用在转移指令中:JMP $+5 无条件跳转到当前指令的偏移地址+5单元继续执行
4.设置偏移地址伪指令
1.当前的偏移地址可用ORG伪指令定义
2.用在数据段中,该指令可确定存储单元的偏移地址。
3.用在代码段中,可从指定的单元开始存放并执行指令。
5.操作符:在汇编时将操作符变为相应的数值回送或定义属性
1.回送偏移地址值OFFSET【MOV BX,OFFSET X 将x单元的偏移地址传送给BX】
2.回送段地址值SEG【MOV BX,SEG X 将x单元的段地址传送给BX】
3.类型回送操作符TYPE【MOV BX,TYPE X 若x是字节单元,则回送值为1,即BX=1。若是字单元,值为2,双字节单元值为4,即BX=4】
4.变量数回送操作符LENGTH【MOV CX,LENGTH Y 若Y是用DUP()定义的,CX=变量个数】
5.字节数回送操作符SIZE【MOV AX,SIZE Y 若Y是用DUP()定义的,给出变量个数所占字节总数】
6.属性定义操作符PTR【MOV BYTE PTR [BX],10 定义目的操作数为字节单元,MOV WORD PTR [SI],20 定义目的操作数为字单元】
7.多重属性操作符THIS【X1 EQU THIS BYTE X2 DW 1234H THIS要求与EQU配合,X1和X2单元是同一单元,但属性不一样,x1为字节,X2为字】
8.类型操作符LABEL【x LABEL BYTE 将x单元的类型定义为BYTE字节型】
6.注释伪指令:;后面内容为注释。