3_汇编语言程序格式.ppt_第1页
3_汇编语言程序格式.ppt_第2页
3_汇编语言程序格式.ppt_第3页
3_汇编语言程序格式.ppt_第4页
3_汇编语言程序格式.ppt_第5页
已阅读5页,还剩91页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1,封面,第三章,汇编语言程序格式,2,第三章汇编语言程序格式,第三章 汇编语言程序格式 概 述 3.1 汇编语言程序的开发 3.2 参数、变量和标号 3.3 程序段的定义和属性 3.4 复杂数据结构 要点及习题分析,3,概述1,概 述 1.“汇编”的含义?手工汇编 机器汇编 2.什麽是汇编程序? 3.什麽是伪指令?伪指令的作用; 伪指令与机器无关,取决于汇编程序的版本,版本越高,提供的伪指令数目增加,功能增强;如MASM6.0提供了.IF/.ENDIF等语句,使汇编语言程序设计类似高级语言的形式。,4,概述2,4.教材的“硬指令”:指的是CPU指令集中的指令。硬指令的条数和功能取决于CPU,

2、和汇编程序无关;但是,用汇编指令(符号指令)表示的硬指令,能否被汇编程序识别并翻译成机器指令,则与汇编程序的版本有关,如4.0以下的版本不支持386的32位指令,5.0开始支持32位指令,6.11版支持Pentium(但还不支持MMX指令6.12支持MMX指令)。 本章以MASM6.X为蓝本,介绍常用伪指令、操作符,汇编、连接、运行程序的过程,以及修改调试方法。,回第三章,5,3.1(目录)汇编语言程序的开发,3.1汇编语言程序的开发 3.1.1 汇编语言程序的语句格式 1)执行性语句 2)说明性语句 3.1.2 汇编语言的程序格式 1)简化段定义格式 2)完整段定义格式 3.1.3 汇编语言

3、程序的开发过程 源程序的编辑、汇编、连接、调试,返回第三章,6,3.1.1汇编语言程序的语句格式,3.1.1 汇编语言程序的语句格式 两类语句:1)执行性语句 2)说明性语句 1)执行性语句(硬指令、代码段) 标号(冒号是标号的一部分):代表该指令的逻辑地址,为分支、循环、调用等指令提供转移的目的地址。是用户自定义的标识符。定义规则:最多31个字母、数字及特殊符号,不能以数字打头;默认情况下,不区别大小写;不能使用保留字。标号定义只可能出现在代码段。,标号:硬指令助记符 操作数,操作数 ;注释,7,执行性语句,硬指令助记符: 任何一条处理器指令或宏指令。 操作数: 立即数、寄存器、存储单元;无

4、操作数、单操作数和双操作数。 注释(分号是注释的一部分): 增加程序的可读性。注释不应是指令功能的重复。如对于指令“mov cx,25”,“25送入寄存器CX”毫无意义,可能应该写成“设置循环次数”。,标号:硬指令助记符 操作数,操作数 ;注释,8,说明性语句,2)说明性语句(伪指令、可位于任何段) 名字 伪指令助记符 参数,参数;注释 名 字: 可以是变量名、段名、子程序名或宏名,这 些名字既反映逻辑地址,又具有自身的各种属性;对不同的说明性语句,其中的名字具有不同的属性,具体内容在介绍伪指令时介绍。名字也可以是一个常数或一个符号的代号,可称其为“符号名”,这种名字仅仅具有标识的作用。 名字

5、与标号的区别:无冒号;可以在任何段定义(严格来说是变量名和符号名)。 名字的定义规则与标号相同。,9,说明性语句(e),伪指令助记符:本章主要内容。 参数:伪指令要求的内容,常数、变量、表达式 注释:增加可读性。 两种语句的四部分要用分割符分开,操作数和参数用逗号,其他用空格或制表符。,返回3.1,名字 伪指令助记符 参数,参数;注释,10,3.1.2程序格式,3.1.2 汇编语言的程序格式 使用汇编语言编写程序时必须遵循的语法规则。 完整的汇编语言源程序由段组成:若干个代码段、数据段、附加段或堆栈段;独立运行的程序必须包含一个代码段,并指出程序的启动语句;所有的执行语句必须位于某一个代码段内

6、,说明性语句可根据需要位于任一段内;堆栈段不是必须的,但最好设置堆栈段。 编写汇编语言源程序通常应遵循所谓“标准格式”,本书介绍标准格式的两种表示形式,一种符合MASM 5.0及更新版本的语法规则,称为“简化段定义格式”;另一种符合早期版本的语法规则,称为“完整段定义格式”(5.0及以后的版本也支持)。,11,简化段定义格式,例3.1a 简化段定义格式 ;lt301a.asm .model small .stack .data String db hello,everybody!,0dh,0ah,$ .code .startup ;说明程序的起点,设置DS、SS mov dx,offset,s

