学训练营C版块前必看,C版块内容涉及到汇编的知识,其中有一些王爽老师汇编书上没有讲解的伪指令。
===========================================================
转载:汇编语言源程序用语句书写,MASM中可使用的语句分成两类,他们是指令性语句和伪指令语句
1.指令性语句:指令性语句与机器指令相对应,汇编程序将他翻译成目标代码(机器指令代码)。语句格为:
标号: 指令助记符 操作数,操作数;注释
标号表示指令语句的符号地址,标号后面必须紧跟“:”。标号可以省略,他经常作为转移指令或CALL指令的一个操作数,用以表示地址的转移。
指令助记符是该语句的指令名称的代表号码,他指出操作的类型,汇编程序将其翻译成机器指令。不可省略。
操作数表示参加本指令的运算数据,根据指令的操作类型,操作数不同,中间必须用“,”隔开。
注释指明一条指令的功能,可以省略。
2.伪指令语句
伪指令语句没有对应的机器指令。汇编程序汇编源程序时对伪指令进行处理,他可以完成数据定义,存储区分配,段定义,段分配,指示程序结束功能。伪指令语句的格式为:
名字 伪指令指示符 操作数,操作数;注释
名字时给伪指令取得名称,他用符号地址表示。伪指令中的名字通常是变量名,段名,过程名、符号名等。
伪指令指示符是汇编程序MASM规定的符号。
操作数是根据伪指令的具体要求来得。
3.数据项
汇编语言中使用的操作数,可以是常数、寄存器、存储器、变量、标号活表达式,其中常数、变量和标号是三种基本数据项。
⑴常数必须是固定的值,没有属性,是确定的数据。
⑵变量在程序运行中是可以修改的。所有的变量具有三种属性
①段值(SEGMENT):指明变量所在段的基址。
②段内偏移地址(OFFSET):指变量所在地址与段首地址之间的偏移字节数。
③类型(TYPE):变量的类型属性指变量中每个单元所包含的字节数,类型有:字节变量(BYTE)、字变量(WORD)、双字变量(DOUBLE WORD)
⑶标号:标号是指可执行指令语句的地址的符号表示,他可作为转移指令和调用指令的目标操作数,以确定程序转换的目标地址,他具有三个属性。
①段值(SEGMENT):指明标号所在段的基址。
②段内偏移地址(OFFSET):指标号所在地址与所在段段首地址之间的偏移字节数。
③类型(TYPE):标号的类型属性指在转移指令中标号可转移的距离类型.NEAR,表示近标号只能实现在本代码段内转移或调用;FAR,表示远标号,可;以作为其他代码段中的目标地址,实现段间调用或转移。
伪指令汇总
1.数据定义语句
格式一:变量名 助记符 操作数,操作数…;注释
格式二:变量名 助记符 n DUP(操作数,操作数…);注释
功能:将操作数存入变量名指定的存储单元中,或者只分配存储空间不存入数据。
变量名,用符号表示,可以省略。汇编程序时将此变量的助记符后的第一个字节的偏移地址作为他的符号地址。
助记符主要有:
DB:用来定义字节,表示每个操作数占用一个字节;
DW:用来定义字,表示每个操作数占用一个字;
DD:用来定义双字,表示每个操作数占用两个字;
DQ:用来定义四个字,表示每个操作数占用四个字;
DT:用来定义十个字节,表示每个操作数占用十个字节;
在格式二中,用n DUP表示时,n必须是整数,表示括号中的操作数的重复次数。DUP后面必须带括号。
2.表达式赋值语句
⑴赋值语句EQU
格式:符号名 EQU 表达式
功能:用来给变量、标号、常数、指令、表达式等定义一个符号名,程序中用到EQU左边得变量、标号时可以用右边的常数值或表达式来代替,但是一经定义在同一个程序模块中不能再重新定义。
⑵符号语句=
符号语句“=”与EQU语句具有相同功能,区别仅在于EQU中左边的标号不允许重新定义,而用“=”定义的语句可以重新定义。
3段定义语句
存储器的物理地址由段基址和偏移地址组合而成,任何一个逻辑段,无论是数码段,数据段,堆栈段,附加段都必须定义。以便连接程序把不同段和模块连成一个可执行的程序。
⑴段定义语句SEGMENT…ENDS
格式:段名 SEGMENT 定位类型 组合类型 ‘分类名’
逻辑段内容
段名 ENDS
功能:将一个逻辑段定义成一个整体
段名,是逻辑段的标识符,不能省略。他确定了逻辑段在存储器中的地址。必须以SEGMENT开始,以ENDS结束,前后段名必须一致。
定位类型,定位类型参数是对该段起始地址的定位。定位类型参数主要有下面4种:
①PARA:指定定位段的起始地址必须在节的整数边界,当定位类型缺省时,就当成PARA
②BYTE:指定定位段的起始地址定位在存储单元的任何字节地址。
③WORD:指定定位段的起始地址定位在字的边界,即段的首地址必须是偶数。
④PAGE:指定定位段的起始地址定位在页的边界,即段的首地址必须是256的整数倍。
组合类型:组合类型参数主要提供了各个逻辑段之间的组合方式
①NONE:该段与其他同名段不进行连接,各段独立于存储器中,NONE可作为缺省参数。
②PUBLIC:该段与其他模块中的同名段连接时,由低地址到高地址连接起来,组成一个逻辑段,连接次序由连接命令指定。
③COMMON:该段在连接时与其他模块中的同名段有相同的起始地址,采用覆盖的方式在存储器中存放,连接长度为各分段中最大长度。
④AT表达式:定位该段的起始地址在表达式所指定的节(16的整数倍)边界上。当用户要求某个逻辑段在指定节的边界上时,就要用AT参数来实现。
⑤STACK:指定该段为堆栈段,此参数在堆栈段中不可省略。
⑥MEMORY:定位该段与其他模块中的同名段有相同的首地址,采用覆盖的方法在存储器中组合连接。其功能与COMMON相似,区别是第一个带MEMORY参数的逻辑段覆盖在其他同名段的最上层,其他带此参数的同名段按照COMMON方式处理。
⑶“分类名”(CLASS NAME)
其主要作用是汇编程序连接时将所有的分类名相同的逻辑段组成一个段组。
2.段分配语句(ASSUME)
格式:ASSUME CS:段名,DS:段名,SS:段名,ES:段名
功能:定义4个逻辑段,指明段和寄存器的关系。
3.过程定义语句
格式:过程名 PROC 属性
过程内容
RET N
过程名 ENDP
功能:定义一个过程,主程序可以用CALL 指令调用他
过程名:给所定义的过程取得名字,不可省略。象标号一样具有三个属性:段属性、偏移地址属性和距离属性。
RET N为过程内部的返回指令。过程中至少一条RET,可以在任何位置,使过程返回到主程序调用他的CALL指令之下的一条指令。N为弹出值,可以缺省,表示从程返回以后,堆栈中应有N个字节的值作废。
4.程序开始和结束语句
⑴NAME:
格式:NAME 程序名
功能:为源程序目标模块赋名字。
⑵TITLE
格式:TITLE 文本名
功能:将文本名赋给源程序目标模块作名字,功能同NAM..
⑶ORG
格式:ORG 表达式
功能:给汇编程序设置位置指针,指定下面语句的起始偏移地址。
⑷END
格式:END 标号名
功能:标记汇编源程序结束
5.外部伪指令及对准伪指令
程序中包含多个模块时,有些程序或数据在各个模块间要相互共享,可用外部伪指令PUBLIC和EXTRN来实现此功能。
⑴外部伪指令
PUBLIC用来定义共享模块,EXTAN用来调用共享模块
格式:PUBLIC 名称,名称,…
EXTRN 名称:类型,名称:类型…
⑵对准伪指令
格式:EVEN
功能:EVEN伪指令使下一语句的地址调整为偶地址
⑶LABEL
LABEL伪指令给已定义的变量或标号取另一个名字,并可重新定义他的类属性
格式:名称 LABEL 类型属性
================================================
例
; * * * * * * * * * * * * * * * * * * * * * * *
data_seg1 segment ; 定义数据段
.
.
.
data_seg1 ends
; * * * * * * * * * * * * * * * * * * * * * * *
data_seg2 segment ; 定义附加段
.
.
.
data_seg2 ends
; * * * * * * * * * * * * * * * * * * * * * * *
code_seg segment ; 定义代码段
assume cs:code_seg, ds:data_seg1, es:data_seg2
start: ; 程序执行的起始地址
; set DS register to current data segment
mov ax, data_seg1 ; 数据段地址
mov ds, ax ; 存入DS寄存器
; set ES register to current extra segment
mov ax, data_seg2 ; 附加段地址
mov es, ax ; 存入ES寄存器
.
.
.
code_seg ends ; 代码段结束
; * * * * * * * * * * * * * * * * * * * * * * * * * *
end start
由于ASSUME伪指令只是指定某个段分配给哪一个段寄存器,它并不能把段地址装入段寄存器中,所以在代码段中,还必须把段地址装入相应的段寄存器中:
MOV AX,DATA_SEG1 ; 数据段地址
MOV DS,AX ; 存入DS寄存器
MOV AX,DATA_SEG2 ; 附加段地址
MOV ES,AX ; 存入ES寄存器
如果程序中还定义了堆栈段STACK_SEG,也需要把段地址装入SS中:
MOV AX,STACK_SEG ; 堆栈段地址
MOV SS,AX ; 存入ES寄存器
注意,在程序中不需要用指令装入代码段的段地址,因为在程序初始化时,装入程序已将代码段的段地址装入CS寄存器了。
为了对段定义作进一步地控制,SEGMENT伪指令还可以增加类型及属性的说明,其格式如下:
段名 SEGMENT [定位类型][组合类型]['类别']
.
.
.
段名 ENDS
[ ]中的内容是可选的,一般情况下,这些说明可以不用。但是,如果需要用连接程序把本程序与其他程序模块相连接时,就需要提供类型和属性的说明。
表4.2.1 ·定位类型:说明段的起始边界值(物理地址)。
定位类型 说 明
BYTE 段可以从任何地址边界开始
WORD 段从字边界开始,即段的起始边界值为偶数
DWORD 段从双字的边界开始,即段的起始边界值为4的倍数
PARA 段从小段边界开始,即段的起始边界值为16 (或10H) 的倍数
PAGE 段从页边界开始,即段的起始边界值为256 (或100H) 的倍数
注意:
定位类型的缺省项是PARA,即在未指定定位类型的情况下,则连接程序默认为PARA。BYTE和WORD用于把其它段(通常是数据段)连入一个段时使用;DWORD一般用于运行在80386及后继机型上的程序。
表4.2.2 ·组合类型:说明程序连接时的段组合方法。
组合类型 说 明
PRIVATE 该段为私有段,连接时将不与其它模块中的同名段合并
PUBLIC 该段连接时将与其它同名段连接在一起,连接次序由连接命令指定
COMMON 该段在连接时与其它同名段有相同的起始地址,所以会产生覆盖
AT 表达式 段地址=表达式的值,其值必为16位但AT不能用来指定代码段
MEMORY 与PUBLIC同义
STACK 将多个同名堆栈段连接在一起,SP设置在第一个堆栈段的开始
注意:组合类型的缺省项是PRIVATE。
例4.2 在连接之前已定义两个目标模块如下:
模块1 SSEG SEGMENT PARA STACK
DSEG1 SEGMENT PARA PUBLIC 'Data'
DSEG2 SEGMENT PARA
CSEG SEGMENT PARA 'Code'
模块2 DSEG1 SEGMENT PARA PUBLIC 'Data'
DSEG2 SEGMENT PARA
CSEG SEGMENT PARA 'Code'
以上两个模块分别汇编后产生 .OBJ 文件,经连接程序连接后产生的 .EXE模块如下:
模块1 CSEG SEGMENT PARA 'Code'
模块2 CSEG SEGMENT PARA 'Code'
模块1+2 DSEG1 SEGMENT PARA PUBLIC 'Data'
模块1 DSEG2 SEGMENT PARA
模块2 DSEG2 SEGMENT PARA
模块1 SSEG SEGMENT PARA STACK
- [ltp1234] push cx add si,1 ;结果的数字个数 04/09 01:58
- [ltp1234] 写的很好!! 04/08 23:48
- [游客] 我也不知道说些什么 挺一下好啦 04/03 20:50
- [e56004474] 没事的话,别坐电车。 据说。。。 03/17 18:52
- [waasmedu] 拜读!受教!! 12/21 11:18
- [chinatree] 不错,顶。 12/05 03:32
- [ljl] 晕,最后一题也没有想到。。。 12/04 14:56
- [mouse] 楼上的看错了,填空位置填inc cx,就是为了找到第一个值为0的byte 07/29 15:37
- [wbkyh] 检测点9.2中,loop s指令有问题,该指令执行后,cx=cx-1,如果cx=0,则循环结束,也就 06/28 09:32
- [游客] 结果是1,*p取得的是a的地址中的内容,也就是a的值 06/08 00:22
- [lp1989] 请教一道题: 在数据段BUF下开始已定义了信息“I LIKE IBM-PC”, 编写在屏 幕上显 12/29 13:32
- [fangaiyisheng] 飘过,很好 ,很强大! 06/18 06:05
- [游客] [ lyh1984 发表于 2009-06-26 10:39 ] 请问一下,我用DEB 07/15 10:59
- [lyh1984] 请问一下,我用DEBUG为什么调不出字符串呢?我想知道你们是怎么调的,是用CMD DEBUG吗? 06/26 10:39
- [q470393267] 我看你头像半天了,那猫和老鼠能抗啊都没有死~ 05/05 21:31
- [fangyugirl] 经过上机DEBUG,我已经知道问题在哪里了,谢谢你呀。 04/09 10:31
- [fangyugirl] 我是想问你第10章的第三个子程序,这个子程序我现在主要的问题是12666/10会产生溢出,所以我调用 04/09 09:57
- [mouse] [ wangping198611 发表于 2009-03-23 11:43 ] 03/31 10:28
- [mouse] miaozaoyang 发表于 2009-03-29 22:31 ] [ 删除留 03/31 10:23
- [miaozaoyang] 又得问你个问题了,不知道为什么,实验15 不能够正常进行,程序应该是没有任何问题的,还是操作系统的问 03/29 22:31