汇编程序的组成

时间:2022-07-25 01:00:29

汇编程序的组成

本章节介绍:

• 语句

• 标示符

• 保留字

• 注释的应用

• 操作数

• 表达式

  数值表达式

  地址表达式

  返回值操作符

  属性操作符

数据的定义

标号与变量的属性

伪指令

a.存储模型说明伪指令.MODEL

b.段伪指令SEGMENT和结束伪指令ENDS

c.过程开始伪指令 PROC和结束伪指令ENDP

d.段使用设定语句伪指令Assume

e.整个程序结束伪指令END

f.简化段伪指令

g.等值伪指令EQU

h.ORG伪指令

一个完整的源程序的组织

 

语句

汇编程序由语句组成

•  汇编语言语句的通用格式:

 

    [标示符]  操作符 [操作数][;注释]

 

       表示符, 操作符, 操作数被至少一个空格或者制表符分开。

• 语句的两种类型:

 

1) 指令,被汇编器转换成机器代码;

     [标号:] 操作符 [操作数] [;注释]

 

2) 伪指令 ,只告诉汇编器要执行的具体行动,不产生机器代码

  [名称/变量] 指令 [表达式/参数 ] [;注释]

[标示符] 操作符[操作数] [;注释]

 

语句的两个例子:

[标号:] 操作符[操作数] [;注释]

     L1:     MOV  AX, 0   ;把 0 移到 AX

 

[名称/变量] 指令[参数][;注释]

counter      DB   1           ;定义字节的值 1

 

标示符

标示符的两种类型:

1. 标号  指令,过程,段的地址

      例如:  下面语句中的Main

       Main:    PROC FAR

 

2. 名称/变量    数据单元的地址

        例如:下面语句中的Counter      

          Counter   DB    0

 

•  标示符 可以使用一下字符:

字母:   A~Z, a~z ;   (不区分大小写)

数字:   0~9   (不能作为第一位) ;

特殊字符:   ?  _ $  .  @

•  标示符的第一个字母必须是字母或者专用字符,但专用字符的“.”除外。

 

• 不能用保留字作为标示符。

 

• 标示符最大长度为31个字符。

 

保留字

汇编语言里的某些名字是为它们固有的用途而保留的,只再特殊情况下使用。

 

种类:

• 指令,如MOV和ADD,是计算机可执行的操作;

• 伪指令, 像END或SEGMENT,是为汇编程序提供信息。

• 操作符, 如FAR和SIZE,可以在表达式中使用。

• 预定义符号, 如@DATA 和 @Model, 它们在汇编期间向程序返回信息。

•  

        

程序注释

遍及整个程序的注释的使用可以改善程序的清晰度。

• 注释用一个分号(;)开始.

 

汇编程序假定在一行中所有在它右边的字符都是注释

注释可以包含任意可打印字符,包括空格在内。

 

例子:

         ADD AX, BX   ; 累计

注释不会产生机器码,因此它不会影响汇编程序的大小和运行。

 

操作数

• 操作数提供操作要用的信息。

 

• 有些指令无需操作数,有些却又一个或者两个操作数。

 

• 对于指令来说,操作数的地址包含在操作数项中。

 

• 操作数项由常量,寄存器,标号,名称/变量或者表达式(一个或多个)组成

 

表达式

表达式分为值表达式和地址表达式。

值表达式中的值是可以在汇编过程中被汇编器计算的。

数值表达式

1) 常量

2) 算术表达式

3) 关系表达式

4) 逻辑表达式

5) 值表达式中其他操作符

6) 操作的优先级(从高至低)

 

1)常量

    十进制常量: 12D,12

    十六进制常量: 0FAH

    二进制常量:  00000001B

    字符串常量:

      是用单引号或者双引号括起来的一个或者多个字符,

      它的值是字符的ASCII码值。

2) 算术表达式

   算术表达式包括 +,-,*, /, MOD (除后的余数).

   例如:

   ADD  AX, 100H /3*2-1

地址表达式

地址表达式表示的内存中存放操作数的地址

 标号, 名字/变量(立即地址), [BX], [SI] ,[DI]都是特殊的地址表达式。

             地址 ±值=地址

例子:

 SUN+1 =SUN下一位的地址

 注意:并非SUN的内容加1;

 

3.值–返回操作符

    有    TYPE, LENGTH, SIZE, OFFSET, SEG.

1)TYPE—返回 变量或者标号的属性类型的值

  格式:      TYPE  变量   或者标号

  字节变量                        属性类型的值1

  字变量                                  2

  双字变量                                4

  近标号                                 -1                 

  远标号                                 -2

 