7、tring mov ah,9 int 21h .exit 0 ;程序结束,形成返回DOS的指令 end,MASM5.0 5.1不支持,MASM5.0 5.1不支持,12,完整段定义格式(e),例3.1b 完整段定义格式 ;lt301b.asmmov ds,ax Stack segment stackmov dx,offset string dw 512 dup(?)mov ah,9 Stack endsint 21h Data segmentmov ax,4c00h String db int 21h Data endscode ends Code segment code end start

8、 assume cs:code,ds:data, ss:stack Start:mov ax,data,返回3.1,13,3.1.3开发过程(1),3.1.3 汇编语言程序的开发过程 1. 源程序的编辑 EDIT。扩展名必须是 .asm。 2. 源程序的汇编 MASM 6.x版本:ml.exe 如 ml /c lt301a.asm MASM 5.x版本:masm.exe 如 masm lt301a.asm 3. 目标文件的连接 将一个或多个目标文件与库文件合并成一个可执行文件(.exe,.com) LINK lt301a.obj LINK的一般格式: LINK /参数选项 obj文件列表 ex

9、e文件名,map 文件名,库文件名,14,开发过程(2),ML /参数选项 文件列表 LINK 连接参数选项,4. ML.EXE的用法 ML.EXE可以自动调用LINK程序,实现汇编和连接自动地依次进行。其一般格式如下: 常用参数选项如下(参数大小写敏感): /c(小写):只汇编,不连接。 /Fl 文件名:创建一个汇编列表文件(.lst)。 /Fr 文件名:创建一个可在PWB下浏览的.SBR文件。 /Fo 文件名:生成指定的.OBJ文件,不用缺省名。 /Fe 文件名:生成指定的.EXE文件,不用缺省名。 /Fm 文件名:创建一个连接映象文件(.MAP)。 /Sg 在列表文件中,列出由汇编程序产

10、生的指令。,15,文件介绍(3),5. 两个文件的介绍(.lst.map) 要生成列表文件和连接映象文件,可以输入如下形式的命令: ML /Fl /Fm /Sg lt301a.asm(p76) 注释: 注意大小写; 参数/Sg将.startup,.exit等伪指令转换成 硬指令,浏览列表文件,浏览映象文件,16,程序的调试(1),6.可执行程序的调试 经汇编、连接生成的可执行程序在DOS提示符后键入文件名即可直接运行。如运行有错误,可使用DEBUG程序调试。 键入命令:DEBUG LT301A.EXE 即可将程序调入内存,由DEBUG控制。用户可使用单步执行、断点执行等方法进行调试。 注意寻找

11、数据段的方法。,17,程序的调试(2),7.程序在内存中的定位及如何寻找数据段 参考:教材P76/例题3.1a:lt301a.asm; 教材P80/lt301a.asm的列表文件; 教材P81/lt301a.asm的影像文件; 教材P82/lt301a.exe由DEBUG装入内存后的反汇编结果以及使用R命令显示的寄存器值。 操作步骤: 按P82 DEBUG装入内存后显示的寄存器值,由DS=ES=14B4H可知,14B4为最低的可用的段地址,即程序段前缀(PSP)的起始地址。 CS=14C4H为代码段的段地址,即14C40为整个程序的起始地址;14C40相当于影像文件的00000H。,18,程序

12、的调试(3),在反汇编结果中,第一条指令为MOV DX,14C6,在影像文件中已经显示DGROUP的“Origin”为0002:0,所以将14C6(14C4+0002)作为DS的值。 数据段第一个数据的地址:在影像文件中显示:DATA段的“Start”为00024H,14C40+00024=14C64,这是数据段第一个数据的物理地址,由于DS=14C6,其逻辑地址为14C6:0004,在数据段的偏移地址当然是0004。从反汇编结果的第13条指令(MOV DX,0004)也可以看出第一个数据的偏移地址为04。,19,程序的调试(4)(end),教材82页SS=14C8: 14C40为整个程序的起

13、始地址,81页的影像文件显示:STACK段的“Start”=00040h, 14c40h+00040h=14c80h,取高4位,即SS=14C8H。这是未调整的堆栈段的段地址。 82页显示SP=0400:影像文件反映起始地址为00040H,末地址为0043FH,长度为0400H(堆栈段默认长度1024字节,16进制数为0400);堆栈区可表示成14C8:003FF。设置SP=0400,则入栈时第一个数据将占用14C8:03FE和03FF单元,显然,SP的值应等于堆栈区的长度值。 SP=0400H是未调整的堆栈指针。,返回第三章,返回3.1,20,3.2(目录)参数、变量和标号,3.2 参数、变

