微机原理与接口技术(四)

1.汇编语言源程序与汇编程序

  • 汇编语言源程序→用助记符编写
  • 汇编程序→源程序的编译程序

汇编语言源程序→汇编程序→机器语言目标程序

汇编语言设计与执行过程

  • 输入汇编语言源程序(EDIT)→源文件.ASM

  • 汇编(MASM)→目标文件.OBJ

  • 链接(LINK)→可执行文件.EXE

  • 调试(TD)→最终程序

2.汇编语言语句类型和格式

汇编语言语句类型:

  • 指令性语句→CPU执行的语句,能够生成目标代码
  • 指示性语句→CPU不执行,而由汇编程序执行的语句,不生成目标代码

汇编语言语句格式:

  • 指令性语句:

    [标号:] [前缀] 注记符 [操作数], [操作数] [;注释]

  • 指示性语句:

    [名字] 伪指令注记符 操作数 [, 操作数, …] [;注释]

3.汇编语言语句中的操作数

  • 寄存器、存储单元、常量、变量或标号、表达式

常量

  • 数字常量→0F00H (十六进制开头不能为字母需加0)、64H

  • 字符串常量→用单引号引起的字符或字符串

  • 例:

    • MOV AL,‘A’ → AL=41H
  • 例:

    • 定义字符串:‘ABCD’ → 汇编时被编译成对应的ASCII码:41H,42H,43H,44H

变量

  • 内存单元的符号地址,为存储器操作数

  • 变量的属性:

    段值——变量所在段的段地址

    偏移量——变量所指单元的偏移地址

    类型——字节型、字型和双字型

表达式

  • 算数运算、逻辑运算、关系运算符、*取值运算和属性运算、其他运算

    ①取值运算符

    • 用于分析存储器操作数的属性

      • 获取变量的属性值

        OFFSET → 取得其后变量或标号的偏移地址

        SEG → 取得其后变量或标号的段地址

        1
        2
        3
        MOV AX, SEG DATA
        MOV DS, AX ;取变量的段地址并送给DS
        MOV BX, OFFSET DATA ;取变量的偏移地址送给BX 等价于 LEA BX, DATA

        ②属性运算符

    • 用于指定其后存储器操作数的类型

    • 运算符:PTR

    • 例:

      • MOV BYTR PTR[BX]. 12H ;PTR指定存储器操作数[BX]为”字节型“

伪指令

  • 由汇编程序执行的”指令系统“

  • 作用:

    • 定义变量
    • 分配存储区
    • 定义逻辑段
    • 指示程序开始和结束
    • 定义过程等
  • 帮助计算机理解注记符指令编写的汇编语言源程序

  • 常用伪指令:

    数据定义伪指令、符号定义伪指令、段定义伪指令、结束伪指令、过程定义伪指令、宏命令伪指令

一、数据定义伪指令

  • 用于定义数据区中变量的类型及其所占内存空间大小

  • 格式:

    [变量名] 伪指令助记符 操作数, … ; [注释]

    • 伪指令注记符:定义变量类型
    • 操作数:变量值可以是常数,表达式或字符串。其大小不能超过伪指令注记符所限定的范围
    • 变量名:符号地址
  • 变量的类型及其操作数的个数决定了该变量所在内存空间的大小

1.数据定义伪指令注记符

  • DB (Define Byte):定义变量为字节型,指向的每一个操作数占1个字节单元
  • DW (Define Word):定义的变量为字类型,指向的每一个操作数占1个字单元(2个字节单元)
  • DD (Define Double Word):定义的变量为双字型,占4个字节单元
  • DQ (Define Quadword):定义的变量为4字型
  • DT (Define Tenbytes):定义的变量为10字节型

数据定义伪指令例

  • DATA1 DB 11H, 22H, 33H, 44H
  • DATA2 DW 11H, 22H, 3344H
  • DATA3 DD 11H*2, 22H,334455566H

见图65

65

数据定义伪指令的几点说明

  • 数据定义伪指令决定所定义变量的类型
  • 定义字符串必须用DB伪指令
  • 例:
    • DATA1 DB ‘ABCD’, 66H

2.重复操作数

  • 当同样的操作数重复多次时,可以使用重复操作符

  • 作用:

    • 为一个数据区的各个单元设置相同的初值
  • 格式:

    [变量名] 伪指令注记符 n DUP (初值[, 初值, …])

  • 例:

    • M1 DB 10 DUP (0)
  • 常用于声明一个数据区

