宏指令及其使用 宏指令、宏定义和宏调用 宏指令...

27
宏宏宏宏宏宏宏 宏宏宏宏宏宏宏 宏宏宏 宏宏宏宏宏宏宏 宏宏宏 宏宏宏宏宏宏宏 宏宏宏 宏宏宏 宏宏宏宏宏宏宏宏宏宏宏 宏宏宏宏宏 宏宏宏宏宏宏宏宏宏宏宏 宏宏宏宏宏 宏宏宏 宏宏宏 宏宏宏宏 宏宏宏宏 MACRO < MACRO < 宏宏宏宏 宏宏宏宏 > ENDM ENDM 宏宏宏 宏宏宏 宏宏宏宏宏宏宏宏宏宏宏宏宏宏宏宏宏宏 宏宏宏宏 < 宏宏宏宏 宏宏宏宏 > >

description

宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ; … 宏体 … ; ENDM 宏调用 宏调用的格式为: 宏指令名 < 实际参数 >. 例: 1 ) PUSHREGMACRO PUSHAX PUSHBX PUSHCX PUSHDX PUSH SI PUSHDI - PowerPoint PPT Presentation

Transcript of 宏指令及其使用 宏指令、宏定义和宏调用 宏指令...

Page 1: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

宏指令及其使用宏指令及其使用 宏指令、宏定义和宏调用 宏指令、宏定义和宏调用

• 宏指令宏指令源程序中具有独立功能的一段程序代码 源程序中具有独立功能的一段程序代码

• 宏定义宏定义宏指令名 宏指令名 MACRO <MACRO < 形式参数形式参数 >>

…… ;;…… 宏体宏体… … ; ;

ENDM ENDM • 宏调用 宏调用

宏调用的格式为:宏调用的格式为:宏指令名宏指令名 << 实际参数实际参数 > >

Page 2: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

例:例:11 )) PUSHREGPUSHREG MACROMACRO PUSHPUSH AXAX PUSHPUSH BXBX PUSHPUSH CXCX PUSHPUSH DXDX

PUSH PUSH SISI PUSHPUSH DIDI ENDMENDM

22 )) LOADW MACRO PRLOADW MACRO PR ,, VARVAR MOVMOV PRPR ,, VARVAR

MOVMOV AXAX ,, [PR][PR] ENDMENDM

33 )) SHIFT MACRO NSHIFT MACRO N ,, REGREG ,,CCCC

MOVMOV CLCL ,, NN S&CC S&CC REGREG ,, CLCL ENDM ENDM

44 )) SAVEW MACRO PRSAVEW MACRO PR ,, REGREG ,,OPCOPC

MOVMOV [PR][PR] ,, REGREGOPCOPC PRPR

ENDM ENDM

LOADW LOADW SISI ,, WVARWVARSHIFT SHIFT 44 ,, AXAX ,, ARARSAVEW SAVEW SISI ,, AXAX ,, INCINC… … 将某变量指针将某变量指针 WVARWVAR 指向的内存单元的指向的内存单元的

内容送内容送 AXAX 寄存器。右移寄存器。右移 44 位后,再存入位后,再存入 WWVARVAR 变量处。变量处。

Page 3: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

MULTIPLY MACRO OPR1MULTIPLY MACRO OPR1 ,, OPR2OPR2 ,, RESULTRESULTMOVMOV AL AL ,, OPR1OPR1

IMULIMUL OPR2 OPR2MOVMOV RESULT RESULT ,, AXAX

ENDMENDMADDMULTADDMULT MACROMACRO REGREG ,, VAR1VAR1 ,, VAR2 VAR2

MULTIPLY FIRST 1MULTIPLY FIRST 1 ,, FIRST2FIRST2 ,, MULT1 MULT1 MULTIPLY SECOND1MULTIPLY SECOND1 ,, SECOND2SECOND2 ,, MULT2MULT2MOVMOV REG REG ,, VAR1VAR1ADDADD REG REG ,, VAR2VAR2MOVMOV SUM SUM ,, REGREG

ENDM ENDM

……MULTIPLY FIRST1MULTIPLY FIRST1 ,, FIRST2FIRST2 ,, MULT1MULT1+MOV AL+MOV AL ,, FIRST1FIRST1+IMUL FIRST2+IMUL FIRST2+MOV MULT1+MOV MULT1 ,, AXAXMULTIPLY MULTIPLY