TYPE   变量 或者 标号

; 返回变量或者标号属性类型的值

 

SEG   变量 或者 标号

;返回变量或者标号所在的段的段地址

OFFSET   变量 或者 标号

;返回变量或者标号的偏移地址

 

4.   属性操作符

1) PTR—指定或者更改变量或者标号的类型。

 

 格式:    类型    PTR  地址表达式

 

 注意:  PTR不分配内存空间。

 

例子:  

 MOV  [SI], 1                            ;出错

 MOV  BYTE PTR [SI], 1       ;指定字节类型

 MOV  WORD PTR [SI], 1     ;指定字类型

 

 

数据定义

EXE程序中的数据段

是用来为定义常量,工作区,输入/输出区和未定义值的。

 

•         数据定义的格式:

[变量] Dn  表达式1[,表达式2,…] [; 注释]

 

   数据项的名字是唯一的,也是具有描述性的。

 

• Flag  DB   ? 

;这个表达式定义一个没初始化的值,但它必须符合定义的大小

 

•一个表达式可以 包含多个被逗号“,”隔开的常量,只被行的长度所限制。

如下所示:

• Flag   DB  21, 22, 23, 24, 25, …
 汇编器把这些常量定义在相邻的字节

     MOV   AL, Flag+3        ; 24(18H) 放进AL

 

重复操作符    DUP

[名称/变量]  Dn重复计数DUP(表达式)…

 

例子:

 Buffer1  DB   5,0, 5 DUP(?)                 ;7 字节

 Buffer2  DW  25DUP(‘ab’)                ;25*2 字节

 Buffer3  DW  1,5DUP(1,2,4 DUP(0))  ;62 字节

 

表达式可以定义 并初始化一个字符串或一个数字常量

 

字符串

例子:

DBSams CD ;单引号

DB ‘Sam”s CD’   ;双引号

 

• 汇编器把字符串当成是普通的ASCII码进行存储

 

 

·在MASM中, DB (字节 )是定义2个以上字符的字符串的仅有格式,这些字符以左相邻的方式并按照正常的从左到右的顺序存放

 

                                                                          34

例子:                                                      32       L1

MESS  DB  ‘OK’                     A  41

FLAG  DW ‘Ab’                      b  62     FLAG

L1        DB   ’24’ ;代表着十六进制 3234    K 4B

                                        O 4F     MESS

标号和变量的属性

• 变量和标号都存储单元的偏移地址

• 变量指示的存储单元中存放数值;

• 标号指示的存储单元中存放的是机器指令的代码。

•          

• 标号是语句的一部分,用在指令前表示对应语句的地址,标号后一定要加冒号(:)

 

标号指示着指令代码所在的第一个内存单元的偏移地址

 

变量(名称)指示着数据项所在的第一个内存单元的偏移地址

 

• 3  标号和变量的属性:

1) 段值

      标号和变量指示的内存单元 所在的段地址

2) 偏移

      标号和变量指示的 起始内存单元地址 段内偏移地址。

3) 类型

   标号的类型主要分为近(段内)和远(段间),属性值分别是-1和-2。

   变量的主要类型有字节,字,双字

伪指令

• 只在汇编过程中起作用,并且不产生机器可执行的代码。

 

• 功能:

   定义数据, 分配内存单元,指出程序的结束,等等。

 

变量定义伪指令

表3-1 各种数据定义伪指令

 

描述                   伪指令           意义          类型属性值

                                                                             

Byte                   DB                 byte             1

Word                    DW                word              2

Double word             DD                 Dword             4

Far word                DF                F word             6

Quad word               DQ                Qword              8

Ten bytes               DT                Tbyte             10

 

段伪指令

PROC 伪指令

•  代码段由一个或者多个过程组成,

•  过程必须完全包含在段中。

 

• 格式

过程名  PROC  Attribute ;第一切入点

                              …          ;执行的指令

过程名  ENDP                    ;过程结束

 

• 过程名必须存在,必须是唯一的,而且必须遵循汇编语言的命名惯例。

• 属性是NEAR(默认) 或者 FAR.

 

• 在同一段中被调用的过程就是近过程,可以通过 偏移地址 来访问。

 

•在段外的被调用的过程就是远过程,可以通过  段地址:偏移地址  来访问。

 

段使用设定语句   
Assume  伪指令

为有效的产生目标代码,

汇编程序要了解各程序段与段寄存器之间的对应关系

 

