跳转至

汇编语言程序格式

逻辑段

  • 汇编语言源程序由一个或多个逻辑段组成
    • 一个程序中可以有几个同一类型的逻辑段
    • 必须至少有一个代码段

[!注] 源程序分段的目的在于程序结构清晰、便于内存分配,寻址方便,一个源程序需要设置几个段应该根据具体问题来定 - 逻辑段: - 程序段 - 主要由指令语句组成,完成源程序的功能 - 数据段 - 定义数据及符号的伪指令组成 - 附加段 - 定义数据及符号的伪指令组成 - 堆栈段 - 定义堆栈伪指令组成 - 段定义伪操作:

段名 segment
....                 ;语句序列
段名 ends
- 如果不指定,则采用默认参数 - 段名对外表现为立即数,为该段的的地址 - 语句格式:

常数和表达式

  • 常数:表示一个固定的值
    • 十进制常数:d或缺省
    • 十六进制:h
    • 二进制:b
    • 八进制:q
    • 字符串常数:ASCII码
    • 符号常数:
      • 等价EQU伪指令:
        • 符号名 EQU 数值表达式
        • 符号名 EQU 字符串
      • 等号=伪指令
        • 符号名=数值
      • 二者的区别:后者可使用多次,前者只能使用一次
  • 数值表达式:使用常数、符号常数和算数、逻辑、关系运算符组成的表达式\((75*2+X)/Y\)
  • 表达式:
    • 汇编程序在汇编过程中计算表达式,最终得到一个数值
      • 一个常数或一个地址
    • 程序运行之前,就已经计算出了表达式
      • 因此,程序的运行速度没有变慢,并且增加了程序的可读性

变量和标号

  • 变量
    • 数据单元的符号地址
    • 书写格式:不能使用系统保留字、不能以数字开头
    • 变量的定义:用[[汇编语言程序格式#^2eea09|数据定义伪指令]]来定义
  • 标号
    • 一个指令单元的符号地址
    • 书写格式:不能使用系统保留字、不能以数字开头
    • 定义:在一条指令语句前输入标号且用:隔开
  • 变量定义伪指令: ^2eea09
    • 格式:变量 DB/DW/DD/DF/DQ/DT 操作数1,....,操作数n
    • 功能:
      • 定义变量
      • 在内存中分配一组存储单元
      • 对单元进行初始化
    • 分类:
  • 操作数:
    • 一组常数数值表达式
      • DATA DB 2, 100*2-5,0,-1
    • 一组字符串
      • STRING DB 'This is a string'
    • 变量名或标号名
      • ADDR1 DW BLOCK :将BLOCK的偏址放在ADDR1单元
      • ADDR2 DD BLOCK:将BLOCK的偏址和段地址放在ADDR2四字节单元中
    • ?
      • 只分配空间,但不进行初始化,其中的值为随机值
    • 重复DUP语句
      • 格式:重复数 n dup (重复内容)
      • 功能:重复
      • 例:BLOCK DB 3 DUP (0,1,-1)

起始地址和对准语句

  • ORG
    • 格式:ORG 表达式
    • 功能:置顶随后指令或定义数据的偏移地址
    • 说明:
      • 可以设置程序段、数据段的任何位置
      • 若没有进行设置,默认的逻辑起始地址为0000H
  • EVEN
    • 格式:EVEN
    • 偶地址对齐指令,若当前地址是奇数,则+1
  • ALIGN
    • 格式:ALIGN n
    • 功能:使随后的数据或指令起始于n(2,4,8)的倍数地址

地址计数器$

汇编器在将原地址转化为目标程序过程中,需要使用地址计数器跟踪其中代码或数据的偏移地址 - $表示当前的偏移地址 - $在程序中的不同位置其值是不同的

地址表达式

  • 地址表达式的组成:变量、标号、+、-
  • 地址表达式可以相减、而不能相加,相减表示两个地址之间的距离
  • 含有变量的地址表达式其类型与该变量保持一致

变量和标号的属性

  • 变量的属性:
    • 段属性:变量的段地址
    • 偏移属性:变量的偏移地址
    • 类型属性:变量所指单元的类型(字节、字、双字等)
  • 标号的属性:
    • 段属性:定义标号所在段的段地址
    • 偏移属性:定义标号处到段地址的距离
    • 类型属性:NEAR(段内)和FAR(段间)

地址操作符

  • SEG
    • 格式:SEG 变量或标号
    • 功能:得到操作数所在的段的段首地址
    • MOV AX, SEG ARR
  • OFFSET
    • 格式:OFFSET 变量或标号
    • 功能:得到操作数所在的偏移地址
    • MOV AX, OFFSET BUF

类型操作符

  • 功能:指定类型

汇编程序编写

stack segment stack
    dw 512 dup(?)
stack ends
data segment
    ...        ;在数据段定义数据
data ends
code segment
    assume cs:code, ds:data, ss:stack
start:
    mov ax, data
    mov ds, ax
    ...         ;在代码段填入指令序列
    mov ah, 4c00h
    int 21h
    ...         ;子程序代码
code ends
    end start

段类型说明伪操作

  • 在代码段开始必须用ASSUME伪操作声明段和寄存器之间的关系:ASSUME 段寄存器:段名[,段寄存器:段名,...]
  • 通知MASM,建立段寄存器与段的缺省关系

    实际上,数据段之所以称为数据段,是由于DS指向它。 由于程序运行时可以改变DS的值,使任何段都可以称为数据段

  • ASSUME语句必须位于程序段开始的位置