微机4-12上第2章(已学汇编).ppt
,第2章 指令系统及汇编语言程序设计,2.1 8088/8086的寻址方式2.2 8088/8086的指令系统2.3 汇编语言汇编语言源程序格式伪指令汇编语言源程序结构2.4汇编语言程序设计 基本程序设计方法DOS功能调用顺序程序设计分支程序设计循环程序设计子程序设计,本次课内容,请大家复习汇编语言掌握本节内容,第二章复习小结,下次课5.9汇编语言单元考试及讲第3章,2.3 汇编语言,汇编语言的特点汇编语言是一种以处理器指令系统为基础的低级程序设计语言,它采用助记符表达指令操作码利用汇编语言编写程序的主要优点是可以直接、有效地控制计算机硬件,因而容易创建代码序列短小、运行快速的可执行程序在有些应用领域,汇编语言的作用是不容置疑和无可替代的汇编程序设计的过程是与其他高级语言程序设计大致相同,什么是汇编语言,以助记符形式表示计算机指令助记符(mnemonic)是便于人们记忆、并能描述指令功能和指令操作数的符号助记符是表明指令功能的英语单词或其缩写汇编格式指令以及使用它们编写程序的规则就形成汇编语言(Assembly Language)汇编语言程序:用汇编语言书写的程序汇编程序:将汇编语言程序“汇编”成机器代码目标模块的程序,汇编语言程序与汇编程序是两个概念,汇编语言程序的语句格式,执行性语句由硬指令构成的语句,它通常对应一条机器指令,出现在程序的代码段中:标号:硬指令助记符 操作数,操作数;注释,说明性语句由伪指令构成的语句,它通常指示汇编程序如何汇编源程序:名字 伪指令助记符 参数,参数,;注释,硬指令和伪指令,汇编程序将汇编语言源程序翻译成在机器上能执行的机器语言程序(目的代码程序硬指令-执行性语句使CPU产生动作、并在程序执行时才处理的语句,就是第2章学习的处理器指令与具体的处理器有关、与汇编程序无关。汇编后对应一条指令代码伪指令(Directive)-说明性语句不产生CPU动作、在程序执行前由汇编程序处理的说明性语句,例如,数据说明、变量定义等等伪指令与具体的处理器类型无关,但与汇编程序的版本有关,本课程采用微软宏汇编程序 MASM 6.15,硬指令和伪指令采用易于记忆的符合表达,这就是助记符,MOV CX,0;传送指令,具有2个操作数DELA:NOP;空操作指令,没有操作数,带有标号 LOOP DELA;循环指令,标号DELA说明转移位置BUF DB 1,2,3,4,5,6,7;数据定义伪指令,在主存中开辟7个连续的字节单元,初值依次为17,BU表示首地址,汇编语言语句实例,一.汇编语言源程序格式(4部分),标号 硬指令的位置(逻辑地址),后加冒号:名字 伪指令的位置或存储单元名称(变量名),后不加冒号:一般最多由31个字母、数字及规定的特殊符号(如 _、$、?、)组成不能以数字开头(如 1ABC错),不能是保留字指令助记符 必须有,其它3部分可无伪指令助记符-伪指令硬指令助记符-硬指令注释语句中由分号“;”开始的部分为注释内容,用以增加源程序的可读性必要时,一个语句行也可以由分号开始作为阶段性注释汇编程序在翻译源程序时将跳过该部分,不对它们做任何处理,标号:硬指令助记符 操作数1,操作数2;注释名字 伪指令助记符 参数1,参数2,;注释,例:硬指令 Done:mov al,02h 伪指令 Sum db 02h,标号 指令助记符 操作数;注释,保留字,保留字(Reserved Word)是汇编程序已经利用的标识符(也称为关键字),主要有:硬指令助记符例如:MOV、ADD伪指令助记符例如:DB、DW操作符例如:OFFSET、PTR寄存器名例如:AX、CS预定义符号例如:data,汇编语言大小写不敏感,汇编语言源程序格式-操作数,操作数 常数、数值表达式、寄存器、标号、变量等数值表达式一般是指由运算符连接的各种常数所构成的表达式汇编程序在汇编过程中计算表达式,最终得到一个确定的数值,所以也是常数常用的运算符是加减乘除(*/)例:mov ax,3*4+5;等价于mov ax,17,汇编语言源程序格式-操作数,操作数 常数、寄存器、标号、数值表达式、变量等常数 汇编时已确定的数据 如硬指令中立即数二进制数 如 MOV AL,10110101B十进制常数 如MOV AL,181十六进制数常数 以字母开头的十六进制数前加“0”。例:MOV AL,0B5H字符和字符串常数例:MOV AX,AB;AX4142h MOV AX,1;AX31h用单引号括起来的单个字符或多个字符,其数值是每个字符对应的ASCII码的值.例如:d=64H,AB=4142H符号常数 用符号名表示一个常数,可以提高程序的可读性,同时更具有通用性符号定义伪指令格式等价EQU伪指令 符号名 EQU 表达式例:XY EQU 5等号=伪指令 符号名=表达式例:XY=5,例:XY EQU5 MOV AH,XY;等价于 MOV AH,5,符号定义DosWriteChar equ 2CarriageReturn=13CallDOS equ 符号应用(左边程序段等价右侧的符号形式)mov ah,2;mov ah,DosWriteCharmov dl,13;mov dl,CarriageReturnint 21h;CallDOS,符号常数实例,二.伪指令,1.符号(常量)定义伪指令 EQU符号常量使用符号名表达一个数值格式 符号名 EQU 表达式 例X EQU 7,2.变量定义伪指令(定义数据伪指令),变量定义伪指令为变量申请固定长度的存储空间,同时将相应存储单元初始化(参数为?则不初始化)。格式为:变量名 DB/DW/DD/DQ 参数1,参数2,DB(或BYTE)定义字节 其后每个参数占1个字节存储单元DW(或WORD)定义字 其后每个参数占2个字节(先低字节后高字节)存储单元DD(或DWORD)定义双字 其后每个参数占4个字节存储单元DQ(或QWORD)定义4个字 其后每个参数占8个字节存储单元多个存储单元如果初值相同,可以用复制操作符DUP进行定义:重复次数 DUP(重复参数)变量实质指内存单元的数据,变量需要事先定义才能使用.定义后的变量可用变量名等引用其中的数据,即变量的数值,例:alphabyte30h,2 DUP(55H),34h,?movcx,alpha;cx5530h movbx,offset alpha moval,bx+3;al34h,变量定义伪指令最常使用,定义字节单元伪指令DB,DB伪指令用于分配一个或多个字节单元,并可以将它们初始化为指定值初值表中每个数据一定是字节量(Byte),存放一个8位数据:可以是0255的无符号数 或是128127带符号数 也可以是字符串常数,字节变量定义实例,;数据段X db 61h,0fbh db 2 dup(64h),?Y db ABC,应用mov al,Xdec X+1mov Y,al,ASCII a=61h A=41h B=42h C=43h,;此处X表示它的第1个数据,故AL61h,;对X为始的第2个数据减1,故为0fah,;Y=al=61h,现在Y这个字符串成为 aBC,实例,程序如下countdb 80h,B,?maxintequ 04hnumberdw maxintarraydb maxint dup(3)mov cx,countdecbyte ptr arraymovbx,offset numbermovah,bx+2moval,bx-2hlt 问:程序执行后ax=?cx=?,答案:cx=4280h ah=2 al=42h,定义字单元伪指令DW,DW伪指令用于分配一个或多个字单元,并可以将它们初始化为指定值初值表中每个数据一定是字量(Word),一个字单元可用于存放任何16位数据:一个段地址一个偏移地址 两个字符 065535之间的无符号数 3276832767之间的带符号数,字变量定义实例,;数据段countdw 8000h,?,ABmaxintequ 64hnumberdw maxintarraydw maxint dup(0),ASCII A=41h B=42h,;数据段 字变量和字常量的定义:WNUM EQU 5678H;定义WNUM为常量COUNT DW 20H;定义COUNT变量,假设在数据段的偏移地址为0010H;代码段 字变量和字常量的应用:MOV AX,BX+SI+WNUM 等价于 MOV AX,BX+SI+5678H MOV AX,COUNT等价于 MOV AX,0010H;AX0020HMOV AX,SI+COUNT等价于 MOV AX,SI+0010H LEA BX,COUNT等价于 LEA BX,0010H;BX 0010HMOV BX,OFFSET COUNT等价于 MOV BX,0010H;BX 0010H,字变量和字常量实例,例.数据复制20次和显示,;数据段source db 33h,34h,35h,36h;定义4个字符数据target db 80 dup(?);分配数据空间420=80;代码段mov ax,dsmov es,ax;data也作为附加段cldmov si,offset sourcemov di,offset targetmov cx,80rep movsb;串传送mov si,0;显示mov bx,offset targetagain:mov dl,bx+si mov ah,2int 21hinc sicmp si,80jc again,movsb,int 21h,串操作类指令,8088的串操作类指令能对主存中一个连续区域的数据(如数组、字符串等)进行传送、比较等同样操作。当DF=0 地址自动增量,从低地址到高地址处理字符串;当DF=1地址减量指令有:传送数据串:MOVS,STOS,LODS检测数据串:CMPS,SCAS重复前缀:REP,REPZ,REPNZ源操作数-DS:SI 目的操作数-ES:DI每执行一次串操作指令,SI和DI将自动修改:1(对于字节串)或2(对于字串)执行指令CLD后,DF=0,地址指针增1或2执行指令STD后,DF=1,地址指针减1或2利用循环程序也可以实现串操作指令的功能,例:MOVSB(move string byte);ES:DIDS:SI;当DF=0,SISI+1 DIDI+1 当DF=1,SISI-1 DIDI-1,例.数据复制和显示,.model small.stack.datasource db 33h,34h,35h,36h;定义4个字符数据target db 80 dup(?);分配数据空间420=80.code.startupmov ax,dsmov es,ax;data也作为附加段cldmov si,offset sourcemov di,offset targetmov cx,80rep movsb;串传送mov si,0;显示mov bx,offset targetagain:mov dl,bx+si mov ah,2int 21hinc sicmp si,80jb again.exit 0end,3.宏(Macro)命令伪指令,为简化程序编制,对多次使用的程序,既可用子程序也可用宏指令、宏汇编实现宏定义 宏是具有宏命令名的一段汇编语句序列宏命令名 MACRO 形参数1,参数2,;宏定义体(硬指令、伪指令)ENDM宏调用 宏命令名 实参数1,参数2,宏需要先定义,然后才可在程序中宏调用,形式上类似其他指令,常称其为宏指令宏指令实际上是一段代码序列的缩写。在汇编时,宏指令被汇编程序用对应的代码序列替代,这就是宏展开因为是在汇编过程中实现的宏展开,所以常称为宏汇编,宏命令伪指令实例:,*子程序设计;主程序mov al,datacall dpchar;子程序 AL左移4位dpcharprocmovcl,4salal,cl retdpcharendp,*宏调用mov al,datadpchar;宏定义:AL左移4位dpcharmacromovcl,4salal,cl endm,dpcharmacro;宏定义movcl,4salal,cl endm.model small.stack.code.startupmov al,datadpchar;宏调用.exit 0end,宏与子程序的比较,比较,仅是源程序级的简化:宏调用在汇编时进行程序语句的展开,不需要返回;不减小目标程序,执行速度没有改变,还是目标程序级的简化:子程序调用在执行时由CALL指令转向、RET指令返回;形成的目标代码较短,执行速度减慢,宏,子程序,定位伪指令,定位伪指令控制数据的偏移地址ORG 参数ORG伪指令是将当前偏移地址指针指向参数表达的偏移地址:ORG 100h;从100h处安排数据或程序ORG$+10;使偏移地址加10,即跳过10个字节空间MASM中,符号“$”表示当前偏移地址值EVEN;从偶地址开始ALIGN n;从n的整数倍地址开始,三.汇编语言的运算符变量和标号的属性,变量和标号具有逻辑地址和类型属性,汇编程序提供有关的操作符,以便获取这些属性值变量例 sum db 02h mov al,sum标号例 done:mov al,02h Jmp done逻辑地址属性 取值运算符SEG和OFFSET变量和标号对应存储单元的逻辑地址逻辑地址包含:段地址和偏移地址例:mov ax,offset sum类型属性 属性运算符PTR变量名的类型可以是BYTE(字节)、WORD(字)和DWORD(双字)等;标号、段名、子程序名的类型可以是NEAR(近)和FAR(远),分别表示段内或段间调用例:dec word ptr sum,取值运算符SEG和OFFSET,取得名字或标号的段地址和偏移地址,例:Alphadb30h,33hmovbx,offset alphamoval,bx+1 movcx,bx,;al33h,;cx3330h,org$+10arraydb 45,45h.codemov ax,seg arraymov ds,axmov bx,offset array;等价于 lea bx,arraymov cl,array+4;等效于 mov cl,array4mov ax,es:2000h,地址操作符实例,属性运算符PTR,对名字或标号的类型属性进行设置类型名 PTR 名字/标号类型名可以是BYTE、WORD、DWORD(依次表示字节、字、双字)等,或者是NEAR、FAR(分别表示近、远)定义的类型 例:mov al,byte ptr var;var是一个字节变量 jmp far ptr label;label是一个标号 dec word ptr di inc byte ptr di使用PTR操作符,可以临时改变名字或标号的类型,8088CPU的存储格式-小端存储方式,低地址,LSB,MSB,00002H单元的内容为:00002H=34H00002H“字”单元的内容为:00002H=1234H00002H号“双字”单元的内容为:00002H=78561234H,多字节数据在存储器中占连续的多个存储单元存放:低字节存入低地址,高字节存入高地址表达:用低地址表示多字节数据占据的地址空间同一个存储器地址可以是字节单元地址、字单元地址、双字单元地址等等,设DS=000002H“双字”单元 MOV EAX,0002H00002H“字”单元 MOV AX,0002H00002H单元 MOV AH,0002H,高地址,存储单元,存储器地址,.model small.stack.datav_byteequ this byte;v_byte是字节类型,与变量v_word的地址相同v_worddw 3332h,3735h;v_word是字类型的变量targetdw 5 dup(20h);分配数据空间2510字节crlfdb 0dh,0ah,$flagdb 0n_pointdw offset s_label;取得标号s_label的偏移地址,例3.4:属性及其应用1/5,例3.4:属性及其应用2/5,.code.startupmov al,byte ptr v_word;用PTR改变v_word的类型,否则类型不匹配dec almov v_byte,al;对v_word的头一个字节操作,原为32H、现为31Hn_label:cmp flag,1jz s_label;flag单元为1转移inc flagjmp n_label;进行短转移,例3.4:属性及其应用3/5,s_label:cmp flag,2jz next;flag单元为2转移inc flagjmp n_point;段内的存储器间接寻址,转移到s_label标号处next:mov ax,type v_word;汇编结果为mov ax,2mov cx,lengthof target;汇编结果为mov cx,5,例3.4:属性及其应用4/5,mov si,offset targetw_again:mov si,ax;对字单元操作inc si;SI指针加2inc siloop w_again;循环mov cx,sizeof target;汇编结果为 mov cx,0ahmov al,?mov di,offset targetb_again:mov di,al;对字节单元操作inc di;DI指针加1loop b_again;循环,例3.4:属性及其应用5/5,mov dx,offset v_word;显示结果:1357?mov ah,9int 21h.exit 0end,四.汇编语言源程序结构,完整的汇编语言源程序由段组成一个汇编语言源程序可以包含若干个代码段、数据段、附加段或堆栈段,段与段之间的顺序可随意排列需独立运行的程序必须包含一个代码段,并指示程序执行的起始点,一个程序只有一个起始点所有的硬指令语句必须位于某一个代码段内,伪指令语句可根据需要位于任一段内通常,程序还需要一个堆栈段,源程序由语句序列构成,汇编语言翻译器(汇编程序,如MASM)对源程序有严格格式要求,才能将之翻译成目的代码,段寄存器及逻辑段分配,段寄存器及逻辑段分配,8088CPU访问内存有20条地址线共 220B=1MB个存储单元FFFFFH,内存地址00000HFFFFFH8088CPU将1MB空间分成许多段,有4个16位段寄存器,对应4种逻辑段.每个段最大限制为64KBCode Segment 代码段Stack Segment 堆栈段Data Segment 数据段Extra Segment 附加段8088有4个16位段寄存器CS(Code Segment Register)指令SS(Stack Segment Register)堆栈DS(Data Segment Register)数据ES(Extra Segment Register)数据每个段寄存器用来确定一个逻辑段的起始地址,每种逻辑段均有各自的用途程序的指令序列必须安排在代码段CS程序使用的堆栈一定在堆栈段SS程序中的数据默认是安排在数据段DS,也经常安排在附加段ES,尤其是串操作的目的区必须是附加段,汇编语言源程序格式,源程序分别用两种格式书写第一种格式从MASM 5.0开始支持简化段定义格式第二种格式MASM 5.0以前就具有完整段定义格式(一般了解),求较大值两无符号数AX、BX的较大值放入 wmax,简单,要求掌握,求较大值两无符号数AX、BX的较大值放入wmax,汇编语言程序实例,wmaxdw 0cmp ax,bx;比较AX和BXjnc next;若AXBX,转移xchg ax,bx;若AXBX,交换next:mov wmax,ax,简化段定义格式求较大值两无符号数AX、BX的较大值放入wmax,.model small.data;定义数据段wmaxdw 0.code;定义代码段start:mov ax,data;程序起始点,建立DSmov ds,ax cmp ax,bx;比较AX和BXjnc next;若AXBX,转移xchg ax,bx;若AXBX,交换next:mov wmax,ax.exit 0;程序正常执行结束end start;汇编结束,程序,数据定义,汇编语言程序实例,stacksegment stack;定义堆栈段dw 512 dup(?);堆栈段有512字(1024字节)空间stackends;堆栈段结束datasegment;定义数据段wmax dw 0dataendscodesegment code;定义代码段assume cs:code,ds:data,ss:stackstart:mov ax,data;建立DS段地址mov ds,axcmp ax,bx;比较AX和BXjnc next;若AXBX,转移xchg ax,bx;若AXBX,交换next:mov wmax,axmov ax,4c00hint 21h;利用功能调用返回DOScodeends;代码段结束end start;汇编结束,同时指明程序起始点,例:完整段定义格式,完整段定义格式程序例题,stacksegment stackdw 512 dup(?)stackendsdatasegment;数据定义(数据待填)dataendscodesegment codeassume cs:code,ds:data,ss:stackstart:mov ax,datamov ds,ax;主程序(指令待填)mov ax,4c00hint 21h;子程序(指令待填)codeendsend start,完整段定义格式 MASM 5.x支持,源程序格式(一般了解),例题,源程序格式(重点掌握),.model small;定义程序的存储模式.data;定义数据段;在数据段定义数据.code;定义代码段.startup;程序起始点,设置DS、SS;主程序(指令待填).exit 0;程序结束点,返回DOS;子程序(指令待填)end;汇编结束,温馨提示:可以无数据段,常用简化段定义格式 MASM 6.x支持,例题,或者源程序格式(重点掌握),.model small;定义程序的存储模式.data;定义数据段;在数据段定义数据.code;定义代码段start:mov ax,data;程序起始点,设置数据段段地址DSmov ds,ax;主程序(指令待填).exit 0;程序结束点,返回DOS;子程序(指令待填)end start;汇编结束,温馨提示:可以无数据段,常用简化段定义格式 MASM 6.x支持,例题,1.简化段定义格式(1)源程序格式,数据段定义伪指令.DATA创建一个数据段代码段定义伪指令.CODE创建一个代码段堆栈段由Windows维护,用户不必设置程序开始执行的位置应用一个标号(例如:START)汇编结束END指令的参数应用程序执行结束语句“EXIT 0”将控制权交还操作系统提供给操作系统一个返回代码通常用0表示执行正确源程序汇编结束END语句,执行结束汇编结束,;SampleA.ASM.model small.stack.data.;在数据段定义数据.code.startup.;在代码段填入指令序列.exit 0.;子程序代码end,简化段定义格式 MASM 6.x支持,;SampleC.ASM.model small.stack.data.;在数据段定义数据.codestart:mov ax,datamov ds,ax.;在代码段填入指令序列mov ax,4c00hint 21h.;子程序代码end start,简化段定义格式 MASM 5.x支持,.model small;定义程序的存储模式.data;定义数据段.code;定义代码段.exit 0;程序结束点,返回DOSend;汇编结束,(2)简化段定义格式伪指令,存储模式伪指令,.MODEL 存储模式,使用简化段定义,必须有存储模式伪指令.model语句必须位于所有段定义语句之前存储模式决定一个程序的规模,确定进行子程序调用、指令转移和数据访问的缺省属性MASM有7种不同的存储模式:TINY SMALL COMPACT MEDIUM LARGE HUGE FLAT,SMALL小型模式,一般的程序(例如本书的绝大多数程序示例和习题)都可用这种模式在小型模式下,一个程序至多只能有一个代码段和一个数据段,每段不大于64KB这里的数据段是指数据段、堆栈段和附加段的总和,它们共用同一个段基址,总长度不可超过64KB;因此小模式下程序的最大长度为128KB访问操作数或指令都只需要使用16位偏移地址;这意味着诸如指令转移、程序调用以及数据访问等都是近属性(NEAR),即小型模式下的调用类型和数据指针缺省分别为近调用和近指针,简化段定义伪指令,.STACK 大小;堆栈段开始.DATA;数据段开始.CODE 段名;代码段开始,简化段定义伪指令指明一个逻辑段的开始,同时自动结束前面的一个段采用简化段定义伪指令前,需有.model语句使用简化段定义,各段名称和其他用户所需的信息可以使用MASM预定义符号,例如:data表示由.data等定义的数据段的段名,堆栈段伪指令,.STACK 大小堆栈段伪指令.STACK创建一个堆栈段,段名是:stack它的参数指定堆栈段所占存储区的字节数,默认是1KB(=1024=400h字节),数据段伪指令,.DATA数据段伪指令.data创建一个数据段,段名是:_DATA。它用于定义具有初值的变量,当然也允许定义无初值的变量无初值变量可以安排在另一个段中,它用.data?伪指令创建,数据段名是:_BSS.const伪指令用于建立只读的常量数据段(段名:CONST),代码段伪指令,.CODE 段名代码段伪指令.code创建一个代码段,它的参数指定该代码段的段名如果没有给出段名,则采用默认段名:在TINY、SMALL、COMPACT和FLAT模式下,默认的代码段名是:_TEXT在MEDIUM、LARGE和HUGE模式下,默认的代码段名是:模块名_TEXT,程序开始伪指令,.STARTUP,按照CPU类型、存储模式、操作系统和堆栈类型,产生程序开始执行的代码;同时还指定程序开始执行的起始点在DOS下,还将设置DS值,调整SS和SP值,mov dx,dgroupmov ds,dx;设置DSmov bx,sssub bx,dxshl bx,1shl bx,1shl bx,1shl bx,1cli;关中断mov ss,dx;调整SS和SPadd sp,bxsti;开中断,mov dx,datamov ds,dx,程序终止伪指令,.EXIT 返回参数,产生终止程序执行返回操作系统的指令代码它的可选参数是一个返回的数码,通常用0表示没有错误。例如.exit 0对应的代码是:mov ax,4c00hint 21hDOS功能调用的4ch子功能(返回DOS):入口参数:AH4ch,AL返回数码,汇编结束伪指令,END 标号,指示汇编程序MASM到此结束汇编过程源程序的最后必须有一条END语句可选的标号用于指定程序开始执行点,连接程序将据此设置CS:IP值采用了.startup伪指令就不需要再用“end 标号”指明开始执行点,但还要有end伪指令,不要糊涂程序终止和汇编结束是两码事,;主程序mov al,04h;提供参数ALcall htoasc;调用子程序 retp1:mov bl,0fh;retp1为返回地址hlt;子程序:将AL低4位的一位16进制数转换成ASCII码htoasc:and al,0fh;只取al的低4位or al,30h;al高4位变成3cmp al,39h;是09,还是0Ah0Fhjc htendadd al,7;是0Ah0Fh,加上7htend:ret;子程序返回,ASCII码 0=30h 9=39h A=41h B=42h,ACII码转换子程序调用程序,.model small;定义程序的存储模式.code;定义代码段start:mov ax,data;程序起始点,建立DSmov ds,ax mov al,04h;提供参数AL call htoasc;调用子程序retp1:mov bl,0fh;retp1为返回地址hlt.exit 0;程序正常执行结束htoasc:;子程序将AL低4位转换成ASCII码and al,0fh;只取al的低4位or al,30h;al高4位变成3cmp al,39h;是09,还是0Ah0Fhjc htendadd al,7;是0Ah0Fh,加上7htend:ret;子程序返回end start;汇编结束,简化段定义格式-例1 ACII码转换子程序调用程序,无数据段,主程序,子程序,编程实现将sum开始的8个无符号数的和放至bpt开始的两个存储单元中,;数据段sumdb 8 dup(2)bptdw?;存放最大值;代码段,movcx,8movsi,offset sum;存放无符号数的存储单元首地址赋给sixorax,ax;ax及进位CF清零done:addal,siadcah,0incsi;指向下一个无符号数的存储单元地址 loop done;cx-1 0 转向donemovbx,offset bpt;cx-1=0(8个无符号数已求完和)bxbpt 偏移地址 mov bx,ax;则将此和放至bpt存储单元hlt,循环程序结构,loop,循环指令,循环指令用于控制程序的重复执行,根据CX(存放循环次数)决定循环(转移至目标地址label)还是顺序执行(下一条指令)循环指令LOOP label CX-1 0,则转移(首先CXCX1;然后判断若CX0,转移到label;否则,顺序执行)LOOPZ/LOOPE label CX-1 0 且ZF=1,则转移 LOOPNZ/LOOPNE label CX-1 0 且ZF=0,则转移JCXZ label CX0,则转移,dec ecxjnz label,简化段定义格式-例2编程实现将sum开始的8个无符号数的和放至bpt开始的两个存储单元中,.model small.data;定义数据段sumdb 8 dup(2)bptdw?;存放最大值.code;定义代码段start:mov ax,data;程序起始点,建立DSmov ds,ax movcx,8movsi,offset sum;存放无符号数的存储单元首地址赋给sixorax,ax;ax及进位CF清零done:addal,siadcah,0incsi;指向下一个无符号数的存储单元地址Loop done;cx-1 0 转向done movbx,offset bpt;cx-1=0(8个无符号数已求完和)bxbpt 偏移地址 mov bx,ax;则将此和放至bpt存储单元 hlt.exit 0;程序正常执行结束end start;汇编结束,程序,数据定义,完整段定义伪指令,段名segment 定位 组合 段字 类别.;语句序列段名ends,完整段定义由SEGMENT和ENDS这一对伪指令实现,SEGMENT伪指令定义一个逻辑段的开始,ENDS伪指令表示一个段的结束段定义指令后的4个关键字用于确定段的各种属性,堆栈段要采用stack组合类型,代码段应具有code类别,其他为可选属性参数如果不指定,则采用默认参数;但如果指定,注意要按照上列次序,2.完整段定义格式,完整段定义利用SEGMENT和ENDS一对伪指令定义逻辑段同时需要配合ASSUME伪指令指明逻辑段是代码段、堆栈段、数据段还是附加段程序设计中常将具有一定功能的程序设计成一个过程。代码段中可有若干个过程,指定段寄存器伪指令,ASSUME 段寄存器:段名,段寄存器名:段名,.,通知MASM用指定的段寄存器来寻址对应的逻辑段,即建立段寄存器与段的缺省关系在明确了程序中各段与段寄存器之间的关系后,汇编程序会根据数据所在的逻辑段,在需要时自动插入段超越前缀。这是ASSUME伪指令的主要功能ASSUME伪指令并不为段寄存器设定初值,连接程序LINK将正确设置CS:IP和SS:SP由于数据段通常都需要,所以在样板源程序中,首先为DS赋值;如果使用附加段,还要赋值ES,stacksegment stackdw 512 dup(?)stackendsdatasegment;在数据段定义数据dataendscodesegment codeassume cs:code,ds:data,ss:stackstart:mov ax,datamov ds,ax;主程序(指令待填)mov ax,4c00hint 21h;子程序(指令待填)codeendsend start,完整段定义格式 MASM 5.x支持,源程序格式(一般了解),例题,例:完整的汇编语言源程序实例,例:将0500H开始的10个字节无符号数的和放至050AH、050BH单元中,movcx,10movsi,0500h;存放无符号数的存储单元首地址赋给sixorax,ax;ax及进位CY清零done:addal,siadcah,0incsi;指向下一个无符号数的存储单元地址 loop done;cx-1 0 转向donemovbx,050ah;cx-1=0(10个无符号数已求完和),bx050ah mov bx,ax;则将此和放至050AH、050BH存储单元,完整的汇编语言源程序 还需有以下处理:段定义过程汇编结束 end,加过程处理,movcx,10movsi,0500h;存放无符号数的存储单元首地址赋给sixorax,ax;ax及进位CY清零done:addal,siadcah,0incsi;指向下一个无符号数的存储单元地址 loop done;cx-1 0 转向donemovbx,050ah mov 050ah,ax;和放至050AH、050BH存储单元,startprocfar pushdsmovax,0pushax,retstart endp,将0500H开始的10个无符号数的和放至050AH、050BH单元中,过程定义伪指令,程序设计中常将具有一定功能的程序设计成一个过程。过程语句格式 过程名 proc near或far(过程属性)过程名 endp为了使程序结束后能返回DOS系统,需:过程名procfar pushds movax,0pushax ret 过程名 endp 这样当该过程的程序运行完毕,便执行DS:0000H处的返回到DOS管理状态的指令,push书51ret,子程序返回指令RET(reture),RET;无参数返回RET i16;有参数返回,除执行RET指令外 还SPSPi16(16位立即数)RET指令放子程序末尾,执行时将堆栈中的返回地址出栈送IP(段内和段间调用)和CS(仅段间调用),使子程序执行完毕能返回主程序弹出CALL指令压入堆栈的返回地址段内返回出栈偏移地址IPIPSS:SP,SPSP2段间返回出栈偏移地址IP和段地址CSIPSS:SP,SPSP2CSSS:SP,SPSP2,startprocfar pushdsmovax,0pushaxmovcx,10movsi,0500h;存放无符号数的存储单元首地址赋给sixorax,ax;ax及进位CY清零done:addal,siadcah,0incsi;指向下一个无符号数的存储单元地址 loop done;cx-1 0 转向donemov bx,050ah mov bx,ax;和放至050AH、050BH存储单元retstart endp,ssegsegmentdb256dup(0)ssegends csegsegmentassume cs:cseg,ds:dseg,ss:sseg,加段定义,代码段,堆栈段,csegendsendstart;汇编结束,段定义,完整的汇编语言源程序分为代码段、数据段(可选)、堆栈段、附加段(可选),分别装入CS、DS、SS、ES段寄存器指定的物理段段定义语句格式 段名 segment 段名 ends伪指令ASSUME指明各段和段寄存器之间的关系 例:dsegsegment sumdb0dsegendsssegsegment para stack ssegdb256dup(0)ssegends;堆栈段 csegseg