您现在的位置:首页 > >

第10章如何发挥主机内存各类寄存器处理器的功能--汇编语言程序设计

发布时间:

10.1 概述
? 10.1.1 汇编语言程序设计的一般步 骤
? 10.1.2 流程图
返回本章首页

10.1.1 汇编语言程序设计的一般 步骤
?汇编语言程序设计一般有以下几 个步骤: ?1.分析问题,确定算法 ?2.绘制流程图 ?3.根据流程图编制程序 ?10.调试程序
返回本节

10.1.2 流程图

? 1.流程图的概念
? 流程图是由特定的几何图形、指向线、 文字说明来表示数据处理的步骤,形象描 述逻辑控制结构以及数据流程的示意图。 流程图具有简洁、明了、直观的特点。

2.流程图符号表示

(1)起止框:表示程序 ?开始

的开始和结束。

?结束

Y

N

? (2)判断

?条件



(3)处理框

? (10)指 向线

10.2 顺序程序设计
? 下面举例说明顺序程序的设计。 ? 【例10.1】试编写一程序计算以下表达式的
值。 ? w=(v-(x*y+z-5100))/x ? 式中x、y、z、v均为有符号字数据。 ? 设x、y、z、v的值存放在字变量X、Y、
Z、V中,结果存放在双字变量W之中,程序 的流程图如图10.1所示。

?.

图 10 1















DX





? 源程序如下:

? DATA

SEGMENT

? X DW 200

? Y DW 100

? Z DW 3000

? V DW 10000

? W DW 2 DUP(?)

? DATA

ENDS

? STACK SEGMENT STACK

?

DB 200 DUP(0)

? STACK ENDS

? CODE

SEGMENT

?

ASSUME DS : DATA , CS : CODE , SS :

STACK

? START: MOV AX,DATA

?

MOV DS,AX

;DATA→AX

?

MOV AX,X

?

IMUL Y

;(X)*(Y)→DX:AX

?

MOV CX,AX

?

MOV BX,DX

;(DX:AX)→(BX:CX)

?

MOV AX,Z

?

CWD ;(Z)符号扩展

?

ADD CX,AX

?

ADC BX,DX

(BX:CX)

;(BX:CX)+(DX:AX)→

?

SUB CX,5100

?

SBB BX,0 ;(BX:CX)-5100→(BX:CX)

?

MOV AX,V

? CWD ;(V)符号扩展 ? SUB AX,CX ? SBB DX,BX ;(DX:AX)-(BX:
CX)→(DX:AX) ? IDIV X ;(DX:AX)/X ? MOV W,AX ;商→W ? MOV W+2,DX ;余数DX→W+2 ? MOV AH,10CH
? INT 21H ? CODE ENDS ;退出DOS 状态
? END START

【例10.2 BX、AL与查表指令】
? 【例10.2】已知某班学生的英语成绩按学号 (从1开始)从小到大的顺序排列在TAB表中, 要查的学生的学号放在变量NO中,查表结果 放在变量ENGLISH中。编写程序如下:

? STACK SEGMENT STACK

? DB

200 DUP(0)

? STACK ENDS

? DATA SEGMENT

? TAB

DB 80,85,86,71,79,96

?
810

DB 83,56,32,66,78。

? NO

DB 10

? ENGLIST DB ?

? DATA ENDS

? CODE SEGMENT

?

ASSUME DS:DATA,SS:STACK,CS:CODE

? BEGIN: MOV AX,DATA

?

MOV DS ,AX

?

LEA BX,TAB

?

MOV AL,NO

?

DEC AL

?

XLAT TAB

?

MOV ENGLISH,AL

?

MOV AH,10CH

?

INT 21H

? CODE

ENDS

?

END BEGIN

10.3 分支程序设计 (标志寄存器与条件转移指令)

测试某一次运算的结 ZF=1 JZ/JE



SF=1 JS

OF=1 JO PF=1 JP

CF=1 JC(JB,JNAE)

比较两个无符号数 (ASCII码)

JB=JNAE=JC(借位 JL=JNGE 位)

测试CX的值,等于0 JCXZ 则转移

JNLE=JG

返回本章首页

10.3 分支程序设计 (标志寄存器与条件转移指令)
? 10.3.1 用条件转移指令实现程序分 支
? 10.3.2 用跳转表实现多路分支
返回本章首页

10.3.1 用条件转移指令实现程序 分支

? 【例10.3】编写计算下面函数值的程序:

?

1 X>0

? Y= 0 X=0

?

-1 X

? 设输入数据为X、输出数据Y,且皆为字节变量。程 序流程图如图10.2所示。