SECOND1SECOND1 ,, SECOND2SECOND2 ,, MULT2MULT2+MOV +MOV ALAL ,, SECOND1SECOND1+IMUL+IMUL SECOND2SECOND2+MOV+MOV MULT2MULT2 ,, AXAXADDMULT ADDMULT

AXAX ,, MULT1MULT1 ,, MULT2MULT2+MOV+MOV AXAX ,, MULT1MULT1+ADD+ADD AXAX ,, MULT2MULT2+MOV+MOV SUMSUM ,, AXAX… …

宏嵌套宏嵌套

宏调用:宏调用:ADDMULTADDMULT AXAX ,, MULT1MULT1 ,, MULT2 MULT2

Page 4: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

宏定义中的标号与变量宏定义中的标号与变量

DELAY DELAY MACROMACRO VALUE1VALUE1 ,, VALUE2VALUE2

LOCAL LOCAL AGAIN1AGAIN1 ,, AGAIN2AGAIN2

PUSH PUSH AXAX

PUSH PUSH CXCX

MOV MOV CXCX ,, VALUE1VALUE1

AGAIN1AGAIN1 :: MOV MOV AXAX ,, VALUE2VALUE2

AGAIN2AGAIN2 :: DEC DEC AXAX

JNZ JNZ AGAIN2AGAIN2

LOOPLOOP AGAIN1AGAIN1

POP POP CXCX

POP POP AXAX

ENDM ENDM

DELAYDELAY 6789H6789H ,, 0FFFFH0FFFFH++ PUSHPUSH AXAX++ PUSHPUSH CXCX++ MOVMOV

CXCX ,, 6789H6789H+??0000+??0000 :: MOV MOV AX, AX,

OFFFFHOFFFFH+??0001+??0001 DECDEC AXAX++ JNZJNZ ??0001??0001++ LOOPLOOP ??0000??0000++ POPPOP CXCX++ POPPOP AXAX

……DELAYDELAY 0FFF0H0FFF0H ,, 8000H8000H+ + PUSHPUSH AXAX+ + PUSHPUSH CXCX+ + MOVMOV

CXCX ,, 0FFF0H0FFF0H+??0002+??0002 :: MOVMOV

AXAX ,, 8000H8000H+??0003+??0003 :: DECDEC AXAX+ + JNZJNZ ??0003??0003+ + LOOPLOOP ??0002??0002+ + POPPOP CXCX+ + POPPOP AXAX

宏调用:宏调用:……

DELAYDELAY 6789H6789H ,, 0FFFFH0FFFFH……

DELAY DELAY 0FFF0H0FFF0H ,, 8000H8000H……

Page 5: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

小结小结宏指令与子程序的异同宏指令与子程序的异同 相同点:均可用来简化源程序,并可使程序对它们多相同点:均可用来简化源程序,并可使程序对它们多

次进行调用。次进行调用。 不同点:不同点:

• 定义方法及格式不同。定义方法及格式不同。• 子程序省内存,宏指令则不省。子程序省内存,宏指令则不省。• 子程序执行速度慢,而宏运行速度快。子程序执行速度慢,而宏运行速度快。

Page 6: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

6.2 6.2 汇编语言程序设计汇编语言程序设计 编制汇编程序步骤:编制汇编程序步骤: 明确任务,确定算法 明确任务,确定算法 绘流程图 绘流程图 根据流程图编写汇编语言程序 根据流程图编写汇编语言程序 上机调试程序 上机调试程序 程序的基本结构: 程序的基本结构: 顺序结构 顺序结构 分支结构 分支结构 循环结构 循环结构 子程序结构 子程序结构

Page 7: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

编辑源程序 EDIT ABC.ASM

汇编源程序 MASM ABC.ASM

形成目标程序 ABC.OBJ

连接目标程序 LINK ABC.OBJ

有连接错误信息?

形成可执行程序 ABC.EXE

装入可执行程序到内存并执行ABC

下一程序

用DEBUG 调试可执行程序DEBUG ABC.EXE

找到原因

Y

N

Y

N

N

Y

N

有汇编错误信息 ?

Y运行结果正确 ?

用DEBUG 调试程序查错?

Page 8: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

1.1.顺序程序设计顺序程序设计 例:例:

TITLETITLE EXAMPLEEXAMPLE

11 DATADATA SEGMENTSEGMENT

2 2 VARXVARX DWDW 66

