欢迎光临散文网 会员登陆 & 注册

第七周 汇编语言程序设计

2021-05-10 19:06 作者:康康Loong  | 我要投稿

大家好,又是我,沉迷学习无法自拔的小笨蛋康sir。

这个文集(点我)将会同步更新我观看吴宁老师的《微机原理与接口技术》教学视频写的笔记,学习笔记,大概每周一章。

有问题大家可以在评论下面留言讨论,欢迎纠错!

欢迎收藏阅读,动动小手给个硬币点个赞

                                                                ——@正能量的康sir

也可移步我的博客(https://blog.csdn.net/qq_33956508)会更新一些其它技术类文章。

第35讲 汇编语言源程序

主要内容

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

汇编语言语句类型与格式

汇编语言语句中的操作数


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

汇编语言源程序——用助记符编写

汇编程序——源程序的编译程序


汇编语言源程序——>汇编程序——>机器语言目标程序


汇编语言程序设计与执行过程

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

汇编(MASM)----目标文件.OBJ

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

调试(TD)-----最终程序


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

汇编语言语句类型:

指令性语句->CPU执行的语句,能够生成目标代码

指示性语句->CPU不执行,而由汇编程序执行的语句,不生成目标代码


汇编语言语句格式:

指令性语句格式:

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

(助记符就是操作码,不可缺少,[ ]中是可以没有的)

(标号Label是指令的符号地址,标号后要有冒号)


指示性语句格式:

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

(指示性语句中至少有一个操作数)

(名字,变量的符号地址,后面不加冒号)


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

寄存器

存储器单元

常量

变量或标号

表达式


常量:

数字常量,1234…

字符常量,用单引号引起的字符或字符串,’A’ ’a’ ’ABCD’

MOV AL,’A’  AL=41H

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


标号(也叫 变量):

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

标号的属性:

段值 变量所在段的段地址

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

类型 字节型\字型\双字类型

标号的命名

不能与指令助记符或伪指令重名(注意 汇编语言不区分大小写 所以变量也不能是小写的注记符或伪指令)

不允许由数字打头

字符个数不超过 31 个。

       

       


表达式:

算数运算

逻辑运算

关系运算

取值运算和属性运算

其他运算


取值运算符

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

获取变量的属性值

OFFSET 取得其后变量或标号的偏移地址. (用LEA也可以做到)

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

例:

MOV AX,SEG DATA

MOV DS,AX

MOV BX,OFFSET DATA等价于LEA BX,DATA


属性运算符

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

运算符PTR

例子

MOV BYTE PTR[BX],12H

指定存储器操作数[BX]是字节型


第36讲 数据定义伪指令

伪指令

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

作用:

定义变量

分配存储器

定义逻辑段

指示程序开始和结束

定义过程等.


帮助计算机理解助记符指令编写的汇编语言源程序



常用伪指令:

数据定义伪指令

符号定义伪指令

段定义伪指令

结束伪指令

过程定义伪指令

宏命令伪指令


数据定义伪指令

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

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

变量名:符号地址

伪指令助记符:定义变量类型

操作数:变量值,可以是常数,表达式或字符串。其大小不能超过伪指令助记符所限定的范围

变量的类型及其操作数的个数决定了该变量所在内存空间的大小

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

 DB(Define Byte):定义的变量为字节型 指向的每一个操作数占1个字节单元

 DW (Define Word) :定义的变量为字类型 指向的每一个操作数占1个字单元

 DD (Define Double Word) :定义的变量为双字型

 DQ (Define Quadword) :定义的变量为4字型

 DT (Define Tenbytes) :定义的变量为10字节型

DATA1 DB 11H,22H,33H,44H

DATA2 DW 11H,22H,3344H

DATA3 DD 11H*2,22H,33445566H

以上变量在内存中的存放形式?

       

       


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

数据定义伪指令决定所定义变量的类型;

定义字符串必须用DB伪指令

例: DATA1 DB ‘ABCD’ ,66H

       

       


2. 重复操作符

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

作用:为一个数据区的各单元设置相同的初值

格式:[变量名] 伪指令助记符 n DUP(初值 [,初值,… ] )

n:重复次数

(初值 [,初值,… ] ):重复的内容

例: M1 DB 10 DUP(0)

常用于声明一个数据区

3. “?”的作用

表示随机值,用于预留存储空间

例:

 MEM1 DB 34H, ’A’ ,? 随机数占1个字节单元

 DW 20 DUP(?) 预留40个字节单元,每单元为随机值


数据定义伪指令例

 M1 DB ‘How are you?’

 M2 DW 3 DUP(11H),3344H

DB 4 DUP(?)

 M3 DB 3 DUP(22H,11H,?)

       

       



第37讲 符号与段定义伪指令

一、符号定义伪指令

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

 格式:

 符号名 EQU 表达式

(EQU说明的表达式不占用内存空间)

(类似于c语言中的#define)

 操作:

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

 例:

 CONSTANT EQU 100

后面的程序就可以用CONSTANT代替100了

二、段定义伪指令

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

 说明逻辑段的起始和结束

 说明不同程序模块中同类逻辑段之间的联系形态

 格式:

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

┇(中间的是内容,可以是代码,可以是数据,看是什么段了)

段名 ENDS


段名 逻辑段的段基地址

定位类型 说明逻辑段的起点。(默认以节为边界,被16整除)

组合类型 装入内存时各逻辑段的组合方式(默认不组合)

类别 链接时不同程序模块中的同类逻辑段将被装入连续存储区。

段定义伪指令例

DATA SEGMENT

MEM1 DB 11H,22H

MEM2 DB ‘Hello!’

MEM3 DW 2 DUP(?)

DATA ENDS

DATA段名代表逻辑段的段地址

MEM1\ MEM2 \MEM 3变量在逻辑段中的位置就代表了它的偏移地址

DW、DB表示变量的类型

DATA段名也代表逻辑段的段地址


三、设定段寄存器伪指令

说明所定义逻辑段的性质。设定段寄存器为指令助记符

格式:

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

因为一个程序模块里有四种逻辑段,每个段寄存器对应每种逻辑段,所以可以用段寄存器来定义逻辑段性质。

例如ASSUME CS:代码段名字 代码段一定有

定义数据段 ASSUME DS:段名

有串操作声明附加段 ASSUME ES:段名

堆栈声明堆栈段   ASSUME SS:段名


四、结束伪指令

 表示源程序结束

 格式: END [标号]


汇编语言源程序结构:

数据段名 SEGMENT

数据段名 ENDS

附加段名 SEGMENT

附加段名 ENDS

堆栈段名 SEGMENT

堆栈段名 ENDS

代码段名 SEGMENT

代码段名 ENDS

END


一定有代码段,大多需要定义数据段,有串操作需要定义附加段,有PUSH\POP\过程中断等需要堆栈的需要定义堆栈段


一个完整源程序结构例:

DSEG SEGMENT

DATA1 DB 1, 2, 3 DUP (?)

DATA2 DW 1234H

DSEG ENDS

ESEG SEGMENT

DB 20 DUP(?)

ESEG ENDS

SSEG SEGMENT STACK ‘STACK‘

DB 200 DUP (?)

SSEG ENDS

CSEG SEGMENT

ASSUME CS: CSEG, DS: DSEG,

ES: ESEG. SS: SSEG;这里可以换行,但是上一句的逗号不能缺省

START: MOV AX, DSEG;因为当目的操作数是段寄存器时,源操作数不能是立即数,所以通过AX.

MOV DS, AX

MOV AX, ESEG

MOV ES, AX

MOV AX, SSEG

MOV SS, AX;这几行叫做段寄存器的初始化,将段地址送给相应的段寄存器

……省略的地方才是前面学的那些源代码程序

CSEG ENDS

END START

第38讲 其它伪指令

过程定义伪指令

宏定义伪指令

调整偏移量伪指令



过程定义伪指令

 用于定义一个过程体

 格式:

过程名 PROC [ NEAR / FAR ]

RET

过程名 ENDP

过程名:过程入口的符号地址

若为近过程,NEAR可省略。(没有的话默认NEAR)

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

过程定义及调用例:

定义延时子程序

DELAY PROC

PUSH BX

PUSH CX;这两条参数保护。和后面POP搭配起来

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

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


宏定义与宏调用例

定义宏:

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 表达式    (表达式的计算值为非负常数)

例:

DATA SEGMENT

ORG 1200H

BUFF DB 1,2; 变量BUFF的偏移地址=1200H

DATA ENDS


第39讲 系统功能调用

BIOS、DOS功能调用

BIOS:驻留在ROM中的基本输入/输出系统. 加电自检,装入引导,主要I/O设备处理程序及接口控制

DOS:磁盘操作系统

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

DOS功能与BIOS功能均通过中断方式调用,所以调用BIOS和调用DOS可以说成BIOS中断、DOS中断


DOS软中断

DOS中断包括:设备管理,目录管理,文件管理,其它

用中断类型码区分

DOS软中断:类型码为21H

关于DOS软中断说明:

 包含多个子功能的功能包;

 各子功能用功能号区分;

 用软中断指令调用,中断类型码固定为21H


DOS功能调用的基本步骤

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

 将功能号装入AH;

 按中断类型号调用DOS中断;

 检查返回参数是否正确。

 调用格式:

MOV AH,功能号

<置相应参数>

INT 21H



1. 单字符输入

 调用方法:

MOV AH,01

INT 21H

 输入的字符在AL中


例子

GET_KEY: MOV AH,1

INT 21H

CMP AL,’Y’;(交互式应答程序)

JZ YES

CMP AL,’N’

JZ NO

JMP GET_KEY

YES: ┇

NO: ┇


2. 字符串输入

 接收由键盘输入一串字符

 输入的字符串存储在内存指导区域中(字符输入缓冲区)

 用户自定义缓冲区格式:

       

       

(敲入的字符从第三个单元开始放。存放键入的字符数比最大少一个,ODH回车要占用一个字符位置)

字符串输入功能号:10

缓存区须定义在数据段

方法:

AH 功能号

DS:DX 字符串在内存中的存放地址。缓冲区必须定义在数据段,规定偏移地址必须送给DX

INT 21H


输入字符串程序段

DAT1 DB 20,?,20 DUP(?); 在数据段中定义

LEA DX,DAT1

MOV AH,0AH

INT 21H

输入缓冲区

定义后的输入缓冲区初始状态:(敲入的字符从第三个单元开始放。20个字节只能输入19个字符哦,因为回车0DH占一个)

       

       


3. 单字符显示输出

AH 功能号2

DL 待输出字符

INT 21H

例:

MOV AH,2

MOV DL,41H

INT 21H

执行结果:屏幕显示A


4. 字符串输出显示

AH 功能号09H

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

INT 21H

注意点:

 被显示的字符串必须以‘$’结束;

 所显示的内容不应出现非可见的ASCII码;

 若考虑输出格式需要,在定义字符串后,加上回车符和换行符。


字符串输出显示例

DATA SEGMENT

MESS1 DB ‘Input String:’, 0DH,0AH,’$’

DATA ENDS

CODE SEGMENT

MOV AH,09

MOV DX,OFFSET MESS1

INT 21H

(0DH回车  光标会在字符后面闪烁

0AH换行

ODH 和0AH 下一行闪烁)

       

       


5. 返回操作系统(DOS)功能

 功能号: 4CH

 调用格式:

MOV AH,4CH

INT 21H

 功能:

 程序执行完该2条语句后能正常返回OS

 常位于程序结尾处。


DOS功能调用小结

 通过中断指令调用。1个中断类型码对应1个功能程序包;

 每个程序包中的子功能通过功能号区分,调用时功能号须送AH;

 注意不同子功能的入口/出口参数要求;

DOS和BIOS中断均可能影响AX (需要用PUSH\POP保护数据)

第40讲 汇编语言程序设计示例详解

实例4:

DATA SEGMENT

STR1 DB ‘HELLO WORLD!‘

STR2 DB ‘HELLO WOOLD!’

COUNT DW 12;16位

FLAG DB ?

DATA ENDS

CODE SEGMENT

ASSUME CS: CODE, DS: DATA, ES: DATA;DATA既是数据段又是逻辑段

START: MOV AX, DATA

MOV DS, AX

MOV ES, AX

LEA BX, FLAG

LEA SI, STR1

LEA DI, STR2

MOV CX,COUNT

CLD

REPE CMPSB

JZ NEXT1

MOV Byte PTR[BⅪ],00H

JMP STOP

NEXT1: MOV Byte PTR(BX], OFFH

STOP:……

问 当程序执行到STOP时

SI\DU\CX\FLAG\ZF的值

SI=9,DI=0015H,CX=3,FLAG=0,ZF=0


开始SI=0 DI=12=0CH

到R和O不同的位置是9次

SI=0+9=9

DI=12+9=21=0015H

遇到不同的,结果不为0,ZF=0

00H给了BX,FLAG=0

CX=12-9=3

       

       


实例5

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

MOV CX, 8

NEXT: ROR AL, 1;不含CF的循环右移指令

JNC NEXT1

MOV Byte PTR[BX], 0FFH

JMP NEXT2

NEXT1: MOV Byte PTR [BX], 0

NEXT2: INC BX

LOOP NEXT

……

如果从380H端口输入的是45H,则程序执行完后:

BX=(8)

AL=(45H)

SUM0-SUM7的内容是(FF,0,FF,0,0,0,FF,0)


AL=01000101 最低位存入CF,存入最高位 AL=10100010

因为CF=1 JNC不会转向NEXT1

[BX]的内容FFH

NEXT2 BX+1

循环8次NEXT


去NEXT

CF=0,AL=01010001

跳到NEXT1

[BX]的内容FFH

。。。

汇编语言程序设计小结

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

 根据实际问题抽象出数学模型

 确定算法

 画程序流程图

 分配内存工作单元和寄存器

 程序编码

 调试

内容提要

 汇编语言源程序的结构

 汇编语言语句---变量、表达式中的运算符

 伪指令

 DOS功能调用:5个子功能的应用

 简单汇编语言源程序的设计


注意点

 变量的定义与应用:明确所定义变量在内存中的分布

 存储区的定义:不能定义没有变量的存储区

 完整的汇编语言源程序结构:定义逻辑段,说明段的含义,初始化段寄存器

 伪指令:数据定义方式

 字符及字符串的输入和显示输出:字符输入缓冲区的定义,输出字符串的定义

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

 子程序结构:子程序的定义和调用方式


例:

 定义20B的字符输入缓冲区BUFF以及20B的字节变量DATA;

 显示字符串输入提示信息,然后从键盘接收字符‘Hello,my friends!’;

 将BUFFER中的字符串按从左到右的方向传送到DATA中。

分析:

字符串显示输出 字符串输入 串操作指令

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:ESEG

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

INT 21H

XOR CX,CX

MOV CL,BUFF+1;BUFF+1的地址是存放放字符串实际长度值的单元

LEA DI,DATA

LEA SI,BUFF+2;开始存字符串内容的地方

CLD

REP MOVSB

MOV AH,4CH

INT 21H

CSEG ENDS

END SATRT



第七周 汇编语言程序设计的评论 (共 条)

分享到微博请遵守国家法律