? 程序如下:

?图10.2 分支运算程序流程图

? DATA SEGMENT

?X

DB -10

?Y

DB ?

? DATA ENDS

? STACK SEGMENT STACK

?

DB 200 DUP(0)

? STACK ENDS

? CODE SEGMENT

? ASSUME DS:DATA,SS:STACK,CS: CODE

? START: MOV AX,DATA

?

MOV

?

CMP

?

JGE

?

MOV

?

JMP

? A1: JG A2

?

MOV

?

JMP

? A2: MOV

? EXIT: MOV

?

INT 21H

? CODE ENDS

?

END

DS,AX X,0 ;与0进行比较 A1 ;X≥0转A1 Y,-1 ;X <0时,-1→Y EXIT ;X>0转A2 Y,0 ;X=0时,0→Y EXIT Y,1 ;X>0,1→Y AH,10CH
START

X<=0
>
?图10.2 分支运算程序流程图

? DATA SEGMENT

?X

DB -10

?Y

DB ?

? DATA ENDS

? STACK SEGMENT STACK

?

DB 200 DUP(0)

? STACK ENDS

? CODE SEGMENT

? ASSUME DS:DATA,SS:STACK,CS: CODE

? START: MOV AX,DATA

?

MOV DS,AX

?

CMP X,0

?

JLE A1

?

MOV Y,1

?

JMP EXIT

? A1: JL

A2

?

MOV Y,0

?

JMP EXIT

? A2: MOV Y,-1

? EXIT: MOV AH,10CH

?

INT 21H

? CODE ENDS

?

END START

【例10.10】
? 【例10.10】试编一程序,求三个带符号 字数据中的最大值,并将最大值存入MAX 字单元中。
? 设三个带符号数分别在三个字变量X、 Y、Z中存储。程序流程图如图10.3所示

图10.3 [例10.10]程序流程图

? 程序如下:

? STAC SEGMENT STACK

?

DB 200 DUP(0)

? STACK ENDS

? DATA SEGMENT

?X

DW 00ABH

?Y

DW –5

?Z

DW 200

? MAX

DW ?

? DATA ENDS

? CODE SEGMENT

?

ASSUME DS:DATA,SS:STACK,CS:CODE

? START: MOV AX,DATA

?

MOV DS,AX

?

MOV AX,X

?

CMP AX,Y ;X>Y?

?

JG

L1

?

MOV AX,Y ;Y>Z?

?

CMP AX,Z

?

JG

EXIT

? L2:

MOV AX,Z

?

JMP EXIT

?

? L1:
?
? EXIT:
? ?
? CODE
?

CMP AX,Z;X>Z?

JLE L2

MOV MAX,AX

MOV

AH,10CH

INT 21H

ENDS

END START

返回本节

10.3.2 用跳转表实现多路分支(教材177页)
? 【例10.5】设某程序有8路分支,试根据给定 的N值(1~8),将程序的执行转移到其中的 一路分支。
? 程序流程如图10.10所示。

? 程序如下:

? DATA SEGMENT

? TAB

DW P1,P2,P3,P10,P5,P6,P7,P8

?N

DB 5

? DATA ENDS

? STACK SEGMENT

?

DB 200 DUP(0)

? STACK ENDS

? CODE SEGMENT

?
CS:CODE

ASSUME DS:DATA,SS:STACK,

?START: MOV AX,DATA

?

MOV DS,AX

?



?

MOV AL,N

? DEC AL

?

ADD AL,AL ;SHL AL

?

MOV BL,AL

?

MOV BH,0

?

JMP TAB[BX] ;

MOV AX,OFFSET TAB ADD BX,AX MOV AX,[BX]
JMP AX

? P1:
?
? JMP ? P2:
?
? JMP ? P2:
?
? JMP ? P3:
?

…… ┆ EXIT …… ┆ EXIT …… ┆ EXIT …… ┆

?

JMP EXIT

?



? P8:

……

?



? EXIT: MOV AH,10CH

?

INT 21H

? CODE ENDS

?

END START

?

上述程序中的无条件转移指令的

转移地址采用的是变址寻址。同理,转移地

址也可以用寄存器间接寻址或基址加变址寻

址,读者可自行考虑。

返回本节

10.10 循环程序设计
? 10.10.1 循环程序的结构 ? 10.10.2 单重循环程序设计 ? 10.10.3 多重循环程序设计
返回本章首页

10.10.1 循环程序的结构
? 1.初始化部分 ? 2.循环体部分 ? 3.循环控制部分

循环程序的常见结构形式如图10.5(a)、 (b)所示。
循 环 体
循 环 体
返回本节