33 VARYVARY DWDW 77

44 RESULT RESULT DW ?DW ?

5 5 DATADATA ENDSENDS

66 STACK1 STACK1 SEGMENT PARA STACKSEGMENT PARA STACK

7 7 DWDW 20H DUP(0)20H DUP(0)

88 STACK1 STACK1 ENDSENDS

9 9 COSEG COSEG SEGMENTSEGMENT

1010 PROC1 PROC1 PROCPROC FARFAR

1111 ASSUMEASSUME CSCS :: COSEGCOSEG ,, DSDS :: DATADATA ,, SSSS :: STACK1STACK1

1212 STARTSTART : : PUSHPUSH DSDS

1313 MOVMOV AXAX ,, 00

Page 9: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

续:续:14 14 PUSHPUSH AXAX15 15 MOVMOV AXAX ,, DATADATA16 16 MOVMOV DSDS ,, AXAX1717 MOVMOV DXDX ,, VARX VARX ;; DX←XDX←X1818 ADD ADD DXDX ,, VARYVARY ;; DX←(X+Y)DX←(X+Y)1919 MOVMOV CLCL ,, 332020 SALSAL DXDX ,, CLCL ;; DX←(X+Y)*8DX←(X+Y)*82121 SUB SUB DXDX ,, VARXVARX ;; DX←(X+Y)*8-XDX←(X+Y)*8-X2222 SARSAR DXDX ,, 11 ;; DX←((X+Y)*8-X)/2DX←((X+Y)*8-X)/22323 MOVMOV RESULTRESULT ,, DXDX ;存结果;存结果2424 RETRET25 PROC1 25 PROC1 ENDPENDP26 COSEG26 COSEG ENDSENDS2727 END END STARTSTART

源程序代码段中:源程序代码段中:第第 15,1615,16 语句是为数据段寄存器赋值,让语句是为数据段寄存器赋值,让 DSDS 指向本程序的数据段指向本程序的数据段 DATADATA 。。第第 17~17~ 第第 2323 语句完成公式计算并存储结果是代码段中。语句完成公式计算并存储结果是代码段中。第第 12~12~ 第第 1414 语句是为用户程序结束,返回语句是为用户程序结束,返回 DOSDOS 操作系统而作的准备。操作系统而作的准备。

Page 10: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

DOSDOS 的装入功能 的装入功能 (( 又称又称 EXECEXEC 系统功能系统功能 ))

可执行文件可执行文件 .exe.exe ,应装入内存方能执行。,应装入内存方能执行。

由由 DOSDOS 的装入功能完成。的装入功能完成。

在在 DOSDOS 的提示符后输入可执行文件的文件名的提示符后输入可执行文件的文件名,,

按回车键,按回车键, DOSDOS 系统即调用装入功能 系统即调用装入功能 ,,

将可执行程序装入内存。将可执行程序装入内存。

Page 11: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

当一个用户程序的可执行文件当一个用户程序的可执行文件 (.EXE)(.EXE) 装入内存后,存储器分配情况如图所示装入内存后,存储器分配情况如图所示

系统占用系统占用程序段前缀程序段前缀用户数据段用户数据段用户堆栈段用户堆栈段

用户代码用户代码……

系统和系统和 ROMROM 占用占用

0H0H

DS,ESDS,ES

SSSS

CSCS

0FFFFFH0FFFFFH

共共 100H100H 个字个字节节

用户空间用户空间

Page 12: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

完成以下操作:完成以下操作: 确定内存可用部分,确定内存可用部分, 以便存放要执行的 以便存放要执行的 .exe .exe 文件。文件。 建立程序段前缀建立程序段前缀 PSPPSP

(( Program Segment PrefixProgram Segment Prefix ))• 程序段前缀大小程序段前缀大小 100H100H ,, 即即 256256 个字节。个字节。• 存放进程间的控制信息。存放进程间的控制信息。• PSPPSP 最开始的两个字节最开始的两个字节 CD 20CD 20 ,, 是一条 是一条 INT 20HINT 20H 指令。指令。 装入可执行程序装入可执行程序 .exe.exe

0000: 0000H

可用内存空间

内 存

FFFF:0000H

ROM BIOS

系统检测程序

COMMAND.COM

DOS 系统1KB 中断向量表

CD 20………

hello.exe

xxxx: 0000H

xxxx: 00FFH

程序段前缀

用户程序

Page 13: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