•段寄存器与程序段的对应关系 由  段使用设定语句说明。

 

•通过Assume伪指令 设定的段名与段寄存器CS,DS和SS之间的对应关系。

 

段使用设定语句的简单格式:

ASSUME   段寄存器名:段名[,段寄存器名:段名…]

  操作符      操作数

   Assume    SS:堆栈名, DS:数据名,CS:代码段

 

例如,  ASSUME   CS:CSEG, DS:DSEG

告诉汇编程序:CS寄存器对应CSEG段,DS寄存器对应DSEG段。

段使用设定语句是伪指令语句,

它不能设置段寄存器的值,

即段寄存器还没有指向对应的段。

 

所以在程序中

还需要用指令语句

来给数据段寄存器和附加段寄存器 赋值。

• 如果你的程序没有用到ES寄存器,

• 则可以省略对ES的说明

• 或者编码为ES:NOTHING

 

• 操作数可以以任何顺序出现。

• 你可以用ASSUME来更改相关的段和段寄存器。

 

Example:

ASSUME  CS:CSEG,DS:DSEG1, ES:DSEG2

            …                                    ;一些指令

ASSUME  CS:CSEG,DS:DSEG2, ES:DSEG1

 

源程序结束语句
   End 伪指令

源程序结束语句的一般格式:   

 

  操作符        操作数

    END          [标号]

    END          [proc-name]

• 在大多数程序中,

• 操作数包含的第一个过程名,

• 或   PROC指定为FAR的过程名,

• 程序要从这里开始执行。

 

• ENDS伪指令结束一个段,

• ENDP伪指令则结束一个过程,

• END则是结束整个程序。

 

结束程序运行的指令

• INT 21H是一种常见的DOS中断指令,

• 用AH寄存器中的功能码,来指定要执行的动作。 

 

INT  21H中断指令,

若AH寄存器中的功能码是4CH时,

则CPU执行完DOS中断指令INT 21H,

就结束程序的执行,

返回DOS操作系统了。

 

 

 我们还可以使用此操作,在AL中返回代码。正常的程序完成后的返回代码,通常是0(零)。

•INT 21H的功能码4CH已经取代了INT 20H的运作,INT 21H的功能码00H最初是用来结束处理过程的。

简化的段伪指令

为了使用简化的段伪指令,在定义任何段之前,必须初始化存储模型。

 

 存储模型说明伪指令 格式:

 . MODEL       存储模型

 

该伪指令以符号点“.”引导

.MODEL 伪指令自动定义所需的ASSUME 语句

 

•为了说明采用SMALL存储模型,只要在源程序首使用如下伪指令:

• .MODEL   SMALL

 

. STACK  [大小]   ;默认大小是1024byte

. DATA

. CODE  [名称]

 

• 一个简化段开始,意味着上一个段的结束。

 

• 伪指令END表明最后一个段(整个代码段程序)的结束。

等值伪指令EQU

格式:

     表达式名      EQU   表达式

 

• EQU伪指令定义一个值,在其他的指令中,汇编器可以用来代替。

• EQU是简单的替换,在生成的对象的程序上,它不需要额外的存储空间。

• 表达式可以是常量,值表达式,字符串,关键词,操作符。

• 不允许重新定义一个表达式的名称。

 

• 表达式中通常不允许向前引用表达式的名称。

 

例子:   

COUNT  EQU  100                 

;汇编器把DB  COUNT  DUP ? 转为 DB 100 DUP ?

DATA     EQU  COUNT+2  

;汇编器用COUNT+2的地址来替换DATA

HELLO   EQU   ‘How are you’

;汇编器用来字符串‘How are you’替换 HELLO

MOVE           EQU   MOV

COUNTER    EQU   CX

MOVE  AX, CX                 ;MOV  AX, CX

MOV    COUNTER, 100          ;MOV CX,100

 

 

ORG 伪指令

格式:  ORG  表达式

 

• 可以用ORG 伪指令来改变内存单元地址计数器的内容。

• 表达式必须从一个2字节的绝对值数(不能是象征性的名称)开始,而且是当前指令的一个字节的内存单元地址

• ORG /伪指令包含一个美元符号($)是指一个操作数的内存单元地址计数器的当前值/在当前指令的第一个字节的位置 。

例1:      

          ORG 100H

BEGIN  MOV AX,1234H      ; BEGIN 的偏移地址是100H

          

         ORG $+8 ; 在内存中跳8个字节

         JMP $+6 

;在当前指令的第一个内存单元之后,跳到第六个字节

;$+6另一条指令的开始的内存单元