您的位置:首页 > 编程语言

写汇编程序前的准备知识

2007-05-22 11:09 218 查看
做汇编程序的步骤:
1.用编辑程序建立.asm源文件
2.用masm程序把.asm文件转换成obj文件。
3.用link程序把.obj文件装换成.exe文件或用exe2bin程序把.exe文件装换成.com文件。

汇编语言源程序的结构
源程序由段组成,每段有一个段名,segment定义段起点,ends定义段结束点。
每段由若干语句行组成,源程序以end结束。
汇编语言源程序是段结构的:代码段、数据段、堆栈段、附加段

1机器指令:指令——使CPU产生动作、并在程序执行时才处理的语句,就是前一章学习的处理器指令
2伪指令(Directive)——不产生CPU动作、在程序执行前由汇编程序处理的说明性语句,例如,数据说明、变量定义等等
 伪指令与具体的处理器类型无关,但与汇编程序的版本有关
3宏指令:由一系列指令或伪指令构成,汇编时展开成若干条机器指令,用于提高编程效率。
伪指令和宏指令由汇编程序在汇编期间处理

1.变量的三种属性:
   段值(SEG):变量所在段的起始地址
   偏移量(OFFSET):段起点距离变量所在存储单元位置的字节数
   类型(TYPE):变量占用的字节数
2.标号 标号:存放指令的存储单元的符号地址,常用作转移地址。如定义的next:
标号的三种属性同变量 type包括 NEAR , FAR

伪操作符号介绍:
DB伪操作:用来定义字节,其后的每个操作数都占有一个字节。
DW的操作:用来定义字,其后的每个操作数占有一个字(低位字节在第一个字节地址中,高位字节在第二个字节地址中)。
DD伪操作:用来定义双字,其后的每个操作数占有二个字。
DQ伪操作:用来定义四个字,其后的每个操作数占有四个字。
DT伪操作:用来定义十个字节,其后的每个操作数占有十个字节,形成压缩的BCD码。

操作数可以是常数,或者是表达式(根据该表达式可以求得一个常数),如
    DATA_BYTE   DB   10,4,l0H
    DATA_WORD  DW   100,100H,-5
    DATA—DW    DD   3*20,0FFFDH
    MESSAGE   DB    ‘H2LLO’;定义字符串
  
操作数?可以保留存储空间,但不存入数据。
如:ABC  DB  0,?, ?, ?,0
    DFF  DW  ?, 52,  ?

操作数字段还可以使用复制操作符来复制某个(或某些)操作数。其格式为:
            repeat_count   DUP(operate,  operate,…)
其中repeat_count可以是一个表达式,它的值应该是一个正整数,用来指定括号中的操作数的重复次数。
例如:
ARRAYl   DB  2  DUP(0, 1,2,?)
和以下语句是等价的:
ARRAYl  DB  0,I,2,?,0,1,2,?
DUP操作可以嵌套,例如
ARRAY3  DB  100DUP(0,2  DUP(1,2),0,3)

EQU相类似的 = 伪操作也可以作为赋值伪操作使用。它们之间的区别是:EQU伪操作中的表达式名是不允许重复定义的,而 = 伪操作则允许重复定义。
即可以
   emp = 7;
   ....
   emp = emp + 1;
  
存储器的物理地址是由段地址和偏移地址组合而成的,汇编程序在把源程序转换为目标程序时,
必须确定标号和变量的偏移地址,并且需要把有关信息通过目标模块传送给连接程序,
以便连接程序把不同的段和模块连接在一起形成一个可执行程序。为此,需要用段定义伪操作
举例:
data  segment
....
data ends
还要明确段和段寄存器的关系,这可用ASSUME伪操作来实现,其格式为:
assume ds:data
其中段寄存器名必须是CS、DS、ES和SS中的一个,而段名则必须是由segment定义的段中的段名。
而ASSUME  NOTHING则可取消前面由ASSUME所指定的段寄存器。 

DS和ES的装入 立即数不能直接送入段寄存器 所以要通过寄存器传值
通过寄存器传送
如:MOV    AX,DATA1
    MOV    DS,AX
    MOV    AX,DATA2
    MOV    ES,AX

指示汇编程序MASM到此结束汇编过程  (注意汇编结束并不是源程序终止)
源程序的最后必须有一条END语句
 SEGMENT伪操作还可以增加类型及属性的说明,格式如下 :
段名     SEGMENT    [定位类型]  [组合类型] [段字][类别名]
                  ?