修改以下寄存器的值修改以下寄存器的值

• DSDS 、、 ESES 设置为设置为 程序段前缀所在内存的段值;程序段前缀所在内存的段值; (DS)=xxxxH(DS)=xxxxH

(ES)=xxxxH (ES)=xxxxH

• SSSS 、、 SP SP 设置为设置为 由连接程序传过来的值;由连接程序传过来的值;

• CSCS 、、 IP IP 设置为设置为 程序的入口地址,程序的入口地址, 即伪操作即伪操作 ENDEND 后跟的后跟的 符号名对应的物理地址;符号名对应的物理地址;

此时 此时 CS:IP CS:IP 指向用户程序,指向用户程序, 开始执行用户程序。开始执行用户程序。

0000: 0000H

可用内存空间

内 存

FFFF:0000H

ROM BIOS

系统检测程序

COMMAND.COM

DOS 系统1KB 中断向量表

CD 20………

hello.exe

xxxx: 0000H

xxxx: 00FFH

程序段前缀

CS:IP

Page 14: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

20H 20H 中断程序的功能:中断程序的功能: 处理程序结束,返回系统。处理程序结束,返回系统。调用调用 20H20H 中断程序是有条件的:中断程序是有条件的: 要求当前的要求当前的 CSCS 应为程序段前缀在内存的段值应为程序段前缀在内存的段值

Page 15: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

CD 20

xxxx

….

0000

xxxx:0

SS:SP

SS:SP

程序段前缀 PSP

PSP 的段值

PSP 的偏值

用户程序

CS IP

采用下面的程序框架,采用下面的程序框架,可保证执行可保证执行 INT 20HINT 20H 时,时,当前的当前的 CSCS 值为程序段前缀在内存的段值。值为程序段前缀在内存的段值。

code SEGMENTcode SEGMENT

ASSUME CS:codeASSUME CS:code

main PROC FAR ;main PROC FAR ; 使使 RETRET 为远返回 为远返回 start: PUSH DS ;start: PUSH DS ; 入栈保存地址入栈保存地址 MOV AX, 0 ;MOV AX, 0 ; 程序段前缀的首地址程序段前缀的首地址 PUSH AXPUSH AX

… … ;; 程序主体部分程序主体部分 … …

RET ;RET ; 取程序段前缀首地址取程序段前缀首地址main ENDPmain ENDP

code ENDScode ENDS

END startEND start

Page 16: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

注意:注意:

不可在汇编语言程序的最后用 不可在汇编语言程序的最后用 INT 20HINT 20H 返回返回 DOSDOS 。。原因是原因是 20h20h 中断子程的执行是有条件的。采用上述返回中断子程的执行是有条件的。采用上述返回 DDOSOS 的程序结构,才能满足该条件,否则无法返回。的程序结构,才能满足该条件,否则无法返回。

Page 17: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

结束用户程序,返回操作系统的另一个办法是用中断指令“结束用户程序,返回操作系统的另一个办法是用中断指令“ INT 21H”INT 21H” 。如使用这种办法,。如使用这种办法,用户程序可以不设置过程,只要在用户程序结束时,用以下两条指令即可:用户程序可以不设置过程,只要在用户程序结束时,用以下两条指令即可:

MOV MOV AHAH ,, 4CH4CH INT INT 21H21H这样,上述程序的代码段可以修改为:这样,上述程序的代码段可以修改为: COSEGCOSEG SEGMENTSEGMENT ASSUMEASSUME CSCS :: COSEGCOSEG ,, DSDS :: DATADATA ASSUMEASSUME SSSS :: STACK1STACK1 STARTSTART :: MOVMOV AXAX ,, DATADATA

MOVMOV DSDS ,, AXAXMOVMOV DXDX ,, VARXVARXADDADD DXDX ,, VAYVAYMOVMOV CLCL ,, 33SALSAL DXDX ,, CLCLSUBSUB DXDX ,, VARXVARXSARSAR DXDX ,, 11MOVMOV RESULTRESULT ,, DXDXMOVMOV AHAH ,, 4CH4CHINTINT 21H21H

COSEGCOSEG ENDSENDSEND END START START

Page 18: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

2.2.分支程序设计分支程序设计 分支程序结构也称条件结构,通常有两种形式,见图。 分支程序结构也称条件结构,通常有两种形式,见图。

两个分支

Y

N

多个分支

Page 19: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