14、量和标号 3.2.1 数值型参数 常数、数值表达式、运算符及运算符 的优先级 3.2.2 变量定义伪指令 3.2.3 变量和标号的属性 变量和标号的三种属性、属性操作符,返回第三章,21,3.2.1 数值型参数,3.2.1 数值型参数 参数可分为两类:数值型参数 地址型参数 对硬指令:指令的操作对象(一般称为操作数),可以是立即数,寄存器和存储单元,其立即数要用数值型参数表达,地址型参数如标号或变量的名字。 对伪指令:参数给汇编程序提供必要的信息,使汇编程序完成汇编。 数值型参数含:常数 数值表达式 1.常数:十进制(默认)十六进制 二进制 八进制 字符串常数(其数值为ASCII码值) 符号常

15、数:表达一个数值的标识符 涉及到的两条伪指令:,22,数值型参数,1)基数控制伪指令(RADIX) RADIX n;n取216内的任意整数。 如“ RADIX 16”,使汇编程序把默认的基数改为16,即没有加后缀的数表示十六进制数,非十六进制数均应加后缀(含十进制数)。 2)符号常数定义伪指令(EQU、=) EQU 符号名 EQU 数值表达式 符号名 EQU ;5.X版用双引号。 给符号定义一个数值或把符号定义成另一个字符串;也可以说使EQU两边的项等效,可以互相代换。,23,数值型参数,例如:Number_1 EQU 2; Loop_count EQU 2*5+Number_1 CallDo

16、s EQU 注释: 1)程序中使用符号常数,而不使用具体数值,可大大提高程序的易读性,而且使程序易于修改。使用汇编语言编写程序,通常应遵循这一原则。 2)EQU右边的项允许出现符号,但该符号必须是已经定义或即将定义的。 3)符号定义后即可在程序中使用,如 MOV CX,Loop_count CallDos,24,数值型参数,“=” 号伪指令 其作用同EQU,但用=号定义的符号在同一个程序中可以重复定义,EQU不可。 如 X=7 ;X EQU 7 正确 X=X+3 ;X EQU X+3 错误,25,数值型参数,2.数值表达式 常数、寄存器、变量及标号等用运算符连接起来即构成表达式,如细分,有算术

17、表达式、逻辑表达式、关系表达式、地址表达式等,但是由于前三种表达式或由它们构成的综合型表达式其结果都是数值,故一律算做数值表达式;如果一个表达式的结果从物理意义来说,代表存储器单元的地址,则称其为地址表达式。 常见运算符分成五类: 1)算术运算符:+ 、- 、* 、/ 、MOD 2)逻辑运算符:AND 、OR 、XOR 、NOT 3)移位运算符:SHL 、SHR 4)关系运算符:EQ、NE、GT、LT、GE、LE 5)高低分离符:HIGH、LOW、HIGHWORD、LOWWORD,26,数值型参数(end),数值表达式作为数值型参数可以出现在硬指令语句和伪指令语句中;数值表达式的结果,由汇编程

18、序负责计算,不会影响目标程序的运行速度。例如: mov ax,3*4+5 ;mov ax,17 and al,03h and 05h ;and al,01h mov al,0101b shl 2*2 ;mov al,01010000b ;移位对象 SHL/SHR 移位次数 mov bx,(port lt 5)and 20)or(port ge 5)and 30) ;如关系成立,值为0FFFFH;否则为0。 ;当port5时,汇编结果为mov bx,20 ;当port5时,汇编结果为mov bx,30 dd_value equ 0ffff1234h mov ax,lowword dd_value

19、 ;mov ax,1234h,关于优先级问题,不同的运算符,有不同的优先级,由于运算符多,优先级层次多,编程时通常用圆括号规定优先级。,返回 3.2,27,3.2.2 变量定义伪指令(1),3.2.2 变量定义伪指令 为变量申请固定长度的存储空间,并将相应存储单 元初始化。 一般格式: 变量名为用户自定义的标识符,表示初值表首个 数据的偏移地址,称为符号地址。如省略变量名, 汇编程序只为初值表分配空间,无符号地址。 伪指令助记符:指DB、DW等。 初值表是由逗号分割开的参数,可以是常数、表 达式、问号、DUP等。问号(?)表示初值不确定, 即不赋初值;DUP为重复分配操作符,格式为: 重复次数

20、 DUP(被重复数据列表),变量名 伪指令助记符 初值表,28,变量定义伪指令(2),1.字节定义伪指令DB 使汇编程序以字节为单位分配一个或多个存储单元, 并将它们按初值表规定的数据初始化。初值表中的每个 数据只能是字节量或字符串常数。,data segment x db a,-5 db 2 dup(1,2,?) y db ABC,? data ends,汇编程序的地址计数器: 每进入一个新段,地址 计数器清零;每分配一 个单元,地址计数器自 动加1,指向下一个待分 配的单元;代表当前值。,变量X、Y定义后,即可在指令中使用: MOV AL,X ;直接寻址(MOV AL,0000H) DEC