3.”?“的作用

  • 表示随机值,用于预留存储空间
  • 例:
    • MEM1 DB 34H, ‘A’, ? ;随机数占一个字节单元
    • DW 20 DUP (?) ;预留40个字节单元,每单元为随机值

数据定义伪指令例

  • M1 DB ‘How are you?’
  • M2 DW 3 DUP(11H), 3344H
  • ​ DB 4 DUP (?)
  • M3 DB 3 DUP (22H, 11H, ?)

见图66

66

二、符号定义伪指令

  • 将表达式的值赋给一个名字。当源程序中需多次引用某一表达式时,可以利用EQU伪命令,用一个符号代替表达式,以便于程序维护。

  • 格式:

    • 符号名 EQU 表达式
  • 操作:

    • 用符号名取代后边的表达式,不可重新定义
  • 例:

    • CONSTANT EQU 100
  • EQU说明的表达式不占用内存空间

三、段定义伪指令

  • 在汇编语言源程序中定义逻辑段

    • 说明逻辑段的骑士和结束
    • 说明不同程序模块中同类逻辑段之间的联系形态
  • 格式:

    段名 SEGMENT [定位类型] [组合类型] [‘类别’]

    ​ …

    段名 ENDS

    • 段名代表逻辑段的段基地址
    • 定位类型说明逻辑段的起点
    • 组合类型为装入内存时各逻辑段的组合方式
    • 类别为链接时不同程序模块中的同类逻辑段将被装入连续存储区

段定义伪指令例

1
2
3
4
5
DATA SEGMENT
MEM1 DB 11H, 22H ;MEM1变量在逻辑段中的位置就代表了他的偏移地址
MEM2 DB 'Hello!'
MEM2 DW 2 DUP (?) ;DW表示变量的类型
DATA ENDS ;DATA段名也代表逻辑段的段地址

四、设定段寄存器伪指令

  • 说明所定义逻辑段的性质
  • 格式:
    • ASSUME 段寄存器名:段名[, 段寄存器名:段名, …]

五、结束伪指令

  • 表示源程序结束
  • 格式:
    • END [标号]

汇编语言源程序结构

见图67

67

一个完整源程序结构例

见图68

68

过程定义伪指令

  • 用于定义一个过程体

  • 格式:

    过程名 PROC [NEAR/FAR]

    ​ …

    ​ RET

    过程名 ENDP

  • 过程体的最后一条指令必须是RET

过程定义及调用例

  • 定义延时子程序

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    DELAY PROC
    PUSH BX
    PUSH CX
    MOV BL, 2
    NEXT: MOV CX, 4167
    W10M: LOOP W10M
    DEC BL
    JNZ NEXT
    POP CX
    POP BX
    RET
    DELAY ENDP
  • 调用延时子程序:CALL DELAY

宏命令伪指令

  • 宏:

    • 源程序中由汇编程序识别的具有独立功能的一段程序代码
  • 当源程序中需要多次使用同一个程序段时,可以将该程序段定义为一个宏

  • 格式:

    宏命令名 MACRO <形式参数>

    ​ …

    ​ …

    ​ ENDM

  • 通过参数传递方式引用宏

宏定义与宏调用例

  • 定义宏

    1
    2
    3
    4
    5
    DADD MACRO X, Y, Z
    MOV AX, X
    ADD AX, Y
    MOV Z,AX
    ENDM
  • 宏调用

    • DADD DATA1, DATA2, SUM
  • 汇编后源程序中的宏展开

    • MOV AX, DATA1
    • ADD AX, DATA2
    • MOV SUM, AX

调整偏移量伪指令

  • 规定程序或变量在逻辑段中的起始地址

    默认情况下,程序或变量在逻辑段中的起始偏移地址为:0

    利用ORG指令,可以改变程序或变量的起始偏移地址

  • 格式:

    • ORG 表达式
    • 表达式为非负常数
  • 例:

    1
    2
    3
    4
    DATA SEGMENT
    ORG 1200H
    BUFF DB 1,2 ;变量BUFF的偏移地址为1200H
    DATA ENDS

    系统功能调用

  • BIOS

    • 主流在ROM中的基本输入/输出系统
      • 家电自检,装入引导,主要I/O设备处理程序及接口控制
  • DOS

    • 磁盘操作系统

DOS功能/BIOS功能调用是调用系统内核子程序