10.10.2 单重循环程序设计
? 1.计数控制 ? 2.条件控制

1.计数控制
? 【例10.7】已知有几个元素存放在以BUF为 首址的字节存贮区中,试统计其中正元素的 个数。
? 显然,每个元素为一个8位有符号二进制 数,统计其中正元素的个数可用循环程序实 现。其程序流程图如图10.6所示。

?.

[Bx] <=0
图 10

6







<=0

程 图

title account data segment
number db 10,-23,-30,50,9,-105,32,310,20,86 s db 0 data ends code segment assume cs:code,ds:data start: mov ax,data
mov ds,ax mov bx,offset number mov cx,10 mov al,s
本题为统计10个数值中正数的个数

do2: mov dl,0 cmp [bx],dl jle do1 inc al
do1: dec cx cmp cx,0 jle exit inc bx jmp do2
exit: mov s,al mov ah,10ch int 21h
code ends end start
本题为统计10个数值中正数的个数

data segment message db "overflow!!!" a db 100 b db 100 c db ?
data ends code segment assume cs:code,ds:data start:mov ax,data
mov ds,ax mov al,a mov bl,b add al,bl jo chuli jmp end1 chuli:call yichu end1:mov ah,10ch int 21h

yichu proc mov cx,11 mov si,offset message
back:mov dl,[si] mov ah,2 int 21h dec cx inc si cmp cx,0 ja back ret
yichu endp code ends
end start

关于循环结构中的串操作指令实施步骤
? 1、如果串操作要涉及两个串,则一个串应在DS中,叫做源 串,另一个应在ES中,叫做目标串。定义一个同时包含这 两个串的数据段,然后把段基址同时传送到DS和ES中,用 DS:[SI](偏移量1)表示源串,用DS:[DI](偏移量2)表 示目的串。
? 2、在串传送、比较等操作之前,因为在串的传送和比较过 程时,系统是逐个字符进行比较的,所以传送和比较操作需 要重复进行多次。因此需要在执行之前用CX保存重复执行 的次数。
? 3、用CLD命令置DF=0,使SI,DI自动增量进行;用STD命 令置DF=1,使SI,DI自动减量进行
? 10、增量可能是1也可能是2,这取决于串处理指令是字节型 还是字类型。

将内存中10000H单元开始存放的“classmates!”的字 符串传送到20000H单元开始的区域
? title account ? data segment ? org 1000h ? db "classmates!" ? org 2000h ? db 11 dup(?) ? data ends ? code segment ? assume cs:code,ds:data,es:data
?

将内存中10000H单元开始存放的

“classmates!”的字符串传送到20000H单元开

? start: mov ax,data始的区域

?

mov ds,ax

?

mov si,1000h

?

mov ax,data

?

mov es,ax

?

mov di,2000h

?

mov cx,11

?

cld

?

rep movsb

?

mov ah,10ch

?

int 21h

? code ends

?

end start

比较“classmate”和”classnate”是否相同

? title account

? data segment

? org 1000h

? db "classmate"

? org 2000h

? db "classnate"

? data ends

? code segment

? assume cs:code,ds:data,es:data

? start: mov ax,data

?

mov ds,ax

?

mov si,1000h

?

mov ax,data

?

mov es,ax

比较“classmate”和”classnate”是否相



?

mov di,2000h

?

mov cx,11

?

cld

?

repe cmpsb

?

cmp cx,0

?

jnz decision1

?

mov bx,0 ;equation

?

jmp exit

? decision1: mov bx,1 ;not equation

? exit:

mov ah,10ch

?

int 21h

? code ends

?

end start

【例10.8】
? 【例10.8】试编写一程序,要求比较两个字 符串STR1和STR所含字符是否相同,若相同 则 显 示 ‘ MATCH ! ’ , 若 不 相 同 则 显 示 ‘NO MATCH!’。(程序略)
? 其流程图如图10.7所示。

?.

图 10 7
程 序 流 程 图

2.条件控制
? 【例10.9】试编一个程序将字单元BUF 中所含1的个数存入COUNT单元中。要测 出BUF字单元所含1的个数,首先将BUF 中的数送给寄存器AX,然后将AX寄存器 逻辑左移一次,如果CF=1,则表明AX中 的最高位为1,则计数器CL计数1次,如 果CF=0,表明AX最高位为0,这样依次 将最高位移入CF中去测试。移位之后, 判断AX的值是否为0,如果为0则结束循 环,不为0,则继续循环。
? 其流程图如图10.8所示。

? 程序如下:

? STACK SEGMENT STACK

?

DB 200 DUP(0)

? STACK EDNS

? DATA SEGMENT

? BUF

DW 0011110010101011B

? COUNT DB ?

? DATA ENDS

? CODE SEGMENT

?

ASSUME DS:DATA,CS:CODE,SS:

STACK

?

START:

MOV AX,DATA

?

MOV DS,AX

?

MOV AX,BUF

?

MOV CL,0 ;计数器为0

?

COPA:

AND AX,AX

?

JE EXIT ;(AX)=0,结束循环

?

SHL AX,1 ;AX 左移一位

?

JNC LOPA

?

INC CL ;产生进位,(CL)+1→CL

?

JMP LOPA

?

EXIT: MOV COUNT,CL

?

MOV AH,10CH

?

INT 21H

?

CODE ENDS

?

END START

返回本节

10.10.3 多重循环程序设计
? 【例10.10】在以BUF为首址的字存储区中存 放有N个有符号数,现需将它们按大到小的顺 序排列在BUF存储区中,试编写其程序。
? 我们采用冒泡排序算法从第一个数开始依 次对相邻两个数进行比较,如次序对,则不 交换两数位置;如次序不对则使这两个数交 换位置。可以看出,第一遍需比较(N-1)次, 此时,最小的数已经放到了最后;第二遍比 较只需考虑剩下的(N-1)个数,即只需比较 ( N-2 ) 次 ; 第 三 遍 只 需 比 较 ( N-3 ) 次,……整个排序过程最多需(N-1)遍。如 下面的10个数即是采用冒泡排序比较的例子。

? 数 10 8 16 90 32 ? 第一遍 10 16 90 32 8 ? 第二遍 16 90 32 10 8 ? 第三遍 90 32 16 10 8 ? 程序流程图如图10.9所示。

?

程序如下:

?

DATA SEGMENT

?

BUF DW 3,-10,6,7,9,2,0,-8,-9,-

10,20

?

N=($-BUF)/2

?

DATA ENDS

?

STACK SEGNMENT STACK

?

DB 200 DUP(0)

?

STACK ENDS

?

CODE SEGMENT

?

ASSUME CS : CODE , DS : DATA , SS :

STACK

?

START:

MOV AX



DATA

?

MOV DS,AX

?

MOV CX,N

?

DEC CX

?

LOOP1:

MOV DX,CX

?

MOV BX,0

?

LOOP2:

MOV AX



BUF[BX]

?

CMP AX,BUF[BX+2]

?

JGE L

?

XCHG AX,BUF[BX+2]

?

MOV BUF[BX],AX

?

L: ADD BX,2

?

DEC CX

?

JNE LOOP2

?

MOV CX,DX

?

LOOP LOOP1

?

MOV AH,10CH

?

INT 21H

?

CODE ENDS

?

END START

? 程序运行后,BUF区中的内容如下: ? 20,9,7,6,3,2,0,-10,-8,
-9,-10 ? 若要对N个无符号数按由大到小的顺
序排列,只需将指令“JGE L”改为 “JAE L”即可。
返回本节

10.5 子程序设计
? 10.5.1 子程序的概念 ? 10.5.2 子程序的定义 ? 10.5.3 子程序设计方法 ? 10.5.10 子程序应用举例
返回本章首页

10.5.1 子程序的概念
? 在程序设计中,我们会发现一些多次无规 律重复的程序段或语句序列。解决此类问题 一个行之有效的方法就是将它们设计成可供 反复调用的独立的子程序结构,以便在需要 时调用。在汇编语言中,子程序又称过程。
? 调用子程序的程序称为主调程序或主程序。
返回本节

10.5.2 子程序的定义

?子程序的定义是由过程定义伪指令PROC和ENDP 来完成的。其格式如下:

?过程名 PROC [NEAR/FAR]

?



?过程名 ENDP

?其中PROC表示过程定义开始,ENDP表示过程定 义结束。过程名是过程入口地址的符号表示。

?一般过程名同标号一样,具有三种属性,即段 属性、偏移地址属性以及类型属性。

返回本节

10.5.3 子程序设计方法
? 1.信息的保护与恢复 ? 2.主程序与子程序参数传递方式

1.信息的保护与恢复

?

例如:若子程序PROG中改变了寄

存器AX,BX,CX,DX的值,则可

采用如下方法保护和恢复现场。

?

PROG PROC

?

PUSH AX

?

PUSH BX

?

PUSH CX ;保护现场

?

PUSH DX

?



?┆ ? POP DX ? POP CX ? POP BX ;恢复现场 ? POP AX ? RET ;返回断点处 ?PROC ENDP