21、 X+1;直接寻址(DEC BYTE PTR0001H) MOV CH,BX+Y;寄存器相对寻址 MOV Y,AL ;直接寻址(MOV 0008H,AL),29,变量定义伪指令(3),2.定义字单元伪指令DW 功能与DB相同,但以字单元(两个字节)为单位分配存储空间;初值表中的每个数据只能是字量,即16位数据。 DATA SEGMENT COUNT DW 8000H;8000H可能是一个无符号数或有符号 ASCII DW AB ;不可多于两个字符,区分高低地址 NUM_1 DW 25H ;DW 0025H MAX EQU 64H ;不占用存储空间 NUM_2 DW MAX,MAX+6,MAX*

22、2 DUP(?) CON_ADDR DW COUNT;变量中为COUNT的偏移地址 DATA ENDS,30,变量定义伪指令(4),指 令 举 例: WNUM EQU 5678H;WNUM为符号常数 COUNT DW 20H;COUNT为变量,设其偏移地址为10H MOV AX,BX+SI+WNUM;同MOV AX,BX+SI+5678H MOV BX,COUNT ;MOV BX,0010H BX=0020H LEA BX,COUNT ;同LEA BX,0010H BX=0010H MOV BX,OFFSET COUNT;同MOV BX,0010H BX=0010H MOV AX,SI+COU

23、NT ;同MOV AX,COUNTSI ;同MOV AX,SI+0010H,偏移量为符号常数,偏移量为变量,31,变量定义伪指令(5),3.定义双字单元伪指令DD 以双字单元(4字节)为单位分配存储空间。初值 表中的每个数据是32位数据,可以是32位有符号或无符 号数,也可以用来表示一个“远指针”(高位字表示段地 址,低位字表示偏移地址,可用做段间间接转移)。 vardd dd 0,?,12345678h far_point dd 00400078h(LDS SI,FAR_POINT) 4.其他数据定义伪指令 1)DF、DQ、DT 略 2)MASM6.0建议使用:BYTE/WORD/DWORD

24、等 3)SBYTE/SWORD/SDWORD:有符号数专用。,32,变量定义伪指令(6),例 3.2 数据定义综合应用 .model small CALLDOS equ .stack .code .data .startup bvar db 16 mov bl,bvar wvar dw 4*3 mov ax,word ptr dvar0 dvar dd 4294967295 mov dx,word ptr dvar2 qvar dq ? mov dx,offset msq db 1,2,3,4,5 mov ah, 9 tvar dt 2345 CALLDOS abc db a,b,c .exi

25、t 0 msq db hello,13,10,$ end bbuf db 12 dup(month) dbuf dd 25 dup(?),改变双字属性,33,变量定义伪指令(7),5.定位伪指令ORG(/EVEN/ALIGN) 控制数据或指令的偏移地址。 1)ORG 参数 使地址计数器指向参数表达的偏移地址。 ORG 100H;从0100H单元开始分配存储器。 ORG$+10;$表示地址计数器的当前值,$+10 ;表示由当前地址向前跳过10个字节。 2)EVEN ;使它后面的数据或指令从偶地址开始。 3)ALIGN n;使它后面的数据或指令从n的整数倍 ;地址开始(可被n整除)。 n是2的乘方

26、(2,4,8)且小于所在段的定位属 性值。如“ALIGN 4”,使下一个地址开始于双字边界。,34,变量定义伪指令(8)(end),定位伪指令举例: DATA SEGMENT D01 DB 1,2,3 ;D01偏移地址为0,=0003H EVEN(ALIGN 2); $为0004H D02 DW 5 ;D02偏移地址为04H, =0006H ALIGN 4 ;最接近6的、可被4整除的数是8 ; =0008H D03 DD 6 ;D03的偏移地址为08H,=000CH ORG +10H ;000CH+0010H=001CH =001CH D04 DB abc ;D04的偏移地址为001CH =0

27、01FH LEN EQU D04;LEN=001F001C=3 ;变量D04所占的字节数。,返回 3.2,35,3.2.3 变量和标号的属性(1),3.2.3 变量和标号的属性 变量和标号有三种属性: 段属性(段属性值、段值):所在段的段地址 偏移属性(偏移值):所在段的段内偏移地址 类型属性 对标号和子程序名:NEAR 或 FAR 对变量:BYTE、WORD、DWORD、FWORD等 注释:变量的偏移值,有时也称“变量的值”。但是最好将二者加以区别:变量的“偏移值”代表偏移地址;变量的值代表变量中存储的内容。高级语言中出现变量,通常是引用变量中所存放的数据,汇编语言中出现变量,根据指令的不同

28、,有时引用变量的偏移地址,有时引用变量中存储的数据。对此,应特别加以注意。,36,变量和标号的属性(2),DATA SEGMENT D01 DW 2508H D01_ADR DW D01 DATA ENDS MOV BX,D01 ;同MOV BX,0000H ;指令执行后,BX=2508H MOV BX,D01+2 ;同MOV BX,0000+2 MOV BX,SI+D01 ;同MOV BX,SI+0 MOV BX,OFFSET D01;同MOV BX,0000H LEA BX,D01;同MOV BX,0000H;执行后 BX=0,引用D01的偏移地址,引用D01存放的数据,D01出现在表达式