例:求补码数例:求补码数 [[XX]]补的绝对值,并送回原处。补的绝对值,并送回原处。STACKSTACK SEGMENTSEGMENT STACKSTACK ;定义堆栈段,;定义堆栈段,

DW DW 256 DUP(?)256 DUP(?) ;预留;预留 256256 个单元个单元TOPTOP LABELLABEL WORDWORD

STACK STACK ENDS ENDS

DATA DATA SEGMENTSEGMENT

XADR XADR DWDW 3456H3456H ;设;设 [X][X] 补补 =3456H=3456H

DATA DATA ENDSENDS

CODE CODE SEGMENTSEGMENT

MAINMAIN PROCPROC FARFAR

ASSUMEASSUME CSCS :: CODECODE ,, DSDS :: DATADATA ,, SSSS :: STACKSTACK

STARTSTART : : MOVMOV AXAX ,, STACKSTACK ;将堆栈段段址送;将堆栈段段址送 SSSS 。。MOVMOV SSSS ,, AXAX

MOV MOV SPSP ,, OFFSET TOPOFFSET TOP ;设置栈指针,使其指向栈顶地址。;设置栈指针,使其指向栈顶地址。PUSHPUSH DSDS ;将;将 PSPPSP 中中 INT 20HINT 20H 指令的存放地址压指令的存放地址压

入栈。入栈。MOVMOV AXAX ,, 00

PUSHPUSH AXAX

MOVMOV AXAX ,, DATADATA ;将数据段段址送;将数据段段址送 DSDS 。。MOV MOV DSDS ,, AXAX

MOV MOV AXAX ,, XADR XADR ;取;取 [X][X] 补到补到 AXAX 。。AND AND AXAX ,, AXAX ;设置标志位。;设置标志位。JNS JNS DONEDONE ;若;若 X≥0X≥0 ,转,转 DONEDONE 。。NEG NEG AXAX ;若;若 X<0X<0 ,求补得,求补得 |X||X| 。。MOV MOV XADRXADR ,, AXAX ;将;将 |X||X| 送回原处。送回原处。

DONEDONE : : RET RET ;返回;返回 PC-DOSPC-DOS 状态。状态。MAINMAIN ENDPENDP

CODECODE ENDSENDS

ENDEND START START

Page 20: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

例:设有一组例:设有一组 (8(8 个个 )) 选择项存于选择项存于 ALAL 寄存器中,试根据寄存器中,试根据 ALAL 中哪一位中哪一位为为 11 把程序分别转移到相应的分支去。 把程序分别转移到相应的分支去。

BRANCH_ADDR BRANCH_ADDR SEGMENT SEGMENT ;定义数据段。;定义数据段。BRANCH_TAB BRANCH_TAB DWDW ROUTINE1ROUTINE1 ;定义数据表;定义数据表 ((跳转表跳转表 )) 。。

DWDW ROUTINE2ROUTINE2

DWDW ROUTINE3ROUTINE3

DWDW ROUTINE4ROUTINE4

DWDW ROUTINE5ROUTINE5

DWDW ROUTINE6ROUTINE6

DWDW ROUTINE7ROUTINE7

DWDW ROUTINE8ROUTINE8

BRANCH_ADDRBRANCH_ADDR ENDSENDS

Page 21: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

续:续:ROUTINE_SELECTROUTINE_SELECT SEGMENTSEGMENT ;定义代码段。;定义代码段。MAINMAIN PROCPROC FARFAR

ASSUME CSASSUME CS :: ROUTINE_SELECTROUTINE_SELECT ,, DSDS :: BRANCH_ADDRBRANCH_ADDRSTARTSTART :: PUSHPUSH DSDS ;将;将 PSPPSP 中中 INT 20INT 20 的存放地址压入栈顶。的存放地址压入栈顶。

SUB SUB BXBX ,, BXBXPUSHPUSH BXBXMOVMOV BXBX ,, BRANCH_ADDRBRANCH_ADDRMOVMOV DSDS ,, BXBXCMPCMP ALAL ,, 00 ;判;判 ALAL 中是否有置中是否有置 11 的位。的位。JEJE DONEDONE ;若;若 ALAL全零,及早退出选择结构。全零,及早退出选择结构。LEALEA BXBX ,, BRANCH_TABBRANCH_TAB ;跳转表首址送;跳转表首址送 BXBX 。。

