1、作业:P112 1、2 实验教程 P60 4,第4章 汇编语言程序设计基本技术,教学重点,综合应用第2章硬指令和第3章伪指令,第4章从程序结构角度展开程序设计,重点掌握: 分支结构程序设计 循环结构程序设计,汇编语言程序设计的过程通常都包括以下步骤:,1. 分析问题,确定算法,2. 编制程序流程,3. 正确、合理使用存贮器和寄存器,4. 编写程序,5. 调试运行程序,程序的基本结构形式有:顺序程序、分支程序、循环程序和子程序。,顺序程序的最大特点:程序从运行开始到结尾一直是按顺序逐条执行指令,且每条指令只执行一次。,4.1 顺序程序设计,顺序程序完全按指令书写的前后顺序执行每一条指令,是最基本
2、、最常见的程序结构,例4.1 计算,例4.2 移位,例题 代码转换,例4.1-1,.model small.stack.dataX dw 5Y dw 6Z dw 7W dw ?,.code.startupmov ax,Xadd ax,Yadd ax,Zmov W,ax.exit 0end,data segmentX dw 5Y dw 6Z dw 7W dw ?data endscode segmentassume cs:code,ds:datastart: push ds ;保存旧的数据段地址sub ax,axpush ax,例4.1-2,mov ax, data ;将data数据段地址mov
3、 ds, ax ;送往ds段寄存器mov ax, Xadd ax, Yadd ax, Zmov W, ax mov ah, 4ch int 21h ;返回DOS code endsend start,例4.21/2,.data qvar dq 1234567887654321h ;定义4字变量.code.startupmov al,byte ptr qvar6mov byte ptr qvar7,almov al,byte ptr qvar5mov byte ptr qvar6,almov al,byte ptr qvar4mov byte ptr qvar5,almov al,byte pt
4、r qvar3mov byte ptr qvar4,almov al,byte ptr qvar2mov byte ptr qvar3,al,图示,例4.22/2,mov al,byte ptr qvar1mov byte ptr qvar2,almov al,byte ptr qvar0mov byte ptr qvar1,almov byte ptr qvar0,0.exit 0end,12 34 56 78 87 65 43 21h,34 56 78 87 65 43 21 00h,移位后,图示,64位数据左移8位,12,34,56,78,87,65,43,21,00,qvar0,qva
5、r1,qvar2,qvar3,qvar4,qvar5,qvar6,qvar7,换码指令执行前: 在主存建立一个字节量表格,内含要转换成的目的代码 表格首地址存放于BX,AL存放相对表格首地址的位移量 换码指令执行后: 将AL寄存器的内容转换为目的代码,换码指令XLAT(translate),将BX指定的缓冲区中、AL指定的位移处的一个字节数据取出赋给AL,XLAT,XLAT ;alds:bx+al,例:代码转换,mov bx,100h mov al,03h xlat,换码指令没有显式的操作数,但使用了BX和AL;因为换码指令使用了隐含寻址方式采用默认操作数,XLAT,例题 代码转换1/2,;查
6、表法,实现一位16进制数转换为ASCII码显示.model small.stack 256.data ASCII db 30h,31h,32h,33h,34h,35hdb 36h,37h,38h,39h ;09的ASCII码db 41h,42h,43h,44h,45h,46h;AF的ASCII码 hex db 0bh;任意设定了一个待转换的一位16进制数,例题 代码转换2/2,.code.startupmov bx,offset ASCII ;BX指向ASCII码表mov al,hex;AL取得一位16进制数,正是ASCII码表中位移and al,0fh ;只有低4位是有效的,高4位清0xla
7、t ;换码:ALDS:BXALmov dl,al ;入口参数:DLALmov ah,2 ;02号DOS功能调用int 21h ;显示一个ASCII码字符.exit 0end,4.2 输入输出功能调用,向显示器输出字符 字符的输出 字符串的输出 从键盘输入数据 字符的输入 字符串的输入 按键的判断,4.2.1 中断指令,中断(Interrupt )是一种改变程序执行顺序的方法 中断具有多种中断类型 中断的指令有3条: INT i8 IRET INTO 本节主要掌握类似子程序调用指令的中断调用指令INT i8,进而学习使用DOS功能调用,中断的过程,主程序,IRET,中断服务程序,断点,中断请求,
8、中断请求可以来自处理器外部的中断源,也可以由处理器执行指令引起: 例如执行INT i8指令。,8086的外部中断,8086可以管理256个中断 各种中断用一个向量编号来区别 主要分成外部中断和内部中断 外部中断来自CPU之外的原因引起的中断,又可以分成 可屏蔽中断:可由CPU的中断允许标志IF控制 非屏蔽中断:不受CPU的中断允许标志IF控制,8086的内部中断,内部中断CPU内部执行程序引起的中断,又可以分成: 除法错中断:执行除法指令,结果溢出产生的 0 号中断 指令中断:执行中断调用指令INT i8产生的 i8 号中断 断点中断:用于断点调试(INT 3)的 3 号中断 溢出中断:执行溢
9、出中断指令,OF1产生的 4 号中断 单步中断:TF1在每条指令执行后产生的 1 号中断,中断指令INT,INT i8 ;中断调用指令:产生i8号中断 IRET ;中断返回指令:实现中断返回 INTO ;溢出中断指令: ;若溢出标志OF=1,产生4号中断 ;否则顺序执行,4.2.2 系统功能调用,21H号中断是DOS提供给用户的用于调用系统功能的中断,它有近百个功能供用户选择使用,主要包括设备管理、目录管理和文件管理三个方面的功能 ROM-BIOS也以中断服务程序的形式,向程序员提供系统的基本输入输出程序 汇编语言程序设计需要采用系统的各种功能程序 充分利用操作系统提供的资源是程序设计的一个重
10、要方面,需要掌握,功能调用的步骤,通常按照如下4个步骤进行: 在AH寄存器中设置系统功能调用号 在指定寄存器中设置入口参数 执行指令INT 21H(或ROM-BIOS的中断向量号),实现中断服务程序的功能调用 根据出口参数,分析功能调用执行情况,字符输出的功能调用,DOS功能调用INT 21H 功能号:AH02H 入口参数:DL字符的ASCII码 功能:在显示器当前光标位置显示给定的字符,光标右移一个字符位置。如按Ctrl-Break或Ctrl-C则退出,例:显示问号,;在当前显示器光标位置显示一个问号 mov ah,02h ;设置功能号:ah02h mov dl,? ;提供入口参数:dl?
11、int 21h ;DOS功能调用:显示,进行字符输出时,当输出响铃字符(07H)以及退格(08H)、回车(0DH)和换行(0AH)字符时,该功能调用可以自动识别并能进行相应处理,字符串输出的功能调用,DOS功能调用INT 21H 功能号:AH09H 入口参数: DS:DX欲显示字符串在主存中的首地址 字符串应以$(24H)结束 功能:在显示器输出指定的字符串 可以输出回车(0DH)和换行(0AH)字符产生回车和换行的作用,例:显示字符串,string db Hello,Everybody !,0dh,0ah,$;在数据段定义要显示的字符串.mov ah,09h;设置功能号:ah09hmov d
12、x,offset string;提供入口参数:dx字符串的偏移地址int 21h;DOS功能调用:显示,字符输入的功能调用,DOS功能调用INT 21H 功能号:AH01H 出口参数:AL字符的ASCII码 功能:获得按键的ASCII代码值 调用此功能时,若无键按下,则会一直等待,直到按键后才读取该键值,例:字符输入+判断按键,getkey: mov ah,01h ;功能号:ah01hint 21h ;功能调用cmp al,Y ;处理出口参数alje yeskey ;是“Y”cmp al,Nje nokey ;是“N”jne getkey. yeskey: . nokey: .,字符串输入的功
13、能调用,DOS功能调用INT 21H 功能号:AH0AH 入口参数:DS:DX缓冲区首地址 执行该功能调用时,用户按键,最后用回车确认 本调用可执行全部标准键盘编辑命令;用户按回车键结束输入,如按CtrlBreak或CtrlC则中止,关键要定义好缓冲区,缓冲区的定义,第1字节事先填入最多欲接收的字符个数(包括回车字符,可以是1255) 第2字节将存放实际输入的字符个数(不包括回车符) 第3字节开始将存放输入的字符串 实际输入的字符数多于定义数时,多出的字符丢掉,且响铃 扩展ASCII码(如功能键等)占两个字节,第1个为0,例: 输入字符串,buffer db 81 ;缓冲区长度;第1个字节填入
14、可能输入的最大字符数db ? ;保留为填入实际输入的字符数db 81 dup(0) ;存放输入的字符串.mov dx,seg buffer;伪指令seg取得buffer的段地址mov ds,dx ;设置数据段DSmov dx,offset buffermov ah,0ahint 21h,按键判断的功能调用,DOS功能调用INT 21H 功能号:AH0BH 出口参数:AL0,当前没有按键;ALFFH,当前已经按键。 功能:仅判断当前是否有按下的键,设置AL后退出,例: 按任意键继续,. ;提示“按任意键继续” getkey: mov ah,0bhint 21hor al,al ;al0?jz g
15、etkey;al0,没有按键,继续等待,4.3 分支程序设计,分支程序根据条件是真或假决定执行与否 判断的条件是各种指令,如CMP、TEST等执行后形成的状态标志 转移指令Jcc和JMP可以实现分支控制,单分支:求绝对值,双分支:例4.3,多分支:例4.4,单分支程序设计,条件成立跳转,否则顺序执行分支语句体 注意选择正确的条件转移指令和转移目标地址,例题 求绝对值,;计算AX的绝对值cmp ax,0jns nonneg ;分支条件:AX0neg ax ;条件不满足,求补 nonneg: mov result,ax ;条件满足 ;计算AX的绝对值cmp ax,0jl yesneg ;分支条件:
16、AX0jmp nonneg yesneg: neg ax ;条件不满足,求补 nonneg: mov result,ax ;条件满足,Good,Bad,双分支程序设计,条件成立,跳转执行第2个分支语句体;否则顺序执行第1个分支语句体 注意:第1个分支体后一定要有一个JMP指令跳到第2个分支体后,例题 显示BX最高位,shl bx,1 ;BX最高位移入CFjc one ;CF1,即最高位为1,转移mov dl,0;CF0,即最高位为0,DL0jmp two ;一定要跳过另一个分支体 one: mov dl,1 ;DL1 two: mov ah,2int 21h ;显示,对比,双分支程序改为单分支
17、程序,例题 显示BX最高位,shl bx,1 ;BX最高位移入CFjnc one ;CF0,即最高位为0,转移mov dl,1;CF1,即最高位为1,DL1jmp two ;一定要跳过另一个分支体 one: mov dl,0 ;DL0 two: mov ah,2int 21h ;显示,双分支程序改为单分支程序,对比,例题 显示BX最高位,mov dl,0 ;DL0shl bx,1 ;BX最高位移入CFjnc two ;CF0,最高位为0,转移mov dl,1 ;CF1,最高位为1,DL1 two: mov ah,2int 21h ;显示,编写分支程序,需留心分支的开始和结束,例4.3 判断有无
18、实根1/2,.startup mov al,_b imul al mov bx,ax ;BX中为b2 mov al,_a imul _c mov cx,4 imul cx ;AX中为4ac(设DX中无有效数据),例4.3 判断有无实根2/2,cmp bx,ax ;比较二者大小jge yes ;条件满足?mov tag,0;第一分支体:条件不满足,tag0jmp done ;跳过第二个分支体 yes: mov tag,1;第二分支体:条件满足,tag1 done: .exit 0,多分支程序设计,多个条件对应各自的分支语句体,哪个条件成立就转入相应分支体执行。多分支可以化解为双分支或单分支结构的
19、组合,例如:or ah,ah ;等效于cmp ah,0jz function0 ;ah0,转向function0dec ah ;等效于cmp ah,1jz function1 ;ah1,转向function1dec ah ;等效于cmp ah,2jz function2 ;ah2,转向function2,图示,多分支结构,种类,条件转移指令,判断条件,条件组合关系,OF SF ZF PF CF,简单条件转移指令,JO JNO,JS JNS,JZ/JE JNZ/JNE,JP/JPE JNP/JPO,JC JNC,JA/JNBE JAE/JNB,JB/JNAE JBE/JNA,JG/JNLE JG
20、E/JNL,JL/JNGE JLE/JNG,无符号数条件转移指令,带符号数条件转移指令,1 0,1 0,1 0,1 0,1 0,0 0,0 1,0 1,11,a a,bb,0 1,0 1,a a,bb,AND OR,AND OR,(a=b) AND ZF=0 (a=b) OR ZF=1,(ab) AND ZF=0 (ab) OR ZF=1,地址表形成多分支,需要在数据段事先安排一个按顺序排列的转移地址表 输入的数字作为转移地址表内的偏移量。16位偏移地址占用2个字节单元,所以偏移量需要乘2 关键是要理解间接寻址方式JMP指令,.data msg db Input number(18):,0dh
21、,0ah,$ msg1 db Chapter 1 : .,0dh,0ah,$ msg2 db Chapter 2 : .,0dh,0ah,$. msg8 db Chapter 8 : . ,0dh,0ah,$ table dw disp1,disp2,disp3,disp4dw disp5,disp6,disp7,disp8;定义各个标号的偏移地址,例4.4 数据段1/3,.code .startup start1: mov dx,offset msg mov ah,9 ;显示“Input number(18):”int 21hmov ah,1 ;等待按键输入int 21hcmp al,1 ;
22、数字 8?ja start1and ax,000fh ;将ASCII码转换成数字,例4.4 代码段2/3,dec ax ;偏移量从0开始shl ax,1 ;等效于add ax,ax 即变为偶数mov bx,axjmp tablebx ;(段内)间接转移:IPtable+bx start2: mov ah,9 ;显示字符串int 21h.exit 0 disp1: mov dx,offset msg1 ;处理程序1jmp start2.end,例4.4 代码段3/3,AH=9时,INT 21H的功能是显示字符串,要求必须以$字符作为定界符,来计算串的长度。 显示字符串时,如果希望光标能自动换行,
23、则可在字符串结束前加上回车(0dH)和换行(0aH)的ASCII码。,作业:实验教程 P61 13P62 34,例:有数组 x(x1,x2,x10) 和 y(y1,y2,y10),编程计算 z(z1,z2,z10)z1 = x1 + y1 z2 = x2 + y2 z3 = x3 - y3 z4 = x4 - y4 z5 = x5 - y5 z6 = x6 + y6 z7 = x7 - y7 z8 = x8 - y8 z9 = x9 + y9 z10= x10 + y10,.data x dw x1,x2,x3,x4,x5,x6,x7,x8,x9,x10 y dw y1,y2,y3,y4,y5
24、,y6,y7,y8,y9,y10 z dw z1,z2,z3,z4,z5,z6,z7,z8,z9,z10 logic_rule dw 00dch ;逻辑尺: 0000,0000,1101,1100; 1 减法0 加法, mov bx, 0 ;设置数组内偏移量mov cx, 10 ;设置计数器mov dx, logic_rule next: mov ax, xbxshr dx, 1 ;判断逻辑尺最低位jc subtract ;为1,进行减法add ax, ybx ;为0,进行加法jmp short result ;存结果 subtract: sub ax, ybx result: mov zbx
25、, axadd bx, 2 ;设置数组内下一字单元loop next,4.4 循环程序设计,循环结构一般是根据某一条件判断为真或假来确定是否重复执行循环体 循环指令和转移指令可以实现循环控制,多重循环:例4.6,循环指令LOOP:例4.5,DO-WHILE 结构 DO-UNTIL 结构,控制条件,初始化,循环体,Y,N,控制条件,初始化,循环体,Y,N,DO-UNTIL 循环结构,循环指令(loop),循环指令默认利用CX计数器,方便实现计数循环的程序结构 label操作数采用相对寻址方式,LOOP label ;CXCX1,;CX0,循环到标号label处,LOOPZ/LOOPE label
26、 ;CXCX1,;CX0且ZF1,循环到标号label处,LOOPNZ label ;CXCX1,;CX0且ZF0,循环到标号label处,.model small.stack.data sum dw ?.code.startupxor ax,ax ;被加数AX清0mov cx,100 again: add ax,cx;从100,99,.,2,1倒序累加loop againmov sum,ax ;将累加和送入指定单元.exit 0end,例4.5 求和,计数控制循环循环次数固定,“冒泡法”是一种排序算法,不是最优的算法,但它易于理解和实现 冒泡法从第一个元素开始,依次对相邻的两个元素进行比较,
27、使前一个元素不大于后一个元素;将所有元素比较完之后,最大的元素排到了最后;然后,除掉最后一个元素之外的元素依上述方法再进行比较,得到次大的元素排在后面;如此重复,直至完成就实现元素从小到大的排序 这需要一个双重循环程序结构,图示,例4.6 冒泡法,冒泡法的排序过程,data segmentarray db 32d,85d,16d,15d,8ddata endsprognam segmentassume cs:prognam,ds:datastart:mov ax,data ;将data数据段地址mov ds,ax ;送往ds段寄存器mov cx,5 ; CX数组元素个数dec cx ; 设置外
28、循环次数,例4.8,outlp: mov dx,cx ;DX内循环次数mov bx,offset array inlp: mov al,bx ;取前一个元素cmp al,bx+1 ;与后一个元素比较jna next;前一个不大于后一个元素,则不进行交换xchg al,bx+1 ;否则,进行交换mov bx,al next: inc bx ;下一对元素dec dxjnz inlp ;内循环尾,由dx控制loop outlp ;外循环尾,由cx控制prognam endsend start,data segmentarray db 32d,85d,16d,15d,8ddata endsprogna
29、m segmentassume cs:prognam,ds:datastart:mov ax,data ;将data数据段地址mov ds,ax ;送往ds段寄存器mov cx,5 ; CX数组元素个数dec cx ; 设置外循环次数,例4.8a,outlp: mov di,cx ; 内循环次数保存到DImov bx,0 ;bx寄存器清零 inlp: mov al,arraybx ; 取前一个元素cmp al,arraybx+1 ; 与后一个元素比较jna next;前一个不大于后一个元素,则不进行交换xchg al,arraybx+1 ;否则,进行交换mov arraybx,al next: inc bx ;下一对元素loop inlp ;内循环,以CX中的数为循环次数mov cx, di ;从DI中恢复内循环次数 loop outlp ;外循环,每次CX = CX 1prognam endsend start,XLAT指令,第4章 教学要求,1. 掌握基本程序结构顺序结构、分支结构、循环结构汇编语言程序设计 2. 熟悉常见程序设计问题: 多精度运算、查表(查代码、特定值等) ASCII、BCD及十六进制数据间的代码转换 数据范围判断(09、AZ、az) 字母大小写转换;字符串传送、比较等操作,放松一下,