29、中,引用偏移地址,37,地址操作符(1),地址及类型操作符 1.地址操作符 OFFSET 变量|标号;返回变量或标号的偏移地址 SEG 变量|标号;返回变量或标号的段地址 设ARRAY为一变量 MOV AX,SEG ARRAY MOV DS,AX MOV BX,OFFSET ARRAY,“SEG ARRAY”和“OFFSET ARRAY”称为地址表达式。前面介绍的算术运算符也可构成地址表达式。 如 “ARRAY2”,“ARRAY-2”。,38,类型操作符(1),2.类型操作符 对变量或标号的类型属性进行操作。 PTR/THIS/LABEL/SHORT/TYPE/SIZEOF/LENGTHOF

30、PTR 类型名 PTR 变量|标号;给变量或标号指定类型属性 BYTE、WORD、DWORD、;NEAR、FAR; STRUCT、RECORD等定义的类型。 例如 MOV AL,BYTE PTR W_VAR MOV AX,WORD PTR B_VAR JMP FAR PTR N_LABEL JMP NEAR PTR F_LABEL,39,类型操作符(2),:给当前偏移地址指定一种类型属性,同时 定义了一个名字。 名字 EQU THIS 类型名,d01 dw 2055h ;设=0008H b_var equ this byte ;不占存储空间 w_var dw 10 dup(0) ;w_var仍

31、然指向0008H,当前偏移地址为0008H,“THIS”给它指定了一个类 型属性:BYTE,并借助EQU为它定义了名字:b_var。 第三条语句使0008H单元具有了另一个名字和另一 种属性。对0008H单元,两个名字、两种属性都可用。 注意: 要借助EQU伪指令。 与下一条伪指令合用。,THIS,40,:同“EQU THIS” L1 LABEL FAR ;不占内存 L2:MOV AX,2055H MOV指令所占单元(即MOV指令)具有两个标号、 两种属性。 L1 EQU THIS FAR L2:MOV AX,2055H,LABEL,类型操作符(3),:设定标号为短转移,只用于JMP指令。 转

32、移范围为-128+127字节(相对于JMP的下一条指令) JMP SHORT L1,SHORT,41,类型操作符(4),TYPE 变量/标号 ;返回变量或标号的类型属性值(数字量) 变量: BYTE WORD DWORD FWORD 返回值 1 2 4 6 标号: SHORT NEAR FAR 返回值 FF01H FF02H FF05H MOV AL,TYPE W_VAR ;MOV AL,2 MOV AX,TYPE L2 ;MOV AX,0FF02H,42,类型操作符(5),LENGTHOF 变量;返回变量的数据项数 如 D01 DW 25H,2050H,55AAH LENGTHOF D01=

33、3 MOV CX,LENGTHOF D01;MOV CX,3 SIZEOF 变量;=(LENGTHOF 变量)*(TYPE 变量) SIZEOR D01=32=6 MOV CX,SIZEOF D01;MOV CX,6,43,类型操作符(5),例 3.4 属性及应用 .model small .stack .data V_byte equ this byte V_word dw 3332h,3735h Target dw 5 dup(20h) Crlf db 0dh,0ah, $ Flag db 0 N_point dw offset s_label .code .startup mov al,

34、byte ptr v_word dec al mov v_byte ,al;v_word=3331h,44,类型操作符(6),N_label: cmp flag,1 ;flag单元=0 jz s_label inc flag ;flag=1 jmp short n_label S_label: cmp flag,2 ;flag=1 jz next inc flag ;flag=2 jmp n_point ;等同于jmp s_label Next: mov ax,type v_word ;ax=0002h mov cx,lengthof target;5个数据项,cx=5 mov si,offs

35、et target W_again: mov si,ax inc si inc si loop w_again;对target填充5个字:0002h,45,类型操作符(7)(end),mov cx,sizeof target;cx=10 mov al,? mov di,offset target B_again: mov di,al inc di loop b_again ;对target填充10个? mov dx,offset v_word mov ah,9 int 21h ;显示结果为1357? .exit 0 end,返回 3.2,返回第三章,46,3.3 (目录)程序段的定义和属性,3

36、.3 程序段的定义和属性 3.3.1 DOS的程序结构 EXE程序和COM程序 3.3.2 简化段定义格式 存储模式/简化段定义 程序开始/程序结束/汇编结束 3.3.3 完整段定义格式 完整段定义/指定段寄存器 段组伪指令/段顺序伪指令,返回第三章,47,3.3.1 DOS的程序结构(EXE),3.3.1 DOS的程序结构 1.EXE程序 由多个段组成;长度可大于64KB; (磁盘上的)EXE文件: 文件头:控制信息、重定位信息; 装入模块:程序本身。,调整示意图,48,DOS的程序结构(COM),2.COM程序 代码段、数据段以及堆栈段 (附加段)合并成一个段,长 度不超过64KB。 磁盘