COUTINUECOUTINUE :: SHR SHR ALAL ,, ll ;; ALAL 最低位移至最低位移至 CFCF 。。JNCJNC NOT_YETNOT_YET ;; CF=0CF=0 ,转去检查下一位。,转去检查下一位。JMPJMP WORD PTR [BX]WORD PTR [BX] ;; CF=1CF=1 ,转相应分支程序。,转相应分支程序。

NOT_YETNOT_YET : : ADD BXADD BX ,, TYPE BRANCH_TABTYPE BRANCH_TAB ;修改;修改 BXBX 内容,为转入下一分支作好准备。内容,为转入下一分支作好准备。JMPJMP COUTINUECOUTINUE ;继续检查下一选择项。;继续检查下一选择项。

DONEDONE : : RETRET ;若无选择项置位转此处,执行其它程序。;若无选择项置位转此处,执行其它程序。ROUTINE1ROUTINE1 :: ……ROUTINE2ROUTINE2 :: ………… …… RETRETMAIN MAIN ENDPENDPROUTINE_SELECT ROUTINE_SELECT ENDSENDS END END STARTSTART

Page 22: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

3.3.循环程序设计循环程序设计 常见的循环程序结构有两种:常见的循环程序结构有两种: WHILE_DOWHILE_DO 结构和结构和 DO_UNTILDO_UNTIL 结构,见图。结构,见图。

循环初始设置

循环体

循环条件判断 ?Y

N

Y

N

循环初始设置

循环体

循环条件判断 ?

当型循环(当条件成立进入循环 )

直到型循环(直到条件成立退出循环 )

Page 23: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

例:将内存的二进制数转化成以压缩的例:将内存的二进制数转化成以压缩的 BCDBCD 码形式存储的十进制数。 码形式存储的十进制数。 .MODEL.MODEL SMALLSMALL

.386.386

DATADATA SEGMENTSEGMENT

BINNUMBINNUM DDDD 12345678H12345678H ;内存中的二进制数。;内存中的二进制数。 DECINUMDECINUM DBDB 5 DUP(0)5 DUP(0) ;转化成压缩的;转化成压缩的 BCDBCD 码的存储区。码的存储区。 NUMBERNUMBER DDDD 10000000001000000000 ,, 100000000100000000 ,, 1000000010000000 ,, 10000001000000

DDDD 100000100000 ,, 1000010000 ,, 10001000 ,, 100100 ,, 1010 ,, 11 ;减数。;减数。DATA DATA ENDSENDS

CODE CODE SEGMENTSEGMENT

ASSUME ASSUME CSCS :: CODECODE ,, DSDS :: DATADATA

MAIN MAIN PROC PROC FARFAR

STARTSTART :: PUSH PUSH DSDS

MOV MOV AXAX ,, 00

PUSH PUSH AXAX

MOVMOV AXAX ,, DATADATA

MOVMOV DSDS ,, AX AX ;初始化。;初始化。 MOVMOV EAXEAX ,, BINNUMBINNUM ;将数放入;将数放入 EAXEAX 。。 MOV MOV SISI ,, OFFSETOFFSET DECINUM DECINUM ;; SISI 指向指向 BCDBCD 码存储区。码存储区。 MOV MOV DIDI ,, OFFSET NUMBEROFFSET NUMBER ;; DIDI 指向减数区。指向减数区。 MOVMOV CXCX ,, 55 ;循环;循环 55 次。次。ROTATEROTATE :: CALL CALL BINDECI BINDECI ;调用二进制转化成十进制子程序。;调用二进制转化成十进制子程序。 ADDADD DIDI ,, 88 ;; DIDI 下移两个双宇。下移两个双宇。 INCINC SISI ;; SISI 下移一个字节。下移一个字节。 LOOP LOOP ROTATEROTATE ;若;若 CX≠0CX≠0 则循环,输出下两位。则循环,输出下两位。 RETRET

MAIN MAIN ENDPENDP

Page 24: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

