如图,labc=50度,labd=140度,如图be平分角abdlabc.be

 上传我的文档
 下载
 收藏
野村水母直径超2米,世界最大水母竟是吃货。 野村水母直径超2米 世界最大水母竟是吃货
 下载此文档
正在努力加载中...
(精选)证两次相似解平面几何竞赛题
下载积分:999
内容提示:(精选)证两次相似解平面几何竞赛题
文档格式:PDF|
浏览次数:1|
上传日期: 00:53:55|
文档星级:
该用户还上传了这些文档
(精选)证两次相似解平面几何竞赛题.PDF
官方公共微信平面基本图形浅说——初一数学竞赛系列讲座(7)
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
平面基本图形浅说——初一数学竞赛系列讲座(7)
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口用中考的眼光审视相似三角形的教学8ε8,п8ε
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
用中考的眼光审视相似三角形的教学
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口第7章7.1微型计算机汇编语言及汇编程序宏汇编语言的基本语法7.27.3 7.4 7.5 7.6 习题伪指令宏指令 系统功能调用 汇编程序的功能及汇编过程 汇编语言程序设计1/200 汇编语言和机
器语言相比, 使用汇编语言来编写程序的突出优点就是可以使用符号;具体地说, 就是可以用助记符来表示指令的操作码和操作数, 可以用标号和符号来代替地址、常量和变量。助记符一般都是表示一个操作的英文字母的缩写, 很便于识别和记忆。不过, 用汇编语言编写的程序不能由机器直接执行, 而必须翻译成由机器代码组成的目标程序, 这个翻译过 程称为汇编。在微型机中, 当前绝大多数情况下, 汇编过程是 通过软件自动完成的。用来把汇编语言编写的程序自动翻译成 目的程序的软件叫汇编程序。汇编过程的含义如图7.1所示。 2/200 用汇编语言编写的程序叫源程序。前面讲的指令系统中的每 条指令都是构成源程序的基本语句。汇编语言的指令和机器语言 的指令之间有一一对应的关系。所以,汇编语言是和机器密切相关的,是面向机器的语言,CPU不同的机器有不同的汇编语言。采用汇编语言进行程序设计时, 我们可以充分利用机器的硬件功能和结构特点, 从而可有效地加快程序的执行速度, 减小目标程序所占用的存储空间。因此, 与高级语言相比, 汇编语言为我们提供了直接控制目标代码的手段, 而且可以对输入/输出端口进行控制, 实时性能好, 执行速度快和节省存储空间等明显优点。所以, 汇编语言大量被用于编写 计算机系统程序、实时通信程序、实时控制程序等。 3/200 , 8系统的汇编程序完全相同, 简称作ASM-86 (Assembler) 。在此基础上进一步扩展其功能, 成为当前广泛使用的8086宏汇编程序, Assembler) 。 汇编程序以汇编语言源程序文件作为输入,并由它产生两种输 出文件:目标程序文件和源程序列表文件。 简称作MASM-86 MASM (Macro4/200 编辑程序. ASM 文件汇编程序. OBJ 文件连接程序. EXE 文件Edit 等MASMLINK汇编语言程序的建立和汇编过程 在计算机上运行汇编语言程序的步骤是: ?用编辑程序(任何一种文本编辑程序)建立ASM文件;?用MASM程序把ASM文件转换成OBJ文件;?用LINK程序把OBJ文件转换成EXE文件;?用DOS命令直接键入文件名就可执行该程序; 5/200 7.1 宏汇编语言的基本语法7.1.1 伪指令语句格式 它与指令语句不同, 伪指令语句(又叫命令语句)中的伪指令本身不产生对应的机器目标代码。它仅仅是告诉汇编程 序, 对后面的指令语句和伪指令语句的操作数应该如何产生 机器目标代码。每一条伪指令语句共分4个字段, 格式如图7.2所示。 它的指令图7.2 6/200 1. 标号名字段 这是一个任选字段。标号名后面不能用冒号“: ‖, 这是 它与指令语句的突出区别。不同的伪指令, 标号名可以是常 量名、变量名、过程名、结构名、记录名等。它们可以作 为指令语句和伪指令语句的操作数, 这时, 标号名就表示一个常量或存储器地址。2. 伪指令字段 这是伪指令语句不可省略的主要成分。伪指令种类很多, 如定义数据伪指令DB, DW, DD;段定义伪指令SEGMENT; 定义过程伪指令PROC;…。它们是伪指令语句要求汇编程 序完成的具体操作命令。 7/200 3. 操作数字段 本字段是否需要, 需要几个, 需要什么样的操作数等都由 伪指令字段中伪指令来确定。操作数可以是一个常数(二进 制、十进制、十六进制等)、字符串、常量名、变量名、标号、一些专用的符号(如BYTE, FAR, PARA等)。4. 注释字段这是一个任选字段, 它必须以分号为开始, 它的作用与指令语句的注释字段相同。8/200 7.1.2 常数、变量和标号常数、变量和标号是汇编语言能识别的数据项, 它是指令 和伪指令语句中操作数的基本组成部分。一个数据项包含有 它的数值和属性两部分, 这两部分对一条语句汇编成机器目 标代码都有直接关系。 1. 常数 常数是没有任何属性的纯数值。在汇编期间, 它的值已能 完全确定, 且在程序运行中, 它也不会发生变化。它可以有 以下几种类型: (1) 二进制数: 以字母B结尾的, B。 由0和1组成的数字序列, 如(2) 八进制数: 以字母O或Q结尾的0~7数字序列, 如723Q, 35Q。 9/200 (3) 十进制数: 0~9数字序列, 可以用字母D结尾, 也可以没有结尾字 母, 如129, 129D。 (4) 十六进制数: 以字母H结尾, 由数字0~9和字母A~F(或a~f)组成 的序列, 如3A5BH, 0FH。为了区别由A~F组成的是一个十六进 制数还是一个标识符, 凡以字母A~F为起始的一个十六进制数,必须在前面冠以数字“0‖, 否则汇编程序认作标识符。(5) 实数: 它由整数、小数和指数3部分组成, 这是计算机中的浮点 表示法。实数一般用十进制数形式给出, 实数的格式如下:±整数部分?小数部分E±指数部分其中, 整数和小数部分形成这个数的值, 称作尾数, 它可以是带 符号的数。指数部分由指数标识符E开始, 它表示了值的大小, 如 5.213E-4。 10/200 (6) 字符串常数: 用引号括起来的一个或多个字符。这些字符 以ASCII码形式存储在内存中。如“AB‖, 在内存中就是41H, 42H。在程序中, 常数主要出现在: (1) 指令语句中源操作数中作立即数, 它应与目的操作数的位 数相一致, 可以是8位或16位, 例如: MOV AX, 0A5F1H(2) 在指令语句的基址加变址的寻址方式中作位移量, 例如: MOV BX, [SI+32H]11/200 (3) 在数据定义伪指令中, 例如: DB 12H ; 定义一个字节数据DWDD DB1234H; 定义一个字数据; 定义一个双字数据H'ABCD'; 定义4个字节的字符串数据12/200 2. 变量 变量是代表存放在某些存储单元的数据, 这些数据在程序运行期间随时可以修改。为了便于对变量的访问, 它常常以变量名的形式出现在程序中, 它可以认为是存放数据存储单元的符号地址。(1) 变量的定义与预置: 定义变量就是给变量分配存储单元, 且对这个存储单元赋于一个符号名——变量名, 同时将这些存储单元预置初值。13/200 定义数据的伪指令DB, DW, DD , DQ和DT, 此伪指令用来定义存储 空间以及存储的长度。 格式: [&变量&] &助记符& &数据1&, …, &数据n& [;&注释&] &变量&代表&数据1&所在存储单元的偏移地址(称为符号地址); &助记符&可以是: DB 定义字节, 此时每个数据占一个字节。 DW 定义字, 此时每个数据占一个字(两个字节)。 DD 定义双字, 此时每个数据占两个字(四个字节)。 DQ 定义八个字节, 此时每个数据占八个字节。 DT 定义十个字节, 此时每个数据占十个字节; &数据&可以是各种形式的数据或地址, 也可以是预留的空存储单元。 如果所定义的存储区存放同样的数据时,可采用操作符DUP。 如果仅定义存储器区域而不放数据, 则以?表示。 14/200 例如: DATA DB 26H, 37H, 0AH, 9FH ; 表示在DATA开始的四个单元中存放了26H, 37H, 0AH, 9FH四个字节的十六进制数。表示在DATA开始的三个单元中存放了A、B、DATADB 'A', 'B', 'C' ;C三个字节的ASCII码。DATA DW 26H, 0AF5H, 9FBDH ; 表示在DATA开始的六个单元中存放了0026H, 0AF5H, 9FBDH三个字的十六进制数。 DATA DB ? ; 表示在DATA开始的一个单元中为随机数, 通常作为程序的工作单元。 BUFFER DB 100 DUP(?) ; 表示BUFFER为100个字节的存储空间。其内容为随机数, 通常作为程序的工作单元。 15/200 例如:VAR-DATA DATA1 DATA2 DATA3 DB DB DW SEGMENT 12H 34H 5678HVAR-DATAENDS经过定义的变量, 每个变量均有3个属性: ① 段属性(SEG): 表示变量存放在哪一个逻辑中(即变量所在段的 ③ 类型属性(TYPE): 表示变量占用存储单元的字节数。这一属性是 ② 偏移量属性(OFFSET):表示变量在逻辑段中离段起始点的字 段基值。例如, 变量名为DATA1, 为 0, 而 DATA2 的 偏 移 量 为 1, 节由数据定义伪指令DB, 的 偏 移 量 DATA2, DATA3的3个变量都 数 。 如 , 变 量 DATA1 DW, DD来规定的。变量DATA1, DATA2 存放在VAR-DATA逻辑段中(用SEGMENT/ENDS伪指令定义一 DATA3的偏移量为2。 个逻辑段)。当在指令中要对这些变量进行存取操作时, 事先要 上述段和偏移量两个属性就构成了变量的逻辑地址。 类型属性为字;如果用DD定义, 类型属性为双字。 把它们所在段的段基值存放在某一个段寄存器(如DS)中。 16/200是用DB定义的,它的类型属性为字节;而DATA3是用DW定义的, (2) 数据定义伪指令:这种伪指令主要为数据项分配存储单元并预置初值。由这种伪指令构成的语句格式是: DB 变量名 DW 表达式1, 表达式2, … DD 其中表达式1, 表达式2, …是给变量赋予的初值。表达式可以有如下几种情况:① 数值表达式。例如: DA_BYTE DB 50H, 50DA_WORDDW0A3F1H, 4981HDA_WORD字单元内容为0A3F1H变量DA_BYTE的内容为50H,它的下一个字节为32H(即DA_BYTE+1 字节单元的内容为十进制50). DA_WORD+2字单元)。 17/200(低字节为F1H,高字节为0A3H)它的下一字单元内容为4981H(即 ? 为数据段分配存储单元。? DATA SEGMENT? A ? B ? C DB DW DD 11H, 12H, 13H 1122H, 78H? DATA ENDS ? 上述变量的存储单元分配 及初始化情况如下图所示。数据段中 数据存储分配图18/200 ? 【练习】已知一数据段中的数据为:? DATA? ASEGMENTDW 000CH? BUF DB 'AB',0DH,0AH ? B ? M DW 0FFAAH DB 2DUP(1) ,2DUP(2,'B')? DATAENDS? 请画出该数据段数据存储的形式。该数据段在主存中的存储形式 19/200 ② ?表达式: 不带引号的?表示可预置任何内容。例如:DA_BDA_WDBDW?, ??, ? 第2条语句第1条语句是要求汇编程序分配两个字节单位,是要求分配两个字单元。这些单元里现在可以是任意值。20/200 ③ 字符串表达式: 对于DB伪指令, 为字符串中每一个字符分配 一个字节单元。字符串必须是用单引号或双引号引起来的一 个 或 多 个 且 不 超 过 255 个 字 符 。 字 符 串 自 左 至 右 以 字 符 的 ASCII码按地址递增的排列顺序依次存放。如'A'用41H 表示, 字符串'A1B2'用41H, 31H, 42H, 32H表示。如 STRING1 DB ′ABCDEF′21/200 附: ASCII 码 对 照 表 十 进 制 65 | 90? 二进制B十进制D 十六进制H65 41字符A00 01 00 006667 68 69 70 71 724243 44 45 46 47 48BC D E F G H22/200 ? 二进制B十进制D 十六进制H字符附: ASCII 码 对 照 表 十 进 制 65 | 9000 00 7374 75 76 77494A 4B 4C 4DIJ K L M01 01 7879 80 81 824E4F 50 51 52NO P Q R23/200 附: ASCII 码 对 照 表 十 进 制 65 | 90? 二进制B 01 01 01 0111十进制D 十六进制H 83 84 85 86 87 53 54 55 56 57字符 S T U V W88895859XY905AZ24/200 ?Bin Dec 48Hex 30字符 0 (零)附: ASCII 码 对 照 表 字符 0 | 911 00114950 513132 3312 311 11 5253 54 55 563435 36 37 3845 6 7 85739925/200 对于DW伪指令, 可以给两个字符组成的字符串分配两个字节存储单元, 而且这两个字符ASCII码的存储顺序是前一在高字 节, 后一字符在低字节, 每一个数据项不能多于两个字符。例如:STRING2 DW ′AB′, ′CD′, ′EF′在存储器中存放的情况如图7.3(b)所示。26/200 例:ORG8000H ;源程序的起始地址为8000H7234H,8AH,10TAB:DW汇编后: (8000H)= 34H(8001H)= 72H (8002H)= 8AH (8003H)= 00H (8004H)= 0AH (8005H)= 00H注: 起点指令 ORG --- 给程序或数据块的起始地址赋值 27/200 对于DD伪指令, 仅可给两个字符组成的字符串分配4个字节单元, 且这两个字符ASCII码是存储在两个低字节(存储 顺序与DW伪指令相同)中, 两个高字节均存放00H。例如: STRING3 DD′AB′, ′CD′ 在图7.3(c)显示了它们存储器中的存放情况。28/200 ? 为字符串分配存储单元。? DATA SEGMENT? STR1 DB '1234'? STR2? STR3DWDD'AB', 'CD', 'A''AB'? DATA ENDS ? 其存储单元分配如图所示。 数据段存储分配图 29/200 汇编程序在对源程序进行汇编时, 是使用一个“地址计数器”来保存指令和变量的地址的。通常, 在汇编语言源程序中, 地址计数器的值用符号“$‖来表示。编写程序时, 用户可以直接使用$来引用地址计数器的当前值。例假定进行汇编时, 为 VARW 分配的偏移地址为0074H.那么 VARW DW 1, 2 , $+4 , 3 , 4 , $+4该存储区的存储情况如何?30/200 VARWDW 1, 2, $+4 , 3 , 4 , $+4解: 由于VARW分配的偏移地址为0074H, 所以在把数据1和2分别存储在0074H和0076H后, 第3个数据应该存放在0078H开始的字单元中。第3个数据是$+4, 即是把地址计数器的当前值$加4后进行存储。此时, $是0078H, 7CH,故第3个数据是007CH。即是把007CH存储在0078H开始的字单元中。再往下继续存放, 最后是把007EH+4H=0082H存放在007EH开始的字单元中。31/200 练习:有如下定义TABLE1 DD 0,1,2,3TABLE2DB 30H, 31H, 32H, 33H则,判断下列三条指令是否正确: 1. MOV AX, TABLE1 2. MOV BX, TABLE2 3. MOV AX, WORD PTR TABLE1? ??32/200 ④ 带DUP表达式: DUP是定义重复数据操作符。在表达式中, DUP操作符格式是: 变量名 DB DW DD 表达式1 DUP (表达式2)使用其中表达式1是重复的次数, 表达式2是重复的内容。例如:D_B1 D_B2 D_W1 DB DB DW 20H 10H 10H DUP(?) DUP(′ABCD′) DUP(4)第1语句表示保留20H个字节, 每个字节可预置任意内容。第2语句是重复10H个字符串“ABCD‖, 共占有40H个字节。第3语句是重复10H个字单元, 每个单元预置为4, 共占有20H个字节 33/200 例题ARRAY1 DB 2 DUP(0, 1, 2, ?) ARRAY2 DB 100 DUP(?) 第1个语句表示把括号内的操作数0, 1, 2和?依次重复定义两次, 而第2个语句表示要预留出100个空的字节单元。其存储情况如下图(a)所示。注意: DUP后括号内所列出的&数据&里面, 仍可以使用 DUP, 从而形成对 DUP 的嵌套使用。34/200 ④ 带DUP表达式: DUP是定义重复数据操作符。例 ARRAY3 DB 100 DUP(0, 2 DUP(1, 2), 0, 3)的存储情况如下图(b)所示。35/200 3. 标号: 标号是一条指令目标代码的符号地址, 它常作为转移指令(含子程序调用指令)的操作数。与变量类似, 每个标号亦具有 3个属性: (1)段属性(SEG): 表示这条指令目标代码在哪个逻辑段中。 (2)偏移量属性(OFFSET): 表示这条指令目标代码的首字节在段内 (3) 距离属性: 表示本标号可作为段内或段间的转移特性。距离属离段起始点的字节数。 性分为两种: ① NEAR(近): 本标号只能被标号所在段的转移和 如 MOV BX OFFSET COUNT;把COUNT这个变量的偏移地 调用指令所访问(即段内转移);② FAR(远): 本标号可被其他段 址送给BX这个寄存器。(不是标号所在段)的转移和调用指令访问(即段间转移)。 同样, 上述两个属性构成了这条指令目标代码首字节的逻辑 地址。 36/200 7.1.3 表达式与运算符表达式由操作数和运算符组成, 在汇编时一个表达式得到一个 值。下面结合运算符讲述表达式。 用一个运算符可以对一个操作数或几个操作数进行运算, 这就 构成了一个表达式, 从而得到一个新的值。ASM?86中分6类运 组合运算符和分离运算符, 它们在汇编时完成相应运算。 1. 算术运算符 +, –, *, /是加减乘除运算符。算符, 包括算术运算符、逻辑运算符、关系运算符、分析运算符、MOD是除法取余运算符。例如, 32 MOD 5=2。SHL是左移操作符。例如, 21H SHL 2=84H。 SHR是右移操作符。 37/200 例: 用算术运算符进行数值表达式运算。 ┆ NUM1 EQU NUM2 EQU 25*4 –50 NUM1 / 7 1, 2, 3, 4, 5 '12345' ; NUM5=0FH ; NUM1=50 ; NUM2=7NUM3 DBVAR1 VAR2 DB DBNUM1 MOD 7; NUM3=1WhyNUM4 EQU VAR2–VAR1 ; NUM4=? 5NUM5 EQU 0FH ┆MOV AL, NUM5 SHL 4 ; (AL)=BMOV BL, NUM5 SHR 4; (BL)=B38/200 OPER1 DB 1, 2 OPER2 DW 1234H, 5678H …… MOV AX, OPER1+1 MOV AL, OPER2如何改正?OPER1Memory 01H 02H 34H 12H 78H 56H… …× 类型不匹配OPER2改正: MOV AX, WORD PTR OPER1+1(AX)=?3402H 34H (AL)=?MOV AL, BYTE PTR OPER21. 存储区的存储情况如何?2. 在求解AX和AL的过程中,OPER1和OPER2扮演了什么角色?&变量&代表&数据1&所在存储单元的偏移地址(称为符号地址); 39/200 MemoryVAR1 DB1, 2, 3, 4, 5VAR101H 02H 03H 04HVAR2 DB'12345'NUM4 EQU VAR2–VAR1VAR205H 31H 32H 33H 34H 35H…NUM4=?…40/200 2. 逻辑运算符 AND是逻辑“与”操作符。例如, 24H AND 0FH=04H。 OR是逻辑“或”操作符。例如, 24H OR 0FH=2FH。 XOR是“异或”操作符。例如, 24H XOR 0FH=2BH。 NOT是逻辑“非”操作符。例如, NOT 24H=0DBH。 ? 【例】用逻辑运算符进行运算。? MOV? MOV ? MOV ? MOVAL, 34H AND 0FHBL, 05H OR 30H CX, NOT 00FFH ;;;04H ? →AL35H ? →BL0FF00H ? →CX;DX, 789AH XOR 000FH7895H? →DX41/200 3. 关系运算符关系运算是逻辑判定式的, 当为“真”时结果取0FFFFH, 当为“假”时结果取0。关系运算是数值型的。EQ等于。 例如, 已赋给符号PP为25, 则25 EQ PP= 0FFFFH。NE不等于。例如, 25 NE PP=0。 LT小于。例如, 25 LT 26=0FFFFH。 LE小于等于。例如, 25 LE PP=0FFFFH。 GT大于。例如, 26 GT 25=0FFFFH。 GE大于等于。例如, 24 GE PP=0。42/200 3. 关系运算符? 【例】用关系运算符进行数值表达式运算。? NUM1 DB 10 LT 5? NUM2 DB 0AAAAH GT 7FFFH ? MOV AX, ' A' EQ 41H ? MOV;NUM1= ?;NUM2= ?0 0FFFFH; 0FFFFH ?→AXBX, NUM2 LT NUM1 ;0?→BX43/200 4. 分析运算符(1) SEG求段基址格式: SEG〈符号名〉;功能: 分离出其后变量或标号所在段的段首址。例如:MOV MOV AX, SEG ARR DS, AX44/200 4. 分析运算符(2) OFFSET求偏移地址 格式: OFFSET〈符号名〉;功能: 分离出其后变量或标号的偏移地址。 例如: MOV BX, OFFSET BUF 例如, 定义FIVE为数据5, FIVE EQU 5 则 1、指令 MOV AX, FIVE ;表示将数值5送入AX寄存器。 2、指令 MOV AX, SEG 段地址送入AX寄存器。 FIVE ; 表示将数值5所在的段的3、 指令MOV AX, OFFSET的偏移地址送入AX寄存器。FIVE ;表示将数值5在该段中45/200 (3) TYPE求符号名类型值 格式: TYPE〈符号名〉 符号名类型表见159页表7-1. (4) SIZE求为符号名分配的字节数 格式: SIZE〈符号名〉为符号名定义的数据项必须是用重复格式DUP()定义的。 (5) LENGTH求为符号名分配的项数 格式: LENGTH 〈符号名〉 为符号名定义的数据项必须是用重复格式DUP()定义的。 LENGTH和SIZE分别给出分配给一个变量的单元数和字节数。 SIZE〈符号名〉=(LENGTH〈符号名〉)*(TYPE〈符号名〉)即对于一个变量, 其总字节数(SIZE)等于单元数(LENGTH)与字节数(TYPE)的乘积。 46/200 练习: 请问, 下面三条语句分别是什么含意。 1、 TABLE DW 100H DUP(0)将TABLE定义为100H个字的数据, 其内容为0。 2、 MOV CX, LENGTH TABLE 将分配给变量TABLE的单元数100H赋值给寄存器CX。 3、 MOV CX, SIZE TABLE将分配给变量TABLE的字节数200H赋值给寄存器CX。47/200 5. 组合运算符组合运算符是用来改变或建立符号名的新类型。(1) 定义符号名为新类型 格式: 〈类型〉PTR〈符号名〉 mov ax,设内存变量D1是字节属性, 把它的两个字节内容送到 例如,是把BX寄存器“里”的值赋予AX, 由于二者都 AX中。 是word型, 所以没有必要加“WORD‖;MOV AX, WORD PTR D1 mov ax, word ptr [bx];是把内存地址等于“BX寄存器的值”这里的符号名可以是间址、变址寻址、基址加变址寻址表示 的地方所存放的数据, 赋予ax。由于只是给出一个内存地址, 的存储器操作数。 不知道希望赋予ax的, 是byte还是word, 所以需要用word ptr明确指出!即当两个操作数的位数不一样时, 要用ptr指明。如Y被定义为字, 而在使用时只用作字节, 则具体的语句为: MOV DL, BYTEPTRY48/200 例 有如下的数据伪指令:TWOB DW ?ONEB DB ?它们使名为 TWOB 符号地址的类型属性为字, 使名为 ONEB 符号地址 的类型属性为字节。 通过下面使用PTR操作符进行的定义: VARB EQU BYTE PTR TWOBVARW EQU WORD PTR ONEB 这就使得VARB与TWOB两个符号地址具有相同的段地址及偏移地址, 但它们的类型属性不同: TWOB的类型属性为字, 而VARB的类型属性为字节。同样VARW和ONEB两符号地址具有相同的段地址及偏移地址, ONEB 的类型属性是字节, 而VARW的类型属性是字。 49/200 例VAR1 EQU BYTE PTR VAR2VAR2 DW 0ABCDH┋VAR1与VAR2两个符号地址SHL VAR1, 1 ;字节操作 SHR VAR2, 1 ;字操作具有相同的段地址及偏移地址请问, 执行上述两条指令后VAR2字单元的内容是 55CD H50/200 练习:1、OPER1 DB 10H,21H,30H,45HMOVAX,WORD PTR OPER1+2请问, 执行上述两条指令后AX = 4530 H 2、有如下定义:SUM DB 12H , 80HTAB DW 1234H 1). MOV AX,WORD PTR SUM 汇编后: MOV AX, 8012 H 2). MOV BH,BYTE PTR TAB汇编后: MOV BH,34H51/200 (2) 指定新类型,与PTR类似, 可为某个符号名建立新类型。THIS产生一个新的变量或标号, 其地址等于当前地址, 类型在THIS中 指定。(THIS不分配存储器)。 格式: THIS〈类型〉例如:LABC EQU THIS BYTELABD DW 4321H, 2255HMOV AL, LABC ;AL=21H MOV AX, LABD ;AX=4321H 符号名LABC与LABD有相同的段地址和偏移地址, 但LABC是字节类型, 而LABD是字类型。 52/200 6. 分离运算符 (1) LOW取低字节 格式: LOW〈表达式〉(2) HIGH取高字节例如: 设 SSY=2050H MOV MOV MOV AL, LOW格式: HIGH〈表达式〉3080H;AL=80H ;AH=20H ;CL=4BHAH, HIGH SSY CL, LOW 3A4BH53/200 7. 汇编运算符的优先级 见表7.2(课本第160页)所示。54/200 7.2 伪指令伪指令本身不会产生可执行的机器指令代码, 它仅仅是告诉汇编程序有关源程序的某些信息, 或者用来说明内存单元的用途。伪指令在汇编过程中由汇编程序进行处理。 伪指令没有对应的机器指令, 它不是由86系列CPU来执行, 而是 由MASM-86识别, 并完成相应的功能。它在很大程度上规定了MASM-86的性能, 因此也可称之为汇编命令。 MASM-86中允许使用的伪指令相当丰富, 令的功能及其用法, 必须搞清楚这些伪指才能编制出高质量的汇编语言源程序。MASM-86中使用的伪指令可分成14类, 下面逐一进行介绍。 55/200 汇编伪指令和汇编语言指令的区别 :[指令语句] 每一条指令语句在源程序汇编时都要产生可供计算机执行的指令代码(即目标代码), 所以这种语句又叫可执行 如数语句。每一条指令语句表示计算机具有的一个基本能力,据传送, 两数相加或相减, 移位等, 而这种能力是在目标程序 (指令代码的有序集合)运行时完成的, 是依赖于汁算机内的中央处理器(CPU)、存储器、I/O接口等硬件设备来实现的。56/200 [伪指令语句] 伪指令语句是用于指示汇编程序如何汇编源程序,所以这种语句又叫命令语句。例如源程序中的伪指令语句告诉汇编程序: 该源程序如何分段, 有哪些逻辑段在程序段中哪些是当前段, 它们分别由哪个段寄存器指向;定义了哪些数据, 存储单元是如何分配的等等。伪指令语句除定义的具体数据要生成目标代码外, 其他均没有对应的目标代码。伪指令语句的这些命令功能是由汇编程序在汇编源程序时, 通过执行一段程序来完成的, 而不是在运行目标程序时实现的。 57/200 1. 符号定义伪指令(赋值语句)(1)赋值伪指令(2)等号(=)伪指令〈名字〉EQU〈表达式〉〈名字〉=〈表达式〉该语句把表达式的值赋给符号名,在同一程序中,用EQU语句赋值的符号名不能被重新赋值, 用“=”号赋值的符号名可以被重新赋值。“〈〉‖号表示此项不能默认, 但该符号不需输入。操作说明: 表达式可以是一个常数、符号、数值或地址表达式 需要注意的是: EQU伪指令不允许对同一符号重复定义。58/200 1. 符号定义伪指令(赋值语句)EQU伪指令具体应用举例如下:CR EQU ODH ;定义CR为常数(回车的ASCII代码)TAB EQU TABLE-ASCIIDIS EQU ;定义变量;定义数值表达式ADR EQU ES: [DI+3]M EQU MOV;定义地址表达式;定义助记符59/200 例 COUNT EQU 256;赋予数256一个名字, 叫做COUNT。; 赋予表达式COUNT-2一个名字, 叫做VAR1 EQU COUNT-2VAR1。如果有“COUNT EQU 256‖在先,那么由于COUNT 是数值256, 所以VAR1就代表数值254。PH EQU PUSH ;赋予PUSH一个名字PH。由于PUSH是汇编语言助记符, 因此, 在程序中书写PH AX, 就相当于 PUSH AX。60/200 2. 内存数据定义伪指令(1) 字节定义伪指令:[名字]DB〈表达式或数据项表〉表达式值或项表中的每一项是一个字节数, 它们从符号名地址开始按字节连续存放, 直到表中数据项结束(地址递增方向)。方括号[]表示该项可以默认。 (2) 字定义伪指令: [名字]DW〈表达式或数据项表〉除表达式值或项表中的每一项是两个字节数之外, 其它与DB 伪指令相同。61/200 (3) 4字节定义伪指令: [名字]DD〈表达式或数据项表〉表达式值或项表的每一项是4个字节数, 该语句可以定义有小数点的十进制数或用科学表示法表示的数据, 此时在汇编时被译成4字节浮点数, 尾数在低地址一端, 阶码在高地址一端。浮点数格式见7.1节中所述。例如:N1 DD 25ABH, 0A002677HN2DD2.5, 3.2E+262/200 (4) 8字节定义伪指令: [名字]DQ〈表达式或数据项表〉 表达式值或数据项表的每一项是8字节数, 各项从小地址一端连续存放, 允许浮点数形式, 与DD伪指令相同。高4个字节填0。 (5) 10字节定义伪指令: [名字]DT〈表达式或数据项表〉 表达式值或数据项表的每一项是10字节数, 允许浮点数形式, 与DQ伪指令相同;若项表中的数据项是十进制整数书写 的, 汇编程序按组合的BCD码格式存放, 最低字节在高地址 一端存放, 数据的最高字节的最高位是符号位, ―0‖表示正,―1‖表示负。 63/200 (5) 10字节定义伪指令: [名字]DT〈表达式或数据项表〉 表达式或数据项表多于一项时, 项与项之间用逗号“, ‖或空格分隔, 表达式或数据项重复书写时, 可用重复格式简写。例如: 在指令中引用上述定义的符号名时, 必须考虑符号名的类型, 否则会出现错误提示。例如: MOV MOV AX, D1 ; D1类型错误 ;正确AX, WORD PTR D164/200 3.段定义伪指令: 在汇编语言源程序中定义逻辑段。常用的段定义伪指令有ASSUME、SEGMENT和ENDS等。存储器在逻辑上是分段的, 各段的定义由伪指令实现。 ? SEGMENT和ENDS伪指令用于定义一个逻辑段, 给逻辑段赋 予一个段名, 并在后面的任选项中给出这个逻辑段的其他特性, 如定位类型、组合类型和类别。65/200 段定义伪指令格式如下:格式: 〈段名〉SEGMENT [定位方式] [连接方式] ['类别名'] … 〈段名〉ENDS说明: SEGMENT伪指令定义一个逻辑段的开始, ENDS伪指令 则表示一个逻辑段的结束, 这两个伪指令总是成对出现, 而且 前面的段名必须一致。两个伪指令语句之间的部分是该逻辑 段的内容。汇编语言的逻辑段包括代码段、数据段和堆栈段 等。代码段主要是程序指令和某些伪指令;数据段用于定义数据和存储单元;堆栈段为堆栈操作预留出存储空间。 66/200 (1) 定位方式(定位类型): 定位方式指定段的起始地址边界, 方式有4种PAGE—指定起始地址的低8位是0, 即其值能被256整除(称为页边界)PARA—指定起始地址的低4位是0, 即其值能被16整除(称为段边界)。 这是系统隐含定位方式。 WORD—指定起始地址的最低位是0, 即其值能被2整除(称为字边界), 也就是该逻辑段的起始地址必须是偶数。 BYTE—指定起始地址是任意值, 即逻辑段边界可以从任何一个字节 开始, (称为字节边界)。 67/200 以上4种边界如下所示:×××××××× ×××× ×××××××××××× ×××× ×××××××××××× ×××× ××××0 0 0 0×××× ×××× ××××0 0 0 00 0 0 0 ××× 0 ××××PAGEPARA WORD BYTE68/200 (2) 连接方式(组合类型): 连接方式告诉连接程序本段与其他段可按某种方式连接, 它有6种选择。①PUBLIC—告诉连接程序把本段与其他同名同类别的段连接起来,公用一个段的起点地址, 形成一个物理段, 即汇编程序连接时,将不同程序模块中具有相同的类别名的逻辑段顺序连接成一 个逻辑段装入内存 。②STACK—表示本段是堆栈段, 即编译程序把所有同名段连接成一个连续的堆栈段。连接方式同PUBLIC, 连接后的段起始地址在SS寄存器中。连接程序要求源程序至少要有一个堆栈段, 否则提示错误, 此时, 系统取约定堆栈段值。 69/200 ③空缺(NONE)—表示本段不与任何段连接, 这是系统隐含连接方式④COMMON—该组合类型产生一个覆盖段。模块连接时,如果有相同的类别名, 则都从同一个地址开始装入, 因而连接的逻辑段将发生重叠。连接以后段的长度等于原来最长的逻辑段的长度, 重叠部分的内容是最后一个逻辑段的内容。⑤MEMORY—表示本段在连接时定位在所有段之上, 即高地址处⑥AT表达式—表示本段定位在表达式值指定的段地址处。如:AT 0830H;本段的地址从0830H开始。70/200 【例】有两个模块, 各模块段定义如下: ? 模块1: ┆ DATA1 SEGMENT PARA PUBLIC 'DATA1' M1 DB 45H DUP(0)DATA1 ENDSDATA2 SEGMENT PARA COMMON 'DATA2'N1 DB 102H DUP(0)DATA2 ENDSEND 71/200 ? 模块2: ┆ DATA1 M2 DATA1 DATA2 N2 SEGMENT PARA PUBLIC 'DATA1' DB 104H DUP (11H) ENDS SEGMENT PARA COMMON 'DATA2' DB 105H DUP(0)DATA2ENDSDATA3 SEGMENT T1 DB 50 DUP(20H)DATA3ENDENDS72/200 组 合 方 式 示 意 图模 块 1 、 模 块 2 连 接 后 段 的 定 位73/200 (3) '类别名': 类别名是合法的自定义符, 它必须用单引号括起来。类别名可由程序设计人员自己选定任何字符串组成, 但它不能再作为程序的标号、变量名或其他定义的符号。 在连接处理时, LINK程序把类别名相同的所有段按先后顺序存放在连续的存储区内。74/200 4. 段寄存器说明伪指令格式如下:ASSUME 段寄存器: 段定义名1 [, 段寄存器: 段定义名2, …]功能: 指定段寄存器与某个逻辑段建立对应关系。其中段寄存器是指四个段寄存器CS、SS、DS、ES中之一,名是指逻辑段的段名。该伪指令告诉汇编程序在汇编时,段四个段寄存器之一应具有的符号段基址,以便汇编指令时确定段和建立错误信息。但是段寄存器实际值(CS除外)还要由传送指令 在执行程序时赋值。 75/200 ASSUME伪指令告诉汇编程序(MASM), 存储器寻址的缺省段名。例: ASSUME CS: CODE, DS: DATA, ES: DATA, SS: STACK 告诉汇编程序: 段名为CODE的段是代码段, 其基地址与CS相联系。 段名为DATA的段是数据段, 其基地址与DS相联系。 段名为DATA的段同时也是附加段, 其基地址与ES相联系。 段名为STACK的段是堆栈段, 其基地址与SS相联系。 注意, ASSUME伪指令与程序运行时段寄存器的值毫无关系。 (1) 程序运行时, DS、ES寄存器的值, 用指令赋给。如, MOV AX, DATA ;DATA是段名MOV DS, AXMOV ES, AX 76/200 (2) 程序运行时, 当某一个段具有STACK组合属性(Combine)时,SS的初值被自动初始化为该段的基地址, SP的初值被自动初始化为该段的长度。 SS、SP的值也可以用指令来设定, 如, MOV AX, STACK ;STACK是段名 MOV SS, AX MOV SP, 1000H77/200 (3) CS和IP的值CS的初值由END伪指令指定。例, END START ;START是一个标号 指定CS的初值等于标号START的段地址。IP的初值一般为0000H, 也可以使用ORG伪指令改变。如, 代码段中, ORG 100H ; 指定IP的值等于0100H。 CS、IP的值在程序运行过程中自动变化。当指令顺序执行时, 每执行一条指令, IP的值增加该指令的机器码长度;调用/返回调 用、中断/返回中断、转移可以改变CS、IP的值。78/200 4. 段寄存器说明伪指令? 需要注意的是: ASSUME伪指令只是告诉汇编程序段寄存器与 逻辑段的关系, 并没有给段寄存器赋予实际的初值。请看下面这段程序实现的是什么功能。CODE SEGMENT ASSUME CS: CODE, DS: DATA1, SS: STACKl MOV AX, DATA1 MOV DS, AXMOV AX, STACKlMOV SS, AX ┊ CODE ENDS 79/200给段寄存器赋值 【例】用ASSUME伪指令建立代码段、堆栈段与CS和SS的对应关系。 ? DATA1 ? A ? DATA1 ? STACK ? STACK ? DATA2 ? B ? DATA2 ? DATA3 ? C ? DATA3SEGMENT ENDS SEGMENT STACK ENDS SGEMENT ENDS SEGMENT ENDS80/200DB 1, 2, 3? DB 200 DUP(0)DB '123ABC'DB ?, ?, ? ? CODE ASSUME ? START: ? MOV ? MOV ? MOV ? ? Q1: MOV ? Q2: MOV ASSUME ? MOV ? MOV ? MOV ? MOV ? ? CODE ? ENDSEGMENT DS:DATA1, ES:DATA2, CS:CODE, SS:STACK MOV AX, DATA1 DS, AX ;DATA1→DS AX, DATA3 ES, AX ;DATA3→ES ┆ AL, A C, AL DS:DATA2 ;建立DS与B段的对应关系 AX, DATA2 DS, AX AL, B C, AL ┆ ENDS START81/200 5. 过程(子程序)定义伪指令: 定义一个过程(子程序)。格式: 〈过程名〉PROC[NEAR](或[FAR])┊ 〈过程名〉ENDP 过程名是自定义符。定义过程是为实现子程序调用而设的。 调用格式为: CALL〈过程名〉 过程由RET指令返回, 它可以不是最后一条指令, 它在过程 中可以设多点返回。 过程起始名和终止名必须相同。类型NEAR和FAR默认时系统约定是近过程, 当选NEAR时, 过程是段内调用, 过程中的RET是段内返回。当选FAR时, RET是段间返回。 82/200过程是段间调用,过程中的 6. 模块开始伪指令 格式: NAME 模块名 该伪指令指明程序模块的开始, 并指出模块名。模块名是 自定义符, 它不能是系统保留字, 每次汇编只能出现一次。 若该伪指令默认, 则取TITLE语句中的页标题前6个字符;若 没有TITLE语句, 则取源程序文件名为模块名。83/200 7. 模块结束伪指令 格式: END[启动标号或过程名] 该伪指令告诉汇编程序源文件结束, 令汇编程序停止汇编,并给出执行程序的入口位置。任何一个完整的源程序均应有 END指令。启动标号或过程名表示该汇编程序的启动地址, 启 动地址只有在主模块才有意义。例如: ?… END START 则表明该程序的启动地址为START。84/200 8. 定位伪指令格式: ORG〈表达式〉该伪指令把以下语句定义的内存数据或程序, 从表达式指定 的起点(偏移地址)开始连续存放, 直至遇到新的ORG指令。表 达式的值是一个无符号数, 值须为0~65535之间的非负整数。例如:ORG 100HVARWDWX于是, 数据 X 所在单元的偏移地址就成为VARW=0100H。85/200 例:ORG 8000HTAB:DB45H,73,'5','A'TAB1:DB 101B 伪指令ORG 定义了TAB的起始地址为8000H, 伪指令DB定义了8000H~8003单元的内容依次为: TAB (8000H)= 45H (8001H)= 49H (8002H)= 35H(1) 由 ORG定义(8003H)= 41H(8004H)= 05H TAB1(2) 跟在其他源程序之后86/200 【例】给汇编地址计数器赋值。 DATA SEGMENT ORG VAR1 ORG VAR2 N 10 ; 置$值为10DW 100H, 200H $+5 ;置$的值为14+5, 即为19DB 1, 2, $+1, $+2 EQU $-VAR2 ;($)= 23DATA ENDS 87/200 9. 列表伪指令(1) 建立标题格式: TITLE 标题为列表文件每页第一行定义大标题。(2) 建立小标题格式: SUBTTL 小标题为列表文件每页定义小标题, 输出在大标题之后。(3) 自动排版(行数、列数)格式: PAGE 行数, 行字数为列表文件定义每页行数(10~255)和每行字符数 (60~132), 默认值是66行, 80列。 88/200 10. 系统隐含进位制伪指令格式: · RADIX 表达式 定义在源程序中书写数据时的隐含进位制方式。表达式 的值是2~16之间的十进制数, 要遇到新的· RADIX语句后才 改变隐含进位制。例如, 表达式取值是8时, 书写默认后缀的数据是八进制而不是十进制。11. 连接伪指令连接伪指令主要解决多模块的连接问题, 对一个大程序来说, 往往要分模块编程, 分模块调试, 最后再系统连接与调 试。连接伪指令为多模块连接进行说明。 89/200 (1) 公用符号伪指令格式: PUBLIC〈符号名1[, 符号名2, …]〉本模块用PUBLIC伪指令说明的自定义符号名可由其他程 序模块引用, 没有说明的符号名不能被其他模块引用。符号 名可以是变量名、标号、过程名或符号常量等。 (2) 引用符号伪指令 格式: EXTRN〈符号名1: 类型[, 符号名2: 类型…]〉 在本模块引用的在其他模块定义的符号名必须用EXTRN进行说明, 否则不能引用。此外还应注意, 所引用的外模块定义的符号名还应是用PUBLIC伪指令说明过的。 90/200 类型是指符号名的类型, 它们可以是:内存变量型: BYTE, WORD, DWORD 过程型: NEAR, FAR 数值型: ABS (3) 插入伪指令(或称包含伪指令)格式: INCLUDE〈模块名〉在本模块汇编时, 把另一模块插入该伪指令处一起汇编, 被插 入的模块可以是不完整的。 (4) 合段伪指令(或称组合伪指令) 格式: 组名GROUP〈段名1[, 段名2, 段名3, …]〉 把其后指定的段组合在一个64KB的物理段中, 组名和段名都 是自定义符, 但不可重名。 91/200 12. 记录伪指令 (1) 记录定义伪指令 格式: 记录名RECORD〈字段名1: 字段宽 [, 字段名2: 字段宽, …]〉记录定义伪指令完成对内存单元二进制位的定义, 这在实际应用中可以实现按位开关量或按位组合信息的处理。记录名和字段名是自定义符, 字段宽度是1~16常数。记录是把1~16个二进制位分为段并赋于一个字段名。记录定义伪指令不真正为记录分配内存单元, 以及记录长度的说明。 92/200它只是在汇编时进行记录名、字段名 (2) 记录存储单元分配及赋值 格式: [变量名]记录名〈字段值表〉 变量名是自定义符, 字段值表中的各字段值赋给记录的各 字段中, 其顺序与记录定义的顺序相同, 若字段值表中的某些项默认, 则默认值为0。应用时尖括号“〈 〉‖不能默认。例如: TAN AP BP RECORD TAN TAN X∶6, Y∶4, Z∶6〈5, 10, , 〉 〈12, , 20〉此例在存储器中分配两个记录,(16位)。每个记录长是两个字节93/200 (3) 记录操作符 ① WIDTH 格式: WIDTH 记录名(或字段名)用该操作符可求出记录或字段所占的位数。例如: MOV MOV ② MASK AX, WIDTH TAN BH, WIDTH Y ;AX←16 ;BH←4格式: MASK 记录字段名用该操作符可返回记录字段位或使用情况, 它是8位或16位二 进制数, 1表示是该字段位, 0表示不是该字段位。例如:MOVMOVAL, MASK ZBL, MASK X;AL←B;BL←B94/200 13. 结构伪指令: 结构伪指令是把多个数据定义语句组织成一个结构, 而把每一个数据定义语句称为一个结构字段, 内存变量名称为字段名。 (1) 结构定义 格式: 结构名 STRUC 〈数据定义语句〉?……结构名 ENDS 结构定义不真正为结构分配存储空间, 它是在汇编时进行 结构说明的。 95/200 (2) 结构存储单元分配及赋值 格式: [变量名]结构名〈字段值表〉 变量名是自定义符, 字段值表的各字段值赋给结构的各字段中, 其顺序与结构定义的顺序相同, 若字段值表中某些项默认, 则保 留初始值。应用时尖括号“〈 〉‖不能默认。例如: TAN1 STRUCD1D2 SYYDB2, 25, 10HDB′WTAN′ DB?TAN1SUN CATENDSTAN1〈, ′DOG1′, 2〉 TAN1〈, ′beg′, 〉在存储器中分配了两个结构单元。 96/200 (3) 结构引用格式: 结构变量名?结构字段名 例如: MOV DH, SUN?SYY;DH←2 MOV AL, CAT?SYY;AL←014. 块注释伪指令格式: COMMENT 定界符 注释 定界符定界符是自定义任何非空字符。例如, COMMENT /注释文/97/200 7.3 宏指令为了简化汇编语言源程序的书写, 把一些频繁出现的程序段定义为“宏指令”, 当程序中遇到这个程序段时, 只需用一条宏调用语句, 这样有效地缩短了源程序的长度, 使源程 序易读, 也减少了由于重复书写而引起的错误。从某种意义上讲, 它与前述的“过程”有相似之处, 也可以将构成一条宏指令的程序段定义为一个“过程”, 但两者具有明显的区 别, 主要表现如下: (1) 宏调用语句由宏汇编程序MASM?86中的宏处理程序来识 别, 并完成相应的处理;而调用过程的CALL语句由CPU来执行。 98/200 (2) 汇编语言源程序在汇编过程中要将宏指令所代替的程序段汇编成相应的机器代码, 并插入到源程序的目标代码中, 每次调用均要插入, 这样, 使用宏调用并不能缩短目标代码的长度。但被定义的“过程”经汇编后的机器代码是与主程序分开而独立存在的,其目标代码在存储器中只需保留一份,因此, 采用过程调用能有效地缩短目标代码的长度, 即节省 内存空间, 而宏指令却没有这一优点。99/200 (3) 过程调用时需要保留程序的断点和现场, 待过程执行完毕还要恢复现场和断点, 这些操作需要耗费CPU的时间, 而宏调用则不需进行这些操作。因此, 过程调用可节省程序占用的存储空间, 但会降低程序的执行速度;而宏调用不能节省存储 空间, 却能有较快的执行速度。100/200 (4) 在每次宏调用时允许修改有关参数, 使得同一条宏指令在各 次调用过程中可完成不同的操作;而“过程”一旦被定义, 一般不允许修改。因此,完成完全相同的功能。任何一个“过程”在各次调用中只能从上述特点可看出, 当需要多次执行的程序段比较长, 对速度要求不很高, 并且不要求修改参数的情况下, 宜采用过 程调用方式;若要求多次执行的程序段比较短, 或希望在各次 调用中能修改某些参数时, 则宜采用宏调用方式。101/200 在使用高级语言时, 各语句的定义(即它对应哪些机器指 令)是由相应的编译程序去处理的, 但宏指令却不一样, 它需要定义。宏指令的使用要经过如下3个步骤: (1) 宏定义: 对各个宏指令进行定义, 并分别起一个名字; (2) 宏调用: 在需要使用的地方, 通过宏指令名来调用它; (3) 宏扩展: 由宏汇编程序用宏定义中的指令来代替宏调用中 的宏指令名。102/200 下面介绍各种宏语句及其功能。 1. 宏代换语句 格式: 宏名 MACRO[形式参数1, 形式参数2, …] ? … … ? ENDM 宏体(指令序列)功能: 宏代换语句为指令序列定义一个宏名, 称为宏指令, 宏名可以像指令一样在程序中引用。103/200 形式参数是任选项, 可用来代换宏体中某些参数或符号。当代 换指令中的符号时, 在其前面需加一个宏代换符&。例如: AH MACRO Y, X MOV CL, XRO&Y CLENDM 经宏代换语句定义的宏名, 在应用时可直接引用, 称为宏调用。宏调用时, 形式参数要用实在参数取代, 顺序也应与形式参数顺序相同。例如: AH R, 5 源程序在汇编后, 在引用宏名的地方, 插入了宏体, 它在.LST文件列表时可以看到, 其中有+号的指令便称为宏扩展。宏指令可以嵌套, 并可与子程序联合嵌套。 104/200 2. 局域符号定义语句格式: LOCAL 符号1[, 符号2, …] 功能: 指出符号1, 符号2, …仅在宏代换中有意义, 其目的是 在宏扩展时不会引起符号重复定义的错误。LOCAL语句必 须紧跟在MACRO之后。 3. 删除宏定义语句 格式: PURGE 宏定义名1[, 宏定义名2, …]功能: 删除(注销)程序中引用的宏指令, 使之在宏调用的地方不再生成宏扩展。105/200 4. 退出宏定义 格式: EXITM功能: 在宏体或重复定义的语句中, 遇到EXITM语句时, 终止以后的宏扩展。 5. 重复定义语句(1) 格式: REPT〈表达式〉 …}指令序列ENDM功能: 重复执行REPT与ENDM之间的指令, 表达式是重复次数 106/200 6. 重复定义语句(2) 格式: IRP 形式参数, 〈参数1, 参数2, …〉?…}指令序列ENDM功能: 重复执行IRP与ENDM之间的语句, 每次重复, 将一个参 数代入形式参数中, 直到最后一个参数代换完为止。 7. 重复定义语句(3)格式: IRPC形式参数, 字符串? …}指令序列 ENDM功能: 重复执行IRPC与ENDM之间的语句, 每次重复, 将一个 字符代入形式参数中, 直到最后一个字符代换完为止。 107/200 8. 包含汇编语句 格式: INCLUDE 文件名 功能: 在程序汇编时, 把INCLUDE指示的文件插入该语句处一起汇编。108/200 7.4 系统功能调用为给编写汇编语言源程序提供方便, MS-DOS系统中设置 了几十个内部子程序, 它们可完成I/O设备管理、存储管理、 文件管理和作业管理等功能。对我们来说, 它们是几十个独立中断服务程序, 它们的入口已由系统置入中断入口地址表中, 在汇编语言源程序中可用软中断指令调用它们。一般我们常用的软中断指令有8条,系统规定它们的中断类型码为20H~27H, 它们各自的功能及入口/出口参数如表7-3所示(见 书第168页)。 109/200 从表7-3中可看出, 这些软中断完全隐蔽了设备的物理特性 和接口方式, 调用它们时只需要先设置好入口参数, 随后安 排一条软中断指令“INT n‖(n=20~27H), 即可转去执行相应的子程序。其中“INT 21H‖是系统功能调用, 它本身包含80多个子程序,0~57H。每个子程序对应一个功能号,其编号从110/200 系统功能调用中的几十个子程序成为汇编语言程序员的重要工具, 程序员不必了解所使用设备的物理特性、接口方式及内存分配等, 不必编写繁锁的控制程序。调用它们时采用统一的格式, 只需使用以下3个语句:(1) 传送入口参数到指定寄存器中;(2) 功能号送入AH寄存器中;(3) INT 21H。111/200 有的子程序无入口参数, 则只需安排后两个语句, 调用结 束后, 系统将出口参数送到指定寄存器中或从屏幕显示出来。 例如: 2号系统功能调用可用如下指令: 调用结果是将DL寄存器 中的可打印字符通过屏幕显示输出(或打印机打印输出)。112/200 下面选择一部分常用的系统功能调用作简要说明:1. 键盘输入单字符这是1号系统功能调用, 使用格式如下所示: 它没有入口参 数, 执行1号系统功能调用时, 系统等待键盘输入, 待程序员 按下任何一键, 系统先检查是否Ctrl-Break键, 如果是则退 出, 否则将键入字符的ASCII码置入AL寄存器中, 并在屏幕 上显示该字符。113/200 2. 键盘输入字符串这是0AH号系统功能调用, 其功能是将键盘输入的字符串写入到内存缓冲区中, 因此必须事先在内存储器中定义一个缓冲区。其第1字节给定该缓冲区中能存放的字节个数, 第2字节留给系统填写实际键入的字符个数, 从第3个字节开始用来存放键入的字符串, 最后键入回车键表示字符串结束。如果实际键入的字符数不足填满缓冲区时, 则其余字节填“0‖;如果实际键入的字符数超过缓冲区的容量, 则超出的字符将被丢失, 而 且响铃, 表示向程序员发出警告。 114/200 0AH号系统功能调用的使用格式如下所示: ? …… BUF DB 20DBDB ……?20 DUP(?)?定义缓冲区MOV DX, OFFSET BUFMOV AH, 0AH INT 21H 0AH号系统功能调用以上程序中, 由变量定义语句定义了一个可存放20个字节的缓 冲区, 执行到INT21H指令时, 系统等待用户键入字符串。程序员 每键入一个字符, 其相应的ASCII码将被写入缓冲区中, 待程序 员最后键入回车键时, 由系统输出实际键入的字符数, 并将其写 入缓冲区的第2字节中。 115/200 3. 输出单字符 这是2号系统功能调用, 使用格式如下所示:MOV DL, 'A'MOV INT AH, 2 21H执行2号系统功能调用时, 将置入DL寄存器中的字符从 屏幕上显示输出(或打印机打印输出)。116/200 ? 4. 输出字符串这是9号系统功能调用, 其功能是将指定的内存缓冲区中的字符 串从屏幕显示输出(或从打印机打印输出)。缓冲区中的字符串以“$”字符作为结束标志。9号系统功能调用的使用格式如下所示: ? …… BUF DB ′good bye $′ …… MOV DX, OFFSET BUF MOV AH, 9 INT 21H …… 执行9号系统功能调用时, 将内存缓冲区BUF中存放的字符串(以 “$”字符为结束)送屏幕显示输出(或送打印机打印输出)。 117/200? 5. 直接控制台输入/输出单字符 这是6号系统功能调用, 如果(DL)=0FFH, 则表示是从键盘输 入单字符送AL寄存器中;如果(DL)≠0FFH, 则表示是将DL寄存 器中内容送屏幕显示输出。它们的使用格式如下: MOV DL, 0FFH MOV AH, 6 ;键盘输入单字符送AL中INT 21HMOV DL ′A′ MOV AH, 6 INT 21H ; 118/200;将DL中的字符“A‖送屏幕显示 6. 无回显直接控制台输入单字符这是7号系统功能调用, 等待从标准输入设备输入单字符置入AL寄存器中, 但不送屏幕显示。其使用格式如下:MOV AH, 7INT 21H它没有入口参数, 系统等待从控制台标准输入设备输入单字符后, 将其ASCII码置入AL寄存器中。119/200 7. 无回显键盘输入单字符 这是8号系统功能调用, 等待从键盘输入单字符, 将其ASCII码置入AL寄存器中。但不送屏幕显示,如下:其使用格式MOV AH, 8INT 21H 与1号系统功能调用的区别仅在于键入它没有入口参数,的字符不送屏幕显示。120/200 8. 从串口输入单字符 这是3号系统功能调用, 其使用格式如下: MOV AH, 3 INT 21H 它没有入口参数, 系统将从异步通信口串行输入的字符置入 AL寄存器中。 9. 向串口输出单字符 这是4号系统功能调用, 其使用格式如下:MOV DL, ′$′MOV AH, 4 INT 21H执行结果将DL寄存器中的字符通过异步通信口串行输出。 121/200 10. 返回操作系统 这是4CH号系统功能调用, 其使用格式如下: MOV AH, 4CH INT 21H 它没有入口参数, 执行结果是结束当前正在执行的程序, 并返回操作系统。屏幕显示操作系统提示 符(N>), N为当前使用的驱动器名。122/200 11. 设置日期 这是2BH号系统功能调用, 其功能是设置有效日期。例如, 当 前需要设置的日期是日, 那么应将年号1990以装配 型BCD码形式置入CX寄存器中, 将月号12置入DH寄存器中, 将 日期26装入DL寄存器中。其使用格式如下: MOV CX, 1990H MOV DH, 12H MOV DL, 26H MOV AH, 2BH INT 21H执行的结果是将有效日期设置为日, 如果设置成 功, 则0→AL寄存器, 否则0FFH→AL寄存器。从此以后日期会 自动修改。 123/200 12. 取得日期这是2AH号系统功能调用, 其使用格式如下: MOV AH, 2AH INT 21H 它没有入口参数, 执行结果是将年号置入CX寄存器 其功能是将当前有效日期取到CX和DX寄存器中, 存放格式与设置日期时相同,中, 月份和日期置入DX寄存器中。124/200 13. 设置时间 这是2DH号系统功能调用, 其功能是设置有效时间。例如, 当前有效时间是8点15分20.5秒, 那么应将小时数8置入CH寄存 器中、分钟数15置入CL寄存器中, 秒数20置入DH寄存器中, 百分之一秒数50置入DL寄存器中。其使用格式如下:MOV CX, 0815H MOV DX, 2050HMOV AH, 2DHINT 21H 执行结果是将当前有效时间设置为8点15分20.5秒以后会自动 修改时间。如果设置成功, 则将AL寄存器内容清“0‖, 否则将 AL寄存器置全“1‖。 125/200 14. 取得时间这是2CH号系统功能调用, 其功能是将当前时间置入CX和DX寄存器中, 存放格式与设置时间相同。其使用格式如下: MOV AH, 2CH INT 21H 它没有入口参数, 存器中供使用。 其他的系统功能调用, 有的不常用, 有的比较繁锁, 不再一 执行结果是将当前时间送入CX和DX寄一说明。126/200 7.5 汇编程序的功能及汇编过程7.5.1 汇编程序的功能 汇编程序的主要功能是将由汇编语言(助记符)编写的源程 序翻译成用机器语言(二进制代码)编写的目标程序。图7.4 可用以说明这个功能。127/200 从图中可以看到,汇编语言源程序作为汇编程序(MASM或ASM)这个“翻译”的输入, 而这个“翻译”的输出是3个文件。其中, 目标代码文件就是机器码文件, 在目标代码文件中的地址数据还是浮动的(相对的), 因此, 它还不能直接运行;列表文件包含了程序的逻辑地址、代码程序及源程序对照清单, 并在该文件后附有引用符号表, 该文件可用DOS的TYPE命令输出;交叉索引文件包含了符号定义行号和引用行号, 能用TYPE命令输出, 文件(.REF)才能输出。 128/200该文件不它需要执行CREF文件后生成索引列表 汇编语言的程序一般要经过编 辑、汇编(MASM或ASM)、连 接(LINK)和调试(DE-BUG)这 些步骤, 如右图7.5所示。129/200 1. 建立源程序文件 建立源程序文件用编辑软件完成, 常用的编辑软件有行编辑EDLIN, 全屏幕编辑WORDSTAR等。2. 汇编(MASM或ASM)源程序IBM PC微机提供了两种汇编程序版本: 一种是全型版本(MASM);另一种是小型版本(ASM)。全型版本比小型版本增加了宏汇编、条件汇编及错误信息全部打印输出功能。小型版本占用存储空间小, 有64KB的内存就可以运行, 而全型版本 至少要有90KB以上的内存。 130/200 汇编程序有两种启动方式: (1) 提问方式 在MS-DOS下输入命令行: MASM或ASM 这时, MS-DOS将装入并启动执行汇编程序, 然后汇编程序 就逐次向用户提问, 用户必须根据要求予以回答。在回答信息 的最后, 可输入一个或多个开关, 汇编程序将按照回答信息及开 关的定义做相应处理。 在回答提示信息时, 可以使用以下两个命令字符: ; 用于省略对后续提示的回答, 仅取默认值;CTRL-C当因为输入了错误的文件名或其他原因而想中途退出汇编程序时, 按下CTRL-C键即可退出。 131/200 (2) 命令方式 以命令方式启动汇编程序时, 必须在MS-DOS下打入下列格 式的命令: MASM(或ASM)〈源文件〉, [〈目标文件〉], [〈列表 文件〉], [〈交叉参考文件〉][/开关]于是在装入汇编程序后将立即开始进行汇编。命令中MASM(或ASM)后面的项目, 分别顺次对应于提问方式中对各提示信息的回答, 各项 目之间用逗号隔开。/开关可放在任一项目之后。如果对某一 提示信息采用默认值, 则只需在对应的项目处连续输入两个逗 号。例如: MASM FUN, , FUN/D/X, FUN 132/200 3. 程序连接 连接程序LINK用来连接汇编程序生成的目标代码文件(.OBJ)以及指定的库文件,程序有3种启动方式:产生一个可执行的装入文件(.EXE)。连接(1) 提问方式, 在MS-DOS下输入命令行: LINK?这时MS-DOS将把连接程序装入内存, 并向用户提问, 用户根据要求输入相应的回答。 除了在汇编程序一段中叙述过的两个命令字符以外, 连接程 序的回答信息中还可使用命令字符+号, 它用以分隔多个要连接 的目标代码模块或库文件。当显示器上一行输入不下时还可使用+号另起一行。 133/200 (2) 命令方式 以命令方式启动连接程序时, 必须在MS-DOS下输入如下格式的命令:LINK〈目标代码模块表〉, [〈装入模块名〉], [〈列表文件名〉], [〈库文件名表〉][/开关]?命令中LINK后面的各项目顺次对应于提问方式中对各提示信息的回答,各项目之间用逗号隔开。如对某一项提示信息采用默认值, 则只需在对应 的项目处连续输入两个逗号。例如: LINK FUN+TEXT+TABLE+CARE/P/M, , FUNLIST, COBLIB-LIB134/200 (3) 文件方式 以文件方式启动LINK的命令格式为:LINK@〈文件名〉?其中, 文件名用来指出一个包含有对于LINK提示信息回答的正文文件, 文件中每一行正文对应一个回答, 因而用户可以不必一一回答LINK的提示, 而由LINK程序直接从文件中取得回答。当然, 在使用文件方式之前, 用户必须建立一个这样的响应文件。135/200 4. 执行程序 在DOS提示符下, 键入连接程序所产生的可执行文件的名字 后, 即可执行该程序。例如: A: >ABCD?(扩展名?EXE可默认) 就会把文件ABCD.EXE装入内存, 并从程序指定地址开始执 行。执行程序其结果不一定正确, 有时会“死机”。“死机” 时要重新启动机器, 然后用DEBUG调试.EXE文件。136/200 5. 调试程序 调试程序DEBUG是专为宏汇编语言设计的一种调试手段, 是 我们必须掌握的一种调试工具。 在操作系统提示符下, 按如下格式键入命令: A: >DEBUG[驱动器名: ][路径][文件名[扩展名]] 例如: A: >DEBUGA: ABCD.EXE?键入此命令后, 就启动了DEBUG程序。DOS的程序首先装入文件, 并把控制权交给DEBUG。 但控制权并不交给DEBUG 程 序 再 装 入 ABCD.EXE 文 件 , ABCD.EXE , 而是由DEBUG掌握着。137/200 在DEBUG程序中, 为我们提供了18条子命令。利用这18条 子命令, 我们可以对程序进行汇编和反汇编;可以观察和修改 并观察每一步执内存及寄存器的内容;可以执行或跟踪程序,行的结果;可以读/写盘上的扇区或文件等。但令人遗憾的是, 如果被调试的文件是可执行文件(.EXE文件), 则调试好的文件不能写回到盘上去。这是因为, 可执行文件是带有重定位信息文件头的, 调试程序不能产生这些重定位 信息, 因此不能把它写回到盘上去。惟一的办法就是在调试过 程中把发现的错误记载下来, 待调试完毕后, 重新编辑、汇编 和连接, 产生新的可执行文件。 138/200 7.6 汇编语言程序设计在第4章中已经讲过, 286/80386等CPU把存储器分成若干段, 每个段是一个可独立寻址的逻辑单位。段是8086系列汇编语言程序的基础, 一个段就是一些指令和数据的集合, 8086系列汇编语言源程序就是建立在段结构的基础上。所以, 在编制汇编语言源程序时, 首先要使用段定义伪指令和段寻址伪指令来构成一个由若干指令和数据组成的程序。一个程序有 几个段, 完全根据实际情况来确定, 通常是按照程序中的用途来划分段。如存放数据的段, 作堆栈使用的段, 存放程序的段,存放子程序的段等等。 139/200 开始编制程序时, 不妨先设3~4个段, 由4个段寄存器CS, DS, SS, ES 分别存放这些段的段基值。这样, 构造一个源程序的基本格式如下: DATA SEGMENT …?}存放数据项的数据段 DATA ENDSEXTRA SEGMENT…?}存放数据项的附加段 EXTRA ENDSSTACK1 SEGMENT PARA STACK…?}作堆栈用的堆栈段 STACK1 ENDS 140/200 COSEG SEGMENTASSUME CS: COSEG, DS: DATAASSUMES S: STACK1, ES: EXTRABEING: MOV AX, DATAMOV DS, AX?…}存放指令序列COSEG ENDS END BEING 上述4个段排列的先后顺序可以是任意的。 141/200 【例7.1】(1) 设计要求: 在源程序中设置数据段、堆栈段及代码段。在数据 段中定义8个字节数据, 把这些数据转换成十六进制数的ASCII 码存在上述数据之后, 然后在屏幕上显示这些数据。显示数据 用DOS功能2号调用, 每个数据用空格分隔。 (2) 程序流程: 程序流程如图7.6和图7.7所示。 (3) 程序清单: 二进制数对十六进制数转换及显示主程序如下:142/200 图7.6图7.7143/200 1: 2: 3: 4: 5: 6: 7:NAME EX1;程序命名伪指令, 程序名为EX1 PAGE50, 70 ;---------------------------------------------------DATSEGMENTPARA ′DAT′ A1DB12H, 34H, 56H, 78H, 9AH DB 0BCH, 0DEH, 0F0H B1=$-A1;赋值伪指令, 求A1(符号地址)到当前汇编指针地址($)的字节数8: 9:B2=B1*2;求2倍B1 A2DBB2DUP(?);数据重复定义伪指令, 定义ASCII码字符区144/20010: DATENDS 11: 12: 13: 14: 15:;---------------------------------------------------STACSEGMENTPARASTACK′STA′ STA1DW100DUP(?) STACENDS ;----------------------------------------------------16:17: 18: 19: 20: 21:CODESEGMENT[]PARA′CODE′ASSUME ASSUME CS: CODE, DS: DAT SS: STAC, ES: DAT FARSTARPROC PUSH DSXOR AX, AX145/200 22: 23: 24: 25: 26: 27: 28:PUSH AX MOV MOV MOV LEA LEA MOV AX, DAT DS, AX ES, AX SI, A1 DI, A2 CX, B129:30: 31:G1: MOVMOV MOVBL, 2AL, [SI] BH, AL146/20032:PUSH CX 33: 34: 35: 36: 37: 38: 39:MOV RORCL, 4 AL, CLPOP CX G2: AND AL, 0FH DAA ;对AL两位十进制数(BCD)调整ADD AL, 0F0H ADC AL, 40H40:41: 42:MOV [DI], ALINC MOV DEC DI AL, BH BL147/20043: 44: 45: 46: 47: 48: 49: 50:JNZ INCG2 SILOOP G1 MOV MOV CALL RET SIOFFSETA2 ;A2的偏移地址送SI寄存器 CX, B2 P1显示ASCII码字符子程序如下:51: 52:P1 PROC MOV BL, 2148/200 53: 54: 55: 56: 57: 58: 59:G:MOVDL, [SI]MOV INTAH, 2 21HINC SI DEC BL JNZ MOV T DL, ′′60:61: 62:MOVINT MOV T:AH, 221H BL, 2 G149/20063:LOOP 64: 65: 66: 67:RET P1 ENDP CODE ENDS END STAR 子程序名: P1功能: 显示ASCII码字符 入口: SI指向ASCII码区CX是ASCII码区长150/200 【例7.2】(1) 设计要求: 设计多字节减法运算程序, 要求程序能够显示运算数据和结果数据(以十六进制形式)。 分模块设计要求: ① 多字节减法; ② 多字节显示; ③ 回车换行操作。 其中回车换行模块按近程设计, 不要求独立汇编, 它在主模块汇编时由包含伪指令INCLUDE插入,构如图7.8所示。并一同汇编。程序层次结151/200 (2) 程序流程(如图7.9和图7.10所示)图 7.9图 7.10152/200 (3) 程序清单 主程序: 1: 2: 3: NAME EX2 PAGE50, 70 PUBLICD1, D2, N1, N24:5: 6: 7: 8: 9:EXTRNEX21: FAREXTRNEX22: FAR ;----------------------------------------------DATSEGMENTPARA′DAT′ D1DB88H, 44H, 66H, 00H, 99H N1=$-D1153/200 10: 11: 12: 13: 14:D2DB22H, 55H, 88H N2=$-D2 DATENDS ;-------------------------------------------------STACSEGMENTPARASTACK15:16: 17: 18: 19: 20:STA1DW100DUP(?)STACENDS ;-------------------------------------------------CODESEGMENTPARA′CODE′ ASSUME ASSUME CS: CODE, DS: DAT SS: STAC, ES: DAT154/200 21:22: 23: 24: 25: 26: 27:STAPROC FARPUSH DS XOR AX, AX PUSH AX MOV MOV MOV AX, DAT DS, AX ES, AX28:29: 30: 31:STDLEA SI, D1ADD SI, N1-1 MOV CX, N1155/200 32: 33: 34: 35: 36: 37:CALL CALL LEAEX21 PP2 SI, D2ADD SI, N2-1 MOV CALL CX, N2 EX2138:39: 40: 41: 42:CALL PP2CALL LEA EX22 SI, D1ADD SI, N1-1 MOV CX, N1156/200 43: 44: 45: 46: 47: 48:CALL RETEX21STA ENDP ;-------------------------------------------------------INCLUDE PP2?ASM CODE ENDS49:END STA回车换行子程序(分模块): 1: 2: 3:PP2 PROC MOV DL, 0DH MOV AH, 2157/200 4: 5: 6: 7: 8: 9:INT 21H MOV DL, 0AH MOV AH, 2 INT 21H RET PP2 ENDP158/200 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:NAME EX21 --------------------------------------------------------------------------------------------PAGE50, 70 PUBLICEX21 CODESEGMENTPARA′CODE′ ASSUMECS: CODE EX21 PROC FAR PUSH AX PUSH DX F: LODSB CALL PP1 MOV DL, ′′ 分模块EX21 MOV AH, 2 功能: 多字节二进制数ASCII码转换、显示。 INT 21H 入口: DS: SI 指向数据区高地址一端, CX是长度 LOOP F POP DX POP AX RET EX21ENDP ;?-------------------------------------------------------------------------------------------------------159/200 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35:PP1PROC PUSH BX PUSH CX MOV BL, AL MOV CL, 4 SHR AL, CL CALL P1 MOV AL, BL CALL P1 POP CX POP BX RET PP1ENDP P1 PROC PUSH PUSH AX DX ----------------------子程序: PP1 功能: 8位二进制数对十六进制数 ASCII码转换、显示。 入口: AL是8位二进制数。36:ANDAL, 0FH子程序P1 功能: 4位二进制数对十六进制数 ASCII码转换、显示 入口: AL低4位是二进制数160/200 37: 38: 39:CMP JB SAL, 10---------------------------------------------------------------子程序P1 功能: 4位二进制数对十六进制数ADD AL, 740:41: 42:S: ADDAL, 30HASCII码转换、显示入口: AL低4位是二进制数MOV DL, AL MOV AH, 243:44: 45:INT 21HPOP DX POP AX46:47: 48: 49:RETP1ENDP CODE ENDS-------------------------------------------------------------------END161/200 多字减法子程序(分模块):1: NAME2: PUBLICEX22 3: EXTRND1: BYTE, D2: BYTE4: EXTRNN1: ABS, N2: ABS5: ;-------------------------------------------------------6: CODESEGMENTPARA′CODE′ 7: ASSUMECS: CODE 8: EX22PROCFAR 9: LEASI, D1 10: LEADI, D2 11: MOV BX, N1 12: MOV CX, N2 13: MM: MOVAL, [DI]162/200 14: SBB [SI], AL 15: INC DI 16: INC SI 17: DEC BX 18: LOOP MM 19: M1: JZ M2 20: JNC M2 21: SBB BYTE PTR [SI], 0 22: INC SI 23: DEC BX 24: JMP M1 25: M2: RET 26: EX22 ENDP 27: CODE ENDS 28: END 163/200 【例7.3】大小写字母互换 (1) 设计要求: 设内存数据区有大小写混合英文ASCII码字母。将其转换成全部大写和全部小写,字母显示用DOS功能9号调用。并在屏幕显示这3种字母。(2) 程序算法: 大小写英文字母转换, 查ASCII码字符表可知, 字母 A ~ Z的 ASCII 码 是 41H ~ 5AH, 字 母 a ~ z的 ASCII 码 是61H~7AH。两种字母转换只需加减20H即可。 (3) 程序如下:164/200 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:TITLE EX3 PAGE50, 70 ;---------------------------------------------------------------------------------DATSEGMENTPARA′DAT′ ↑ D0DB0DH, 0AH D1DB′AKFDjfjjecJIDJkdkjkJD′, ′$′设置大小写混合字母 DATENDS ↓ ;---------------------------------------------------------------------------------STACSEGMENTPARASTACK′STAC′ ↑ STA1DW100DUP(?) 设置堆栈段 STACENDS ↓ ;--------------------------------------------------------------------------------CODESEGMENT PARA′CODE′ ASSUME CS: CODE, DS: DAT ASSUME SS: STAC, ES: DAT STARFAR165/200 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33:PUSH DS XOR AX, AX PUSH AX MOV AX, DAT--------------------------------↓------------------------MOV DS, AX 设置数据段地址 MOV ES, AX-----------------------------------↑------------------------; --------------------------------------------------------------↑---------------CALL TT 显示大小写混合字母(TT) LEA DI, D1 大写字母转换小写字母(TT1) CALL TT1 显示小写字母(TT) CALL TT 小写字母转换大写字母(TT2) LEA DI, D1 显示大写字母(TT) CALL TT2 CALL TT ↓ RET-----------------------------------------------------------------------------STARENDP ;166/200 34: 35: 36:TT1PROC GO: MOV AL, [DI]↑ CMP AL, ′$′37:38: 39: 40: 41: 42: 43:JZ GO2CMP AL, ′A′ JB GO1 CMP AL, ′Z′大写字母转换小写字母子程序 JA GO1TT1 ADD BYTEPTR[DI], 20H GO1: INC DI44:45: 46: 47:JMP GOGO2: RET TT1ENDP ↓ ;167/200 48: 49: 50:TT2PROC ------------------------------------------↑-----------------------GQ: MOV AL, [DI] CMP AL, ′$”51:52: 53: 54: 55: 56: 57:JZ GQ2CMP AL, ′a′ JB GQ1 CMP AL, ′Z′ JA GQ1TT2 SUB BYTEPTR[DI], 20H GQ1: INC DI 小写字母转换大写字母子程序58:59: 60: 61:JMP GQGQ2: RET TT2ENDP ;------------------------------------------------------↓-------------------------168/200 62: 63: 64: 65: 66: 67: 68: 69:TT PROC ------------------------------------↑-----------------------------LEA DX, DS 显示字符串子程序TTMOV AH, 9 INT RET TT ENDP------------------------------------↓------------------------------CODE ENDS ENDSTAR 21H执行程序: A>EX3AKFDjfjjecJIDJkdkjkJD akfdjfjjecjidjkdkjkjdAKFDJFJJECJIDJKDKJKJD 169/200 【例7.4】表的处理 表是数据(或信息代码)元素的集合, 按其元素排列顺序可分为有序表和无序表。有序表是指表中元素之间有着某种规律的表, 这是应用时非常希望的。无序表是指表中元素之间无任何规律可寻的 表, 这给表的应用带来许多不便, 但这种表在应用中会经常遇到,如随机检测到的各种物理参量等。 表的元素类型有数值型的、字符型的或是代表某种意义信息代码。表的应用十分广泛, 如函数表、平方及立方表、对数表、程序转移地址表、中断向量表等。 170/200 表的处理有以下几个方面: ① 读表: 读出表中某个或某些元素, 进行显示或处理。 ② 删除: 删除表中某个或某些元素。 ③ 插入: 在表中某个位置插入某些元素。 ④ 排序: 把表中元素按某种规律重新排列。 ⑤ 搜索: 从表中查找某种或某些元素。 ⑥ 对表中元素作某种要求的统计。例如, 统计表中某种元素个数等。(1) 读表程序设计① 设计要求 设内存DS: 2000H地址开始有一个ASCII码字符表(设表长不大于 100字节), 该表以*作结束标志。 统计表长并以十进制数显示。由键盘输入两位十进制数指示表 的位置, 读出该位置元素值并送屏幕显示。 171/200 ② 程序算法统计表长是从表首开始按字节计数, 用DAA指令对计数值进行十进 制数调整, 计数遇到*符结束。对十进制计数值进行ASCII码转换, 送屏 幕显示。 用DOS功能1号调用, 从键盘输入两位十进制数, 将其转换成二进制 数后在表中定位, 读出该位置的元素(ASCII码字符)并送屏幕显示。 ③ 程序清单如下:1:2: 3:NAME EX4-1PAGE50, 70 ;-------------------------------------------------------↑---------------------------4:DATSEGMENTPARA′DAT′设置数据段5: ORG2000H 6: A1DB10DUP(′ABCDE′)7: DB 8DUP(′12345′)8: DB′*′设置数据表及结束标志*172/200 9: DATENDS 10: 11: 12: 13: 14: 15: 16:-------------------------------------------↓---------------------------;----------------------------------------------------------------------------------STAC SEGMENT PARA STACK ↑STA1DW100DUP(?) STACENDS设置堆栈段 ↓;----------------------------------------------------------------------------------CODESEGMENT[]PARA′CODE′ ASSUME CS∶CODE, DS∶DAT ↑17:18:ASSUME SS∶STAC, ES∶DAT 设置代码段STAPROC FAR------------------------------------↓------------------------173/200 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33:PUSH DS ------------------------------------↓-----------------------XOR AX, AX 保护DOS返回地址 PUSH AX---------------------------------------↑-----------------------MOV AX, DAT ----------------------------↑----------------------MOV DS, AX 置数据段值 MOV ES, AX--------------------------------↓-------------------------LEA SI, A1 --------------------------------↑-------------------------XOR AX, AX MOV AH, ′*′ Q1: CMP AH, [SI] JZ Q2 统计表长 INC SI (十进制) ADD AL, 1 DAA JMP Q1------------------------------------------↓-----------------------174/200 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49:Q2: MOV BL, AL --------------------------↑-------------------------MOV CL, 4 SHR AL, CL OR AL, 30H MOV DL, AL MOV AH, 2 INT 21H 十进制数转换ASCII码 AND BL, 0FH 送屏幕显示 OR BL, 30H MOV DL, BL MOV AH, 2 INT 21H CALL P10 ----------------------------------↓-------------------------MOV CL, 2 ----------------------------------↑-------------------------Q3: MOV AH, 1键盘输入(DOS功能1号) INT 21H -------------------------------------↓---------------------------175/200 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66:CMP AL, 30H ------------------------↑----------------------------JB Q3 CMP AL, 39H 键盘输入判别, 非0—9字符 JA Q3 重新输入 DEC CL JZ Q4 ----------------------------------↓--------------------------AND AL, 0FH ------------------------↑---------------------------MOV AH, 10 键盘输入数字对二进制数转换 MUL AH (十位数) MOV BL, AL JMP Q3 -------------------------------↓---------------------------Q4∶AND AL, 0FH ---------------------↑-----------------------ADD AL, BL DEC AL 键盘输入数字对二进制数转换 LEA SI, A1 (个位数) MOV AH, 0 ADD SI, AX ----------------------------↓---------------------------176/200 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84:MOV DL, ′′--------------------------↑-------------------------------MOV AH, 2 显示空格 INT 21H ---------------------------------↓-------------------------------MOV DL, [SI] -------------------- ↑-------------------------------MOV AH, 2 读表元素 INT 21H --------------------------------↓-------------------------------RET STA ENDP ;-------------------------------------------------------------------------------------P10 PROC ↑ MOV DL, 0DH MOV AH, 2 INT 21H 输出回车换行子程序 MOV DL, 0AH MOV AH, 2 INT 21H RET ↓ P10 ---------------------------------------------------------------177/200 85: 86:CODEENDS ENDSTA① 设计要求 设内存数据区DS∶2000H地址开始有150个ASCII码字符, 表以$符结束。 删除表中第31至45元素, 从表首插入5个“!‖符, 显示表删除 插入前后的内容, 显示表内容。 ② 程序算法 删除表中元素, 只要把后面的元素向前移动, 覆盖要删除的 元素。表插入元素, 先把指定位置以后的全部元素向后移动, 留 由键盘输入一个字符, 删除表中的这个元素, 该出空位, 再把要插入的元素插入。 178/200 当删除表中某类元素时, 要对表进行全面搜索, 然后删去所 要删除的该类元素。③ 程序清单如下:1: 2: NAME EX4-2 PAGE50, 703:4: 5:;------------------------------------------------------------------------------DATSEGMENTPARA′DAT′ ORG2000H ↑ 设置数据段6:7: 8: 9: 10: 11:A0DB0DH, 0AHA1DB10 DUP(′QWERTYUIO, ′) DB 5DUP(′ASDFGHJKL, ′) DB′$′ DATENDS设置字符表设置表结束符$;------------------------------------------------↓-------------------------------179/200 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27:STACSEGMENTPARASTACK -----------------↑-------------------STA1DW100DUP(?) 设置堆栈段 STACENDS ↓ ;---------------------------------------------------------------------------------CODESEGMENTPARA′CODE′---------------------↑-------------ASSUME CS∶CODE, DS∶DAT 设置代码段 ASSUME SS∶STAC, ES∶DAT ↓ STAPROC FAR--------------------------------------------------------------PUSH DS ↑ XOR AX, AX 保护DOS返回地址 PUSH AX -----------------------------------↓-------------------------MOV AX, DAT ↑ MOV DS, AX 设置数据段值 MOV ES, AX----------------------------------↓-------------------------CALL IT ↑ STD180/200 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43:MOV CX, 30 LEA SI, A1 MOV DI, SI 显示字符表, 子程序IT ADD SI, 29 在表中插入5个!字符 ADD DI, 34 REP MOVSB MOV CX, 5 MOV AL, ′!′ REP STOSB ------------------------↓-------------------------------CLD ------------------------------↑--------------------------------ADD SI, 45+1 ADD DI, 35+1 删去原第31—45元素 MOV CX, 105+1 显示插入、删除后表元素(IT) REP MOVSB CALL IT MOV AH, 1 ------------------------↓-------------------------------181/200 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59:INT 21H键盘输入 -----------------------------------------------LEA SI, A1 ↑ T1∶CMP BYTEPTR[SI], ′$′ JZ T3 CMP AL, [SI] 查找要删除的元素, JZ T2 遇到$符结束 INC SI JMP T1 调数据块移动子程序EX4-3 T2∶CALL EX4-3 调显示表元素子程序IT JMP T1 T3∶IT RET STA ENDP----------------------------------↓------------------------------; ITPROC ↑ LEA DX, A0182/200 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77:MOV AH, 9 显示表元素子程序IT INT 21H RET ITENDP-------------------------------↓---------------------------------------EX4-3 -------------------------------↑---------------------------------------PROC PUSH SI MOV DI, SI INC SI 数据块移动子程序 R: MOVSB CMP BYTEPTR[DI-1], ′$′ EX4-3 JZ R1 JMP R R1: SI RET EX4-3 ENDP ↓ CODE ENDS --------------------------------------------------------------STA183/200 排序是把表中元素按某种规律排列起来, 排序需要事先约定排序条件, 序排列。 ①设计要求: 设源程序代码段中有无序字符表, 将其按代码值大 小升序排序, 显示排序前后字符表, 显示完, 提示OK字符。 称为关键条件。如把表中元素按值的大小升序或降②程序算法: 气泡排序是一种常用的排序方法, 它的规则是: 表中相邻两元素一一比较, 并把大值元素向下交换, 直至表尾(大值元素落底), 此时, 称为一次冒泡(程序中一次大循环)。以后重复冒泡排序, 直至最小元素冒到表顶为止。若在一次冒泡排序中没有出现两元素交换(设标志为0), 则停止排序。 ③程序流程(如图7.11所示) 184/200 图7.11185/200 ④1: 2: 3: 4:程序清单如下:NAME CODES EX4-4 SEGMENTORG0100H ASSUMECS∶CODES5:6: 7: 8: 9:STAR∶JMPSSTTASCII DB′GAJXYDEBFIPKWR′ DB′QOUZVCHMST4135′ COUNT OK DB =$-ASCII-1 0DH, 0AH, ′OK!$′10:SSTT∶MOVAX, CS186/200 11:12: 13: 14: 15: 16: 17:MOVMOV MOV XOR L0∶ JZDS, AXDL, COUNT DH, 1 BXBX DH, DHOR L3MOVDH, 018:19: 20:MOVSUB MOVCX, COUNTCX, BX SI, OFFSETASCII187/200 21:22: 23: 24: 25: 26: 27:L1∶INCMOVSIAL, [SI]CMP JBEAL, [SI] L2 AL, [SI] [SI-1], AL DH, 1XCHG MOV MOV28:29: 30:L2∶INC DECLOOPBX DLL1188/200 31: 32: 33: 34: 35:JNZ L3∶L0 MOV DX, OFFSETASCIIMOV INT INTAH, 9 21H 20H36:37:CODESENDENDSSTAR189/200 【例7.5】(1) 设计要求求y=a2+b2+2ab, 显示运算结果(十六进制形式)。a, b是两个 单字节无符号数, 并在数据段中定义, 结果存在这两个数之后, 约定3个字节。 子程序结构要求:两字节相乘、一个字节数显示、多字节数显示, 设计成3个子程序。多字节数显示子程序嵌套一个字节数显示子程序。 程序层次结构如图7.12所示。 子程序采用近程(段内)直接调用, 主程序与子程序间参数传 递用存储器约定单元。(2) 程序流程(如图7.13和图7.14、图7.15所示) 190/200 图7.12图7.13 191/200 图7.14子程序: PP 功能: 显示多字节数(十六进制)。 入口: 显示数据在Y单元, 长度3字节。 出口: 显示十六进制数图7.15 192/200 (3) 程序清单1: : NAME EX5 2: PAGE50, 70 3: DATSEGMENT 4: ADB125 5: BDB90 6: YDB3DUP(0) 7: ZDB0, 0 8: DATENDS 9: STASEGMENTSTACK 10: DW50DUP(?) 11: STAENDS 12: CODSEGMENT 13: ASSUMECS: COD, DS∶DAT 14: STAR PROC FAR 15: PUSH DS 193/200 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31:XOR PUSH MOV MOV MOV MOV ;AX, AX AX AX, DAT DS, AX AX, STA SS, AXMOV MOV MOV CALL MOV MOV MOV CALL MOVAL, A Z, AL Z+1, AL EX5-1 AL, B Z, AL Z+1, AL EX5-1 AL, A194/200 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47:MOV Z, AL MOV AL, B MOV Z+1, AL CALL EX5-1 ADD WORDPTRY, AX ADC BYTEPTR[Y+2], 0 CALL PP RET STAR ENDP ; EX5-1 PROC MOV AL, Z MOV AH, Z+1 MUL AH ADD WORDPTRY, AX ADC BYTEPTR[Y+2], 0195/200 48: 49: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64:RET EX5-1 ENDP PP PROC LEA SI, Y ADD SI, 2 MOV CX, 3 P∶ MOV AL, [SI] CALL PP3 DEC SI LOOP P RET PP ENDP ; PP3 PROC PUSH AX PUSH BX196/200 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80:PUSH CX PUSH DX MOV BH, AL MOV BL, 2 MOV CL, 4 SHR AL, CL GG2∶ CMP AL, 10 JGE GG3 OR AL, 30H JMP GG4 GG3∶ ADD AL, 37H GG4∶ MOV DL, AL MOV AH, 2 INT 21H DEC BL JZ GG5197/200 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92:MOV AL, BH AND AL, 0FH JMP GG2 GG5∶ POP DX POP CX POP BX POP AX RET PP3 ENDP ; COD ENDS END STAR198/200 习题7.1 在数据区中, 以TABLE开始连续存放0~6的立方值(称为立方表), 设任 给一数x(0≤x≤6), x在TAB1单元, 查表求x的立方值, 并把结果存入TAB2 单元。7.2 假设学生某门课的成绩存放在数据区中, 请编一程序, 统计该成绩中小于60分的人数, 60~90分的人数, 大于90分的人数, 并显示在屏幕上。 7.3 在数据区中以如下方式存放数据:DATALIST1SEGMENTDB DB 15 48DBLIST2 DB?20, 53, ?199/200 7.4 编一个十进制的乘法程序, 被乘数和乘数均以ASCII码的形 式存放在内存中, 将乘积在屏幕上显示出来。200/200
微机原理第07章——提供以文本文档的格式的各类文档免费下载和在线浏览。

我要回帖

更多关于 cd与be互相垂直平分 的文章

 

随机推荐