37、上的COM文件是内存的完 全映象,不含附加信息。,CS=DS=ES=SS,1)所有段地址都指向PSP的段 地址; 2)执行起点:CS:0100 处。 3)SP自动设为0FFFEH(64K的 最后一个字单元。且将0FFFEH 和0FFFFH单元设为0。,返回 3.3,49,3.3.2 简化段定义格式,3.3.2 简化段定义格式 简化段定义标准格式: .model small .stack .data .code .startup .exit 0 end,;子程序代码,;程序代码,;数据定义,程序开始伪指令,程序结束伪指令,存储模式伪指令,汇编结束伪指令,50,存储模式,1. 存储模式伪指令 .m

38、odel 存储模式,语言类型,系统类型,堆栈选项 使用简化段定义格式时,必须使用。 必须位于所有段定义语句之前。 7种不同的存储模式: 只介绍下面两种 TINY(微型模式) SMALL(小型模式),默认参数: DOS、SS=DS,混合编程时使用,51,TINY 模式,微型模式是MASM 6.0才引入的 用于创建COM类型程序 用微型模式编写汇编语言程序时,所有的段地址寄存器都被设置为同一值 这意味着代码段、数据段、堆栈段都在同一个段内,不大于64KB;访问操作数或指令都只需要使用16位偏移地址,TINY 微型模式,52,SMALL 模式,一般的程序(例如本书的绝大多数程序示例和习题)都可用这种

39、模式 在小型模式下,一个程序至多只能有一个代码段和一个数据段,每段不大于64KB 这里的数据段是指数据段、堆栈段和附加段的总和,它们共用同一个段基址,总长度不可超过64KB;因此小模式下程序的最大长度为128KB 访问操作数或指令都只需要使用16位偏移地址;这意味着诸如指令转移、程序调用以及数据访问等都是近属性(NEAR),即小型模式下的调用类型和数据指针缺省分别为近调用和近指针,SMALL小型模式,53,简化段定义,2.简化段定义伪指令 .stack 大小:创建堆栈段,段名:STACK .STACK 512;创建512字节的堆栈段。 .STACK ;创建1024字节(默认)的堆栈段。 .DA

40、TA ;创建数据段,段名:_DATA .DATA ? ;数据段,无初值变量专用(_BSS) .CONST ;只读的常量数据段(CONST) .CODE 段名;创建代码段,在SMALL模式下, 默认的段名为:_TEXT 没有段定义结束语句,下一个段的开始,就是本段的结束。,54,预定义符号, 关于预定义符号 前面已经介绍,用简化段定义格式定义段时,各段 都有默认的段名,如_text、_data等。为方便编程时引 用,MASM设置了一些预定义符号,如 CODE、DATA、 STACK等,这些预定义符号可以在程序中使用。 如: MOV AX,STACK MOV SS, AX MOV AX, DATA

41、 MOV DS, AX 其中DATA是数据段段组的名字,即将数据段、 无初值数据段、常量数据段和堆栈段合并成一个段组 (DGROUP),该段组命名为DATA。,55,程序开始,3.程序开始伪指令 .STARTUP ;按CPU类型、存储模式、操作系统 和堆栈类型,产生程序开始执行的代码;指定了程 序开始执行的起点。在DOS环境下,设置DS,调整SS 和SP的值。 在SMALL模式,8086CPU,汇编得到的启动代码: mov dx,dgroup shl bx,1 ;(SS-DS)*16 mov ds,dx;设置DS shl bx,1 ;=数据占用的 mov bx,ss cli ;字节数 sub

42、bx,dx;SS-DS mov ss,dx;使SS=DS shl bx,1 add sp,bx;SP+字节数 shl bx,1 sti,56,数据段、堆栈段调整示意图,数据段、堆栈段调整示意图:,MOV AX,DGROUP MOV DS,AX,使SS=DS SP+(SS-DS)*16SP,57,程序结束,4.程序结束伪指令 .EXIT 返回数码 产生终止程序执行返回操作系统的指令代码,可 选参数为返给操作系统的一个数码,通常用0表示没有 错误,因而通常的用法是:.EXIT 0 。 产生代码:mov ax,4c00h int 21h 5.汇编结束伪指令 END 标号 标号指出程序的开始执行点。当

43、不使用.STARTUP 时,主程序的END伪指令必须给出标号;非主程序模块 一定不能给。,58,COM程序示例,例 3.5 COM程序示例 .model tiny ;只能是TINY模式 .code ;只有一个代码段 .startup ;等效于ORG 100H mov dx,offset string mov ah,09 int 21h ;显示信息 mov ah,01 int 21h ;等待按键 mov ah,02 mov dl,07 ;“鸣笛”的ASCII码 int 21h ;鸣笛 .exit 0 string db Press any key to continue !$ end ;数据安排

44、在代码后面,返回 3.3,59,3.3.3 完整段定义格式,3.3.3 完整段定义格式 1.段定义伪指令 段名 SEGMENT 定位 组合 段字 类别 段名 ENDS 定位属性:指定逻辑段的起始地址 BYTE:为下一个可用的字节地址(xxxx xxxxB) WORD:为下一个可用的偶数地址(xxxx xxx0B) DWORD:下一个可被4整除的地址(xxxx xx00B) PARA:下一个可被16整除的地址(xxxx 0000B) PAGE:下一个可被256整除的地址(0000 0000B),60,完整段定义格式,默认的定位属性为PARA。简化段定义中,代码段和 数据段默认的定位属性为WORD

45、,堆栈段为PARA。 组合属性:指定段与段之间的关系。 通常在多模块设计时使用,单模块下,除堆栈段必 须使用组合属性 STACK 外,其它段使用默认值即可。 完整段定义时,默认的组合属性为PRIVATE,意思是各段 相互独立,不与其它段合并,各段都有自己的段地址; 简化段定义时,默认的组合属性为PUBLIC,意思是告诉 连接程序把本段与所有同名的其它段相邻地连接在一起, 并合并为同一个段,共用一个段地址。,61,段字属性、类别属性,段字属性(use16use32): MASM5.0以后版本增加。对8086使用默认值(16位段),对32位CPU默认采用32位段,当然,也可以设置成16位段。 类别

46、属性:类别名。类别名相同的段相邻连接但各有各的段地址。通常使用code,date和stack等类别名,以保持所有代码和数据的连续。 注释:要把多个段(如代码段)连接成一个物理段,即共用一个段地址,仅仅使类别名相同是作不到的,类别名相同,只能作到“相邻连接”。详细内容在第五章介绍。,62,指定段寄存器,2.指定段寄存器伪指令 ASSUME 段寄存器:段名,段寄存器:段名 建立段寄存器与段之间的缺省关系,改变这种缺省关系可使用段跨越前缀。 如 ASSUME CS:CODE,DS:DATA ASSUME 段寄存器:NOTHING 对指令给出的段寄存器取消已经指定的缺省关系。 注意:ASSUME伪指令

47、并不能为段寄存器赋值。,63,段组伪指令,3.段组伪指令 组名 GROUP 段名,段名 将多个同类但不同名的段合并为一个不超过64KB 的物理段,并使用组名统一访问它。可理解为组合属 性PUBLIC的补充。 .MODEL SMALL具有下面语句的作用: dgroup GROUP _data,_bss,stack,64,段顺序伪指令,4.段顺序伪指令 设置段在内存中的实际存放顺序。 .SEG ;按源程序中的书写顺序。 .DOSSEG ;按DOS标准中规定的顺序,即代码段、 ;数据段、堆栈段。 .ALPHA ;按段名的字母顺序。 完整段定义格式默认为SEG; 简化段定义格式默认为DOSSEG。,6

48、5,例 3.7/1,例 3.7: 按要求写出适当的段定义:数据段起始于字边界,连接时同名逻辑段连接成一个物理段,类别名为data;堆栈设置在数据段内,起始地址为DS:100处,大小为200个字,sp指向栈顶;堆栈区后面为100个字的数组array;代码段cseg将100个字压入自设的堆栈。 dsegsegment word public data org 100h dw 200 dup(?) topsp equ this word array dw 100 dup(5868h) dsegends,66,例 3.7/2,csegsegment code assume cs:cseg,ds:dse

49、g,ss:dseg start:mov ax,dseg mov ds,ax mov ss,ax mov sp,offset topsp mov ah,4ch int 21h csegends end start,67,例3.6/1,例3.6 在程序中使用段组合 stacksegsegment stack db 256 dup(?) stacksegends data1 segment word public const const1dw 100 data1 ends data2 segment word public vars var1dw ? data2 ends datagroup gro

50、up data1,data2;进行段组合 codeseg segment para public code assume cs:codeseg,ds:datagroup,ss:stackseg,68,/2,start:mov ax,datagroup mov ds,ax ;对段组寻址 mov ax,const1;相当 mov ax,0000, ax=100 mov var1,ax ;var1=100 mov ax,offset var1;ax=2 mov ax,offset data1;后跟段组中的某个段名, 表示该段最后一个字节后面字节相对于段组的偏移地 址,也就是var1的偏移地址,ax=

51、2 mov ax,offset data2;取的是var1后面一个字 节的偏移地址:ax=4,69,/3(end),assume ds:data2 mov ax,data2 mov ds,ax mov ax,var1 ;ax=100 mov ax,offset var1;ax=2,仍然是相对段组 ;的偏移地址 mov ax,4c00h int 21h codeseg ends end start,返回 3.3,返回第三章,70,3.4 (目录)复杂数据结构,3.4 复杂数据结构 DB、DW 等伪指令用来定义变量,变量的数据类型 是单一的字节、两字节、四字节等,称其为简单数据结 构;将若干简单数

52、据结构的变量组合在一起,形成一个 复合型数据,再给这个复合型数据起一个名字,就得到 了一种新的数据类型,新数据类型的用法和DB、DW等伪 指令的用法相似。 3.4.1 结构 结构类型说明、变量定义、引用 3.4.2 记录 记录类型说明、变量定义、引用,回第三章,71,3.4.1结构类型的说明1,3.4.1 结构 1.结构类型的说明 结构名 STRUCT(5.0为STRUC) ;数据定义语句 结构名 ENDS 结构名自己定义 结构体为各种数据类型的数据定义语句 结构体前后为一对伪指令语句,72,结构类型说明2,student struct sid dw ? sname db abcdefgh m

53、ath db 0 english db 0 student ends 说明了一个结构类型,结构类型名为:student, 为该结构类型的标识;结构类型中所含的变量称为结构 字段;相应的变量名 称为字段名。 显然,结构中的元素可以是类型不同的变量。 字段数量不限;字段可以有名或无名; 可以有初值或无初值;可以独立存取。,73,结构变量,2.结构变量的定义 结构说明只是说明了一种新的数据类型,并没有定 义采用这种数据类型的变量,也就没有分配内存(如同 DB、DW等,未定义变量,也就不分配内存)。 使用结构预置语句定义结构变量: 变量名 结构类型名 ,74,结构变量,结构变量举例 stu1 stud

54、ent ;定义变量 stu2 student student 100 dup();预留100个结构变量空间 初值按结构说明的顺序对应;如某字段的值为空, 用逗号分割;初值表中为空的字段保持结构说明时指定 的初值。 比较:VAR DB 2,4,6,8 DB 100 DUP(?) “student”的作用和“DB”的作用是相同的。,75,结构变量的引用,3.结构变量及其字段的引用 引用结构变量:结构变量名。 引用结构变量的字段:结构变量名.字段名。 例3.8 定义含有100个PERSON结构数组的数据段,结构 中包括编号、姓名、性别和出生日期,并赋值编号。 .model small .stack

55、256 .data person struct number dw 0 pname db abcdefgh sex db 0 birthday db mm/dd/yyyy person ends ;array:第一个(person) array person 100 dup();结构数据的符号地址,76,举例结构变量(e),.code .startup mov bx,offset array mov ax,1 sub si,si mov cx,length array mov dx,type array again:mov bx+si.person.number,ax inc ax add s

56、i,dx loop again .exit 0 end,结构数据 的偏移地址,无结构变量名,用结构类型名,返回3.4,77,3.4.2记录 记录类型的说明1,3.4.2 记录 所谓“记录”,是将一个字节或一个字划分成若干个 “位段”,并给每个位段起一个名字,使得程序中可以使 用名字访问“位段”。记录中的基本存储单位是bit,即 “位段”是由一个或若干个二进制位组成的。 1.记录类型的说明 记录名 RECORD 位段 ,位段 记录名是该记录类型的标识(如同DB是字节类型 的标识)。位段说明了该记录类型的数据结构。,78,记录类型的说明2,位段的格式 位段名:位数=表达式 如:year:4,sex

57、:1=0,marriage:1=1 位段名分别为year,sex,marriage; 位数说明该位段占用的二进制位数:year占用4 位,sex占用1位,marriage占用1位; 表达式给位段赋值,可以省略:位段year没有赋 值,位段sex被赋值0,位段marriage被赋值1。,79,记录类型的说明3,year:4,sex:1=0,marriage:1=1 整个记录的长度为所有位段占用位数的和,为1 16位。 记录长度小于一个字节时,按一个字节汇编,长度 为916位时,按一个字汇编。 给位段分配“位”时,位段从最右边开始,二进制位 从最低位开始。如上述3个位段总长度为6位,按一个字 节汇

58、编,marriage占D0,sex占D1,year占D2D5。 不用的D6、D7为0。 完整的记录说明: person RECORD year:4,sex:1=0,marriage:1=1,80,记录变量的定义,2.记录变量的定义 说明了一种新的数据类型(记录类型)之后,即可 定义该类型的变量: 记录变量名 记录类型名 位段初值表为各位段赋值,用逗号分隔,与说明中的位 段次序按顺序对应;不赋初值的位段逗号不可省略,其 值采用说明时赋的值。 zhang person ;字节值00101010b wang person ;字节值00011100b,81,记录变量引用和记录操作符,3.记录变量的引用和记录操作符 1)记录变量的引用 MOV AL,zhang / MOV AL,wang 2)记录操作符 位段名:返回该位段在记录中的位置,也就是该位 段移到D0的移位次数。 MOV CL,year;C

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论