BINDECI BINDECI PROC NEARPROC NEAR PUSHFPUSHF PUSH PUSH CX CX ;入栈。;入栈。 MOVMOV CXCX ,, 00 ;; CXCX 存放商,初始清存放商,初始清 00 。。 CLCCLC ;清除;清除 CFCF 。。DO_AGAIN1DO_AGAIN1 :: SUB SUB EAXEAX ,, DWORD PTR[DI]DWORD PTR[DI] ;; EAXEAX 减去相应的减数。减去相应的减数。 JC JC NEXT1NEXT1 ;若不够减,则跳出循环。;若不够减,则跳出循环。 INC INC CLCL ;否则,;否则, CLCL 加加 ll (商)。(商)。 JMP JMP DO_AGAIN1DO_AGAIN1 ;继续减。;继续减。NEXT1NEXT1 : : MOV MOV CHCH ,, CL CL ;将商移入;将商移入 CHCH 。。 MOVMOV CLCL ,, 00 ;; CLCL 清清 00 。。 ADD ADD EAXEAX ,, DWORD PTR[DI]DWORD PTR[DI] ;恢复最后一次减前的值。;恢复最后一次减前的值。 CLCCLC ;清除;清除 CFCF 。。DO-AGAIN2DO-AGAIN2 :: SUB SUB EAXEAX ,, DWORD PTR[DI+4]DWORD PTR[DI+4] ;; EAXEAX 减去下一个数。减去下一个数。 JC JC NEXT2NEXT2 ;若不够减,则跳出循环。;若不够减,则跳出循环。 INC INC CLCL ;否则,;否则, CLCL 加加 11 (商)。(商)。 JMP JMP DO_AGAIN2DO_AGAIN2 ;继续减。;继续减。NEXT2NEXT2 :: ADD ADD EAXEAX ,, DWORD PTR[DI+4]DWORD PTR[DI+4] ;恢复最后一次减前的值。;恢复最后一次减前的值。

;; CHCH :: CLCL 中放的是高两位商,是非压缩的中放的是高两位商,是非压缩的 BCDBCD 码。码。;以下将它们转化成压缩的;以下将它们转化成压缩的 BCDBCD 码并放入存储单元。码并放入存储单元。

SHLSHL CHCH ,, 11 SHLSHL CHCH ,, 11 SHLSHL CHCH ,, 11 SHLSHL CHCH ,, 1 1 ;; CHCH左移左移 44 位。位。 OROR CHCH ,, CL CL ;; CHCH 中存放压缩的中存放压缩的 BCDBCD 码。码。 MOVMOV BYTE PTR[SI]BYTE PTR[SI] ,, CHCH ;放入存储区。;放入存储区。 POPPOP CXCX POPFPOPF RETRETBINDECIBINDECI ENDPENDPCODECODE ENDSENDS ENDEND STARTSTART

Page 25: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

例:将内存中以压缩的例:将内存中以压缩的 BCDBCD 码形式存储的十进制数转化成二制数 码形式存储的十进制数转化成二制数 .MODEL.MODEL SMALLSMALL

.386.386

DATADATA SEGMENTSEGMENT

BINNUMBINNUM DD 0DD 0

DECINUMDECINUM DB 12HDB 12H ,, 34H34H ,, 56H56H ,, 78H78H ,, 90H90H ;用十六进制数表示压缩的;用十六进制数表示压缩的 BCDBCD 码。码。 DATADATA ENDSENDS ;十进制数是;十进制数是 12345678901234567890 。。CODECODE SEGMENTSEGMENT

ASSUMEASSUME CSCS :: CODECODE ,, DSDS :: DATADATA

MAINMAIN PROCPROC FARFAR

STARTSTART :: PUSHPUSH DSDS

MOVMOV AXAX ,, 00

PUSHPUSH AXAX

MOVMOV AXAX ,, DATADATA

MOVMOV DSDS ,, AXAX ;初始化;初始化 MOV MOV EAXEAX ,, 00 ;; 3232 位二进制数初始值为位二进制数初始值为 00 。。 MOV MOV SI OFFSET DECINUMSI OFFSET DECINUM ;; DSDS :: SISI 指向 指向 DECINUMDECINUM 。。

MOV MOV CXCX ,, 55 ;循环;循环 55 次。次。ROTATEROTATE :: CALL CALL DECIBINDECIBIN

INC INC SISI ;; SISI 指向下一个字节指向下一个字节 LOOPLOOP ROTATEROTATE

MOVMOV DWORD PTR BINNUMDWORD PTR BINNUM ,, EAXEAX ;将;将 3232 位二进制数放入 位二进制数放入 BINNUMBINNUM 。。 RETRET

MAIN MAIN ENDP ENDP

Page 26: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

