microcomputer_principle_10_汇编程序设计示例
Carpe Tu Black Whistle

汇编语言程序设计

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

内容提要

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

Notes

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

  • 汇编语言程序结构:
    • 顺序结构
    • 循环结构
      • 使用LOOP或条件转移指令实现
    • 分支结构
      • 一般用条件转移指令实现
    • 子程序结构(call 调用)

e.g.

  1. 定义20B的字符输入缓冲区BUFF以及20B的字节变量DATA;
  2. 显示字符串输入提示信息,然后从键盘接收字符‘Hello, my friends!’;
  3. 将BUFF中的字符串按从左到右的方向传送到DATA中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
DSEG SEGMENT
MESS DB 'Please input string:', 0DH, 0AH, '$'
BUFF DB 20, ?, 20 DUP(?)
DATA DB 20 DUP(?)
DSEG ENDS

CSEG SEGMENT
ASSUME CS:CSEG, DS:DSEG, ES:DSEG

START: MOV AX, DSEG
MOV DS, AX
MOV ES, AX
AGAIN: LEA DX, MESS
MOV AH, 9
INT 21H

LEA DX, BUFF
MOV AH, 10(0AH)
INT 21 ; 以上3步实现实现输入
XOR CX, CX ; 清零
MOV CL, BUFF+1 ; BUFF+1-> N2 存储了实际长度值
; 串传送指令 BUFF -> DATA
; 串操作,要求串长度-> CX
LEA DI, DATA
LEA SI, BUFF+2
CLD
REP MOVSB
MOV AH, 4CH
INT 21H
CSEG ENDS
END START

示例讲解

example 1

1
2
3
4
DATA SEGMENT
NAMES DB 'TOM..', 20 ; 每个字符在内存中以ASCII码表示,占用1B
DB 'CATE', 25 ; 20和25为十进制数表示形式
DATA ENDS

以上数据区在内存中是如何存储的?

image

example 2

阅读程序段,说明该程序段的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
DATA SEGMENT
A DB '123ABC' ; 定义了数据段区
DATA ENDS

CODE SEGMENT
ASSUME CS: CODE, DS: DATA

START: MOV AX, DATA ; 除了代码段之外,其它的代码段,段寄存器初始化必须要有
MOV DS, AX ; 源代码首两句指令,初始化数据段基地址
LEA BX, A
MOV CX, 6
LP: MOV AH, 2 ;AH=2,输出单字符
MOV AL, [BX]
XCHG AL, DL
INC BX
INT 21H ;核心语句,看到21H去找AH寄存器
LOOP LP
MOV AH, 4CH
INT 21H
CODE ENDS
END START

example 3

1
2
3
4
5
6
7
8
9
10
11
12
DATA SEGMENT
TABLE DW 3400H, 5600H, 2300H, 4500H, 2300H, 1200H, 2344H, 3500H
DATA ENDS

CODE SEGMENT
ASSUME CS: CODE, DS: DATA

START: MOV AX, DATA
MOV DS, AX
MOV BX, OFFSET TABLE
MOV SI, 06H
A: JMP DWORD PTR[BX+SI+2] ; 核心语句

程序执行完标号为A的指令后: CS=(1200H) IP=(2300H)

低地址单元是IP
高地址单元为CS

example 4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
DATA SEGMENT
STR1 DB 'HELLO WORLD!'
STR2 DB 'HELLO WOOLD!'
COUNT DB 12 ; [COUNT] = 0CH
FLAG DB ?
DATA ENDS

CODE SEGMENT
ASSUME CS: CODE, DS: DATA, ES: DATA ; DATA即是数据段,又是附加段
; 这是运用串操作时,经常定义的方式

START: MOV AX, DATA
MOV DS, AX ; 代码的前三段主要用于初始化DS,ES
MOV ES, AX
LEA BX, FLAG
LEA SI, STR1
LEA DI, STR2
MOV CX, COUNT
CLD ; 设置方向
REPE CMPSB ; 核心指令
JZ NEXT1
MOV BYTE PTR[BX], 00H
JMP STOP
NEXT1: MOV BYTE PTR[BX], 0FFH
STOP: ...

当程序执行到STOP时:
SI = (9)
DI = (15H) 21
CX = (3)
FLAG = (0)
ZF = (1)

image

example 5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
DATA SEGMENT
SUM DB 8 DUP(0)
DATA ENDS

CODE SEGMENT
ASSUME CS:CODE, DS:DATA

START: MOV AX, DATA
MOV DS, AX
LEA BX, SUM
MOV DX, 380H
IN AL, DX ; 读入380H端口数值
MOV CX, 8
NEXT: ROR AL, 1 ; 核心指令,不含CF循环右移
JNC NEXT1 ; CF=0跳转
MOV BYTE PTR[BX], 0FFH
JMP NEXT2
NEXT1: MOV BYTE PTR[BX], 0
NEXT2: INC BX
LOOP NEXT

如果从380H端口输入的是45H,则程序执行完后:
BX=(8)
AL=(45H)=(0100 0101B) 16进制转2进制不要搞错
SUM0–SUM7的内容为:
(FF,0,FF,0,0,0,FF,0)