段名     ENDS
一般情况下,这些说明可以不用。但是,如果需要用连接程序把本程序与其他程序模块相连接时,就需要使用这些说明。分别叙述如下:
1.定位类型(align_type)可以是:
实际上定位类型可以理解为"对两个相临段的段地址给予的一些规定"。定位类型可以有以下几种:
PARA:指定所定义的段开始于小段边界,实际是规定这个段的起始地址与前面一个段的起始地址之差必须是16字节的整数倍。
这意味着相临两个段的段地址之差最小也得是1。
PAGE:指定定义的段开始于页边界,实际是规定这个段的起始地址与前面一个段的起始地址之差必须是256字节的整数倍。
BYTE:所定义的段开始于字节边界,实际上是指这个段可以从任何地址开始。
WORD:所定义的段开始于字边界,实际是指这个段只能从偶数地址开始。
如果源程序中指定了段的定位类型为PARA或PAGE,那么获得的可执行文件中相临段的段地址就有差异。
    但是如果源程序中指定了段的定位类型是BYTE或WORD,那么在可执行文件中相临段的段地址就有可能相同。
2.
组合类型  (combine_type)设置一定的组合类型就可以通知LINK程序把一些分散在不同模块内的同类型段组织在一个段内,这样可以使最终形成的可执行文件结构比较清晰。
PUBLIC  该段连接时将与有相同名字的其他分段连接在一起。其连接次序由连接命令指定。
COMMON  该段在连接时与其他同名分段有相同的起始地址,所以会产生覆盖。COMMON的连接长度是各分段中的最大长度。
AT  expression  使段的起始地址是表达式所计算出来的16位段地址。但它不能用来指定代码段。
STOCK  指定该段在运行时为堆栈段的部分。
MEMORY  指定该段将分配在所有其他连接在一起的段的前面(在高地址上),如果连接时有几个指定MEMORY的段,则遇到的第一段作为MEMORY段,其他则作为COMMON段.

(3)段字属性/寻址类型(Use)——这是为32位段设置的属性。对于16位x86CPU默认的是16位段,即USE16,而对于汇编32位x86CPU指令时,默认采用32位段,即USE32,但可以用USE16指定标准的16位段。编写运行于实地址方式(8086工作方式)的汇编语言程序,必须采用16位段。即,对于80386及以上,可以设定为USE16或USE32,代表16位寻址或32位寻址,当处理器是386级以上时,保护模式下缺省为USE32,其它模式为USE16,对于386以下的CPU,不具备32位寻址方式,只能是USE16。
(4)类别(Class)——当连接程序组织段时,将所有的同类别段相邻分配。段类别可以任意命名,但必须位于单引号中,大多数MASM程序使用‘code’、‘data’和‘stack’来分别指示代码段、数据段和堆栈段,以保持所有代码和数据的连续。

五。程序开始和结束
在程序的开始可以用NAME或TITLE为模块取名字,NAME的格式是:
    NAME  module_name
汇编程序将以给出的module_name作为模块的名字。如果程序中没有NAME伪操作,则也可使用TITLE伪操作,其格式为;
      TITLE   text
TITLE 伪操作可指定每一页上打印的标题。同时,如果程序中没有使用NAME伪操作.则程序将用text中的前六个字符作为模块名。text最多可有60个字符。如果程序中既无NAME又无TITLE伪操作,则将用源文件名作为模块名。所以NAME及TILLE伪操作并不是必要的,
表示源程序结束的伪操作的格式为:
end label
其中标号指示程序开始执行的起始地址。如果多个程序模块相连接,则只有主程序要使用标号,其它子程序模块则只用END而不必指定标号。

六。对准伪操作
1.使下一个字节地址成为偶数。一个字的地址最好从偶地址开始,所以对于字数组为保证其从偶地址开始,
可以在它前面用EVEN伪操作来达到这一目的。
2.ORG  Constant expression
如常数表达式的值为n,则ORG伪操作可以使下一个字节的地址成为常数表达式的值n。例 :
vectors segment
        org 10
vect1   dw  47a5h
        org  20
vect2 dw 0c596h
...
vectors  ends
则VECT1的偏移地址值为0AH,而VECT2的偏移地址值为14H。
    在汇编程序对源程序汇编的过程中,使用地址计数器来保存当前正在汇编的指令的地址。地址计数器的值可用$来表示,汇编语言允许用户直接用$来引用地址计数器的值,因此
ORG  $+8
可以表示跳过8个字节的存储区。   
七、基数控制伪操作
汇编程序默认的是十进制数,为此,当使用其他基数表示的常数时,需要专门给以标记如下:
二进制:后面跟字母B
十进制:默认,后面也可以跟字母D
十六进制:后面跟字母H,如果第一个字母是A-F时,应在其前面加上数字0
八进制:后面跟O或Q。
·RADIX伪操作,可以把默认的基数改变为2 – 16范围内的任何基数。格式如下:
   ·RADIX  expression
字符串可以看成串常数,可以用单引号或双引号把字符串放在其中,得到的是字符串的ASC码值,例如‘ABCD’。 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息