2.主程序与子程序参数传递 ? (1)寄方存器式法
? (2)约定单元法 ? (3)堆栈法
返回本节

10.5.10 子程序应用举例
? 【例10.12】将一个给定的二进制数按 位转换成相应的ASCII码字符串,送到 指定的存储单元并显示。如二进制数 10010011转换成字符串为‘10010011’。 要求将转换过程写成子程序,且子程序 应具有较好的通用性,而必须能实现对 8倍和16倍二进制数的转换。

? 入口参数:DX存放待转换的二进制数 ? CX存放待转换数的位数(8位或16位) ? DI存放ASCII码首地址 ? 出口参数:转换后的字符串存放在以DI作指针的字节
存贮区中 ? 程序如下:
? DATA SEGMENT
? NUM8 DB 93H
? NUM16 DW 0ABCDH ? ASCBUF DB 20 DUP(0)
? DATA ENDS

?

CODE SEGMENT

?

ASSUME DS : DATA , CS : CODE , SS :

STACK

?

START:

MOV AX,DATA

?

MOV DS,AX

?

MOV DX,0

?

MOV DL,NUM8 ;转换二进制数送DX

?

MOV CX,8 ;置位数8

?

LEA DI,ASCBUF ;字符串首址→DI

?

CALL BTASC ;调用子程序BTASC

?

MOV [DI],BYTE PTR 0DH

?

MOV [DI+1],BYTE PTR 0AH

? MOV [DI+2],BYTE PTR ‘$’

?

LEA DX,ASCBUF

?

MOV AH,9

?

INT 21H

?

MOV DX,NUM16

?

MOV CX,16 ;置位数16

?

LEA DI,ASCBUF

?

CALL BTASC

?

MOV [DL],BYTE PTR 0DH

?

MOV [DL+1],BYTE PTR 0AH

?

MOV [DL+2],BYTE PTR ‘$’



显示转换后的字符串

?

LEA DX, ASCBUF

?

MOV AH,9

?

INT 21H

?

BTASC PROC

?

PUSH AX ;保存AX

?

MOV AL,0

?

CMP CX,8 ;比较8位数

?

JNE L1 ;直接转换16位数

?

MOV DH,DL

;8位数转换送DH

?

L1: ROL DX,,1 ;DX最高位移入CF

?

RCL AL,1 ;CF移入AL最低位

?

ADD AL,30H

?

MOV [DI],AL

?

INC DI

?

LOOP L1

?

POP AX

?

RET

?

BTASC ENDP

?

CODE ENDS

?

END START

返回本节

data segment message db
"overflow!!!$" a db 100 b db 100 c db ?
data ends code segment
assume cs:code,ds:data start:mov ax,data
mov ds,ax mov al,a mov bl,b add al,bl jo chuli

jmp end1 chuli:call yichu end1:mov ah,10ch
int 21h yichu proc mov dl,offset message mov ah,9
int 21h ret
yichu endp code ends
end start

10.7 高级汇编语言技术
? 10.7.1 宏指令 ? 10.7.2 宏指令的使用过程
返回本章首页

10.7.1 宏指令
? 在汇编语言程序设计过程中,可以 将具有一定功能,需多次重复使用,且 比较短的程序段定义成一条宏指令。
? 使用宏指令语句可以减少程序书写 错误,缩短源程序长度,使源程序编写 像高级语言一样清晰、简洁。特别是使 用宏库后,可以提高编程效率。
返回本节

10.7.2 宏指令的使用过程
? 1.宏定义 ? 2.宏调用 ? 3.宏扩展

1.宏定义
? (1)带参宏定义 ? 宏 指 令 名 MACRO 形 参 1 , 形 参
2,…… ? 宏体 ? ENDM ? (2)无参宏定义 ? 宏指令 MACRO ? 宏体 ? ENDM

2.宏调用

? 格式:

? 宏指令名 [实参1,实参2,……]

? 例如:对上面的宏定义的三种调用形式为:

?



? PRINT BUF1

?



? PRINT BUF2

?┆

? PRINT BUF3

?



3.宏扩展

?例如:上面三次宏调用,其展开的形式为:

?┆ ? + LEA ? + MOV ? + INT ?┆ ? + LEA ? + MOV ? + INT

DX,BUF1 AH,9
21H

DX,BUF2 ┆

AH,9

+ LEA + MOV

DX,BUF3 AH,9

21H

+ INT 21H



返回本节



热文推荐
猜你喜欢
友情链接: 幼儿教育 小学教案 初中教案 高中教案 职业教育 成人教育