DECIBIN PROC NEARDECIBIN PROC NEAR PUSHFPUSHF PUSH PUSH ECXECX PUSH PUSH EBXEBXBEGINBEGIN :: MOV MOV ECXECX ,, 100 100 ;; ECXECX 放置乘数 放置乘数 100100 。。 MUL MUL ECXECX ;; EAXEAX 乘乘 100100 MOV MOV CHCH ,, BYTE PTR[SI]BYTE PTR[SI] ;取出一个压缩的;取出一个压缩的 BCDBCD 码到码到 CHCH 。。 MOV MOV CLCL ,, CHCH ;复制到;复制到 CLCL 。。 AND AND CLCL ,, 0FH0FH ;; CLCL 中保留低中保留低 44 位。位。 AND AND CHCH ,, 0F0H 0F0H ;; CHCH 中保留高中保留高 44 位,这时位,这时 CHCH 相当于非压缩的相当于非压缩的 BCDBCD 码码 *16*16 。。 SHR SHR CHCH ,, 11 ;算术右移;算术右移 11 位,相当于非压缩的位,相当于非压缩的 BCD BCD 码乘码乘 88 。。 MOV MOV BHBH ,, CHCH ;移入;移入 BHBH暂时保存。暂时保存。 SHR SHR CHCH ,, 11 ;再算术右移;再算术右移 11 位。位。 SHR SHR CHCH ,, 11 ;再算术右移;再算术右移 11 位,相当于非压缩的 位,相当于非压缩的 BCDBCD 码乘码乘 22

ADD ADD CHCH ,, BHBH ;相当于非压缩的;相当于非压缩的 BCDBCD 码乘码乘 1010 。。 ADD ADD CLCL ,, CHCH ;加到;加到 CLCL 上。上。 MOV MOV CHCH ,, 00 ;; ECXECX 保存两位保存两位 BCDBCD 码转化成二进制数的结果。码转化成二进制数的结果。 ADD ADD EAXEAX ,, ECXECX ;加到;加到 EAXEAX 上去。上去。 POPPOP EBXEBX POPPOP ECXECX POPFPOPF RETRETDECIBIN DECIBIN ENDPENDPCODE CODE ENDSENDS END END START START

Page 27: 宏指令及其使用 宏指令、宏定义和宏调用 宏指令 源程序中具有独立功能的一段程序代码 宏定义 宏指令名 MACRO < 形式参数 > … ;

DSEGDSEG SEGMENTSEGMENT ADDR ADDR DW N DUP(?)DW N DUP(?)DSEGDSEG ENDSENDSCSEGCSEG SEGMENTSEGMENTMAINMAIN PROCPROC FARFARSTARTSTART :: PUSHPUSH DSDS SUBSUB AXAX ,, AXAX PUSHPUSH AXAX MOVMOV AXAX ,, DSEGDSEG MOVMOV DSDS ,, AXAX MOVMOV CXCX ,, NN ;内循环变量存于;内循环变量存于 CXCX 中,初值为中,初值为 N-lN-l 。。 DECDEC CXCXLOOP1LOOP1 :: MOVMOV DIDI ,, CXCX ;外循环变量存于;外循环变量存于 DIDI 中,初值为中,初值为 N-lN-l 。。 MOVMOV BXBX ,, 00 ;地址指针预置为;地址指针预置为 00 。。LOOP2LOOP2 :: MOVMOV AXAX ,, ADDR[BX]ADDR[BX] ;取相邻两数比较。;取相邻两数比较。 ADDR[BX]ADDR[BX] CMPCMP AXAX ,, ADDR[BX+2]ADDR[BX+2] JGEJGE COTINUM COTINUM ;若符合排列次序,转移。;若符合排列次序,转移。 XCHGXCHG AXAX ,, ADDR[BX+2]ADDR[BX+2] ;若不符合排列次序,二数交换。;若不符合排列次序,二数交换。 MOVMOV ADDR[BX]ADDR[BX] ,, AXAX ;存大数。;存大数。COTINUECOTINUE :: ADDADD BXBX ,, 22 ;修改地址指针。;修改地址指针。 LOOPLOOP LOOP2LOOP2 ;若一遍未比较完,继续。;若一遍未比较完,继续。 MOVMOV CXCX ,, DIDI LOOPLOOP LOOP1LOOP1 ;若;若 N-lN-l遍未作完,继续。遍未作完,继续。 RETRETMAIN MAIN ENDPENDPCSEG CSEG ENDSENDS ENDEND START START

气泡排序算法气泡排序算法