DOS功能与BIOS功能均通过中断方式调用,称为BIOS中断和DOS中断

DOS软中断

  • DOS中断包括:设备管理,目录管理,文件管理,其他用中断类型码区分

  • DOS软中断:类型码为21H

  • 关于DOS软中断说明

    • 包含多个子宫内的功能包
    • 各子功能用功能号区分
    • 用软中断指令调用,中断类型码固定为21H

DOS功能调用的基本步骤

  • 将调用参数装入指定的寄存器(入口参数/出口参数)

  • 将功能号装入AH

  • 按中断类型号调用DOS中断

  • 检查返回参数是否正确

  • 调用格式:

    MOV AH, 功能号

    <置相应参数>

    INT 21H

1.单字符输入
  • 调用方法:

    MOV AH, 01

    INT 21H

  • 输入的字符在AL中

  • 单字符输入例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    GET KEY: MOV AH, 1
    INT 21H
    CMP AL, 'Y'
    JZ YES
    CMP AL, 'N'
    JZ NO
    JMP GET KEY
    YES: ...
    NO: ...
2.字符串输入
  • 接收由键盘输入一串字符

  • 输入的字符串存储在内存指导区域中→字符输入缓冲区

  • 用户自定义缓冲区格式

    见图69

    69

  • 字符串输入功能号

    • 10
  • 缓存区须定义在数据段

  • 方法:

    AH ;功能号

    DS: DX ;字符串在内存中的存放地址

    INT 21H

  • 输入字符串程序段

    1
    2
    3
    4
    5
    DAT1 DB 20, ?, 20 DUP (?)         ;在数据段中定义
    ...
    LEA DX, DAT1
    MOV AH, 0AH
    INT 21H
  • 输入缓冲区

    见图70

    70

3.单字符显示输出
  • AH ;功能号2

    DL ;待输出字符

    INT 21H

  • 1
    2
    3
    MOV AH, 2
    MOV DL, 41H
    INT 21H ;执行结果:屏幕显示A
    4.字符串输出显示
  • AH ;功能号09H

    DS: DX ;待输出字符串的偏移地址

    INT 21H

  • 注意点:

    • 被显示的字符串必须以‘$’结束
    • 所显示的内容不应出现非可见的ASCII码
    • 若考虑输出格式需要,在定义字符串后,加上回车符和换行符
  • 字符串输出显示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    DATA SEGMENT
    MESS1 DB 'Input String:', 0DH, 0AH,'$'
    DATA ENDS
    CODE SEGMENT
    ...
    MOV AH, 09
    MOV DX, OFFSET MESS1
    INT 21H
    ...
    5.返回操作系统(DOS)功能
  • 功能号:

    • 4CH
  • 调用格式

    • MOV AH, 4CH
    • INT 21H
  • 功能:

    • 程序执行完该2条语句后能正常返回DOS
    • 常位于程序结尾处

DOS功能调用小结

  • 通过中断指令调用。一个中断类型码对应1个功能程序包
  • 每个程序包中的子功能通过功能号区分,调用时功能号须送AH
  • 注意不同子功能的入口/出口参数要求
  • DOS和BOIS中断均可能影响AX

汇编程序设计示例

见图71

71

见图72

72

见图73

73

见图74

74

见图75

75

见图76

76

汇编程序设计小结

  • 汇编语言程序设计一般步骤

    • 根据实际问题抽象出数学模型
    • 确定算法
    • 画程序流程图
    • 分配内存工作单元和寄存器
    • 程序编码
    • 调试
  • 内容提要

    • 汇编语言源程序的结构
    • 汇编语言语句→变量、表达式中的运算符
    • 伪指令
    • DOS功能调用
      • 5个子功能的应用
    • 简单汇编语言源程序的设计
  • 注意点

    • 变量的定义与应用
      • 明确所定义变量在内存中的分布
    • 存储区的定义
      • 定义没有变量的存储区没有意义
    • 完整的汇编语言源程序结构
      • 定义逻辑段,说明段的含义,初始化段寄存器
    • 伪指令
      • 数据定义方式
    • 字符及字符串的输入和显示输出
      • 字符输入缓冲区的定义,输出字符串的定义
    • 汇编语言程序结构
      • 顺序结构
      • 循环结构
        • 使用LOOP指令或条件转移指令实现
      • 分支结构
        • 一般用条件转移指令实现
      • 子程序结构

见图77

77

见图78

78