汇编语言程序设计(四子程序).ppt
汇编语言程序设计实验,子程序是程序的一部分,是完成特定功能的程序段,它能够在程序的任何地方被调用。在使用子程序时应注意:(1)参数的传递。子程序调用时,经常需要将一些参数传给子程序,而子程序也常常需要在运行后将结果和状态等信息回送给调用程序。这种子程序和调用程序之间的信息传送,就是参数传递。参数的传递可通过寄存器、变量、地址表、堆栈等方式进行。(2)相应寄存器内容的保护。由于CPU寄存器数量有限,子程序要用到的一些寄存器常在调用程序中也被用到,为了防止破坏调用程序中寄存器的内容,需在子程序入口处将所用到的寄存器内容压入堆栈保存;(3)子程序还可以调用别的子程序,即子程序嵌套。与子程序调用有关的CPU指令有:CALL和RET;伪指令有:PROC和ENDP。,实验四 子程序及功能调用实验,1.实验目的:掌握汇编语言子程序及功能调用结构、指令及调用方法。学习二进制数转换为十六进制数并显示的方法。2.实验内容:掌握子程序的编程格式:子程序名 PROC NEAR/FAR(子程序属性)RET 子程序名 ENDP。编写一个子程序,把一个16位二进制数用十六进制形式在屏幕上显示出来。分别运用如下2种参数传递方法,并用一个主程序验证它。采用AX寄存器传递这个16位二进制数。采用wordTEMP变量传递这个16位二进制数。3.实验用设备仪器及材料:硬件:计算机 软件:DEBUG调试软件。4.实验要求:能在DEBUG提示符下,编写简单的汇编程序。熟练掌握修改寄存器、存储单元的方法,理解段地址、偏移量的表达方式。,实验四 子程序及功能调用实验,5.实验步骤:用文件编辑器编写汇编语言程序(如:记事本),并以asm为后缀命名,如:2.asm 运行masm编译器进入dos,调入所编写的汇编程序,生成2.obj,然后用 link.exe连接2.obj文件,生成可执行文件2.exe.用DEBUG调用2.exe文件,格式为DEBUG 2.EXE 用D命令观察内存单元值用U命令观察源程序 用G命令运行程序 用T命令单步执行程序用R命令观察或修改寄存器内的值,实验四 子程序及功能调用实验,6.实验报告:同学要对本次实验课的内容加以总结,并写出自己对本次实验的体会和 收获。实验报告格式:实验名称 实验材料 实验步骤 实验总结,实验四 子程序及功能调用实验,实验原理:AX中16位二进制数对应4位十六进制数,先转换最高4位成ASCII码并显示(循环左移4位,使最高4位移到AL的低四位,使AL高4位为0,等待处理,注意事先保存原AX值,防止丢失),然后转换次高四位并显示,以此类推。最后显示“H”(表示16进制)1位十六进制(对应4位二进制)转换为ASCII码原理如下:将获得的16进制数与9H比较:若9H,则先加上30H,再加上07H,才为该数的ASCII码。,实验四 子程序及功能调用实验,高四位,次高,次低,低四位,0,4,8,12,15,AX,AX,循环左移4位 ROL AX,CL,DL,次高,次低,低四位,高四位,高四位,低四位,次高,次低,DH,DL,高四位,低四位,屏蔽DL高4位 AND DL,0FH,DL,高四位,0,高四位,3,高四位,3,判DL低4位,DL39H,DL39H,DL+07H,DL内的数送显示,显示功能调用AH=02H,DL=数,INT 21H,实验四 子程序及功能调用实验,DL+30,保存AX中的数,DX,ASCII码对照表:,低10位,高6位,实验参考程序1(寄存器传递参数):data segment wordtemp dw 105Eh;也可用二进制表示 0001 0000 0101 1110bdata endscode segment assume cs:code,ds:datastart:mov ax,data mov ds,ax mov ax,wordtemp call ALdisp mov ax,4c00h;设置功能调用 AH=4C 带返回码结束 int 21h ALdisp proc;实现al内容显示的子程序 push ax;过程中使用了AX、BX、CX和DX,寄存器内容压栈保护数据。push bx push cx push dx mov bx,4;设置移动次数,存放ASCII码地址首地址,实验四 子程序及功能调用实验,a1:mov cl,4;设置左移位数 rol ax,cl;循环左移 push ax;暂存ax里的数据,DOS功能会改变AL内容 mov dl,al;转换al的高4位 and dl,0fh;将dl中的高4位清零 or dl,30h;dl高4位变成3 cmp dl,39h jbe aldisp1;dl内的数小于等于39h转移 add dl,7;是0Ah0Fh,还要加上7aldisp1:mov ah,2;显示,ah=02表示:将dl中的内容以字符的形式输出到屏幕 int 21h;系统功能调用,至于是那种功能调用,取决于ah里的内容 pop ax;弹出栈,此时ax的内容为循环左移4位原数 dec bx;计数器减1(左移次数)jnz a1;结果不为0转移,进行下一个4位转换 mov dl,H mov ah,2;显示字符“H”int 21h pop dx pop cx pop bx pop ax ret;过程返回ALdispendp code ends end start,实验参考程序2(变量传递参数):data segment wordtemp dw 2df4hdata endscode segment assume cs:code,ds:datastart:mov ax,data mov ds,ax call ALdisp mov ax,4c00h int 21h ALdispproc;实现al内容的显示 push ax;过程中使用了AX、BX,CX和DX push bx push cx push dx mov ax,wordtemp mov bx,4,实验四 子程序及功能调用实验,a1:mov cl,4 rol ax,cl push ax mov dl,al;转换al的高4位 and dl,0fh or dl,30h;al高4位变成3 cmp dl,39h jbe aldisp1 add dl,7;是0Ah0Fh,还要加上7aldisp1:mov ah,2;显示 int 21h pop ax dec bx jnz a1 mov dl,H mov ah,2;显示 int 21h pop dx pop cx pop bx pop ax ret;过程返回ALdispendp code ends end start,实验参考程序:-aXXXX:0100 mov bx,0120;将第一个被加数的地址放入BX中。Mov si,0130;将第一个加数的地址放入SI中。Mov cx,5;设置循环次数必须放入CX中。XXXX:0109 Mov al,bx;将被加数放入AL中。Adc al,si;被加数+加数,和数放入AL中。Mov bx+20,al;将AL中的和数送到BX+20地址单元中。Inc bx;BX+1,取下一个被加数的地址。Inc si;SI+1,取下一个加数的地址。Loop 0109;CX-1,CX=0?,CX0返回0109地址。XXXX:0114 命令格式提示:用E命令修改01200124和01300134各五个单元中的数据,观察并验证数据的正确性。_e 0120 00.被加数1 00.被加数2 00.被加数3 00.被加数4 00.被加数5(修改单元数据)_e 0130 00.加 数1 00.加 数2 00.加 数3 00.加 数4 00.加 数5(修改单元数据)_d 0100 观察内存单元中存放程序的情况。_g=0100 0114运行程序(需要给出起始地址0100,中断地址0114)。_t=0100 逐条执行程序指令,注意观察cs、ip、ax、bx、cx等寄存器值的变化。,实验一 交换机的配置实验,DEBUG命令使用方法:哪一类问题可以用子程序来完成其功能?仔细观察调用子程序时,CS、IP寄存器内地址数据变化情况。观察子程序返回时堆栈SS、SI寄存器内数据的变化。分析不同参数传递方法的优缺点。,实验一 交换机的配置实验,为什么,思考问题,16.3 直接定址表,现在,我们讨论用查表的方法编写相关程序的技巧。编写子程序,以十六进制的形式在屏幕中间显示给定的byte 型数据。分析,16.3 直接定址表,分析:一个字节需要用两个十六进制数码来表示,所以,子程序需要在屏幕上显示两个ASCII 字符。我们当然要用“0”、“1”、“2”、“3”、“4”、“5”、“6”、“7”、“8”、“9”、“A”、“B”、“C”、“D”、“E”、“F”这16个字符来显示十六进制数码。,16.3 直接定址表,我们可以将一个byte的高4位和低4 位分开,分别用它们的值得到对应的数码字符。比如 2Bh,我们可以得到高4 位的值为2,低4 位的值为11。那么我们如何用这两个数值得到对应的数码字符“2”和“B”呢?,16.3 直接定址表,最简单的办法就是一个一个地比较,如下:如果数值为 0,则显示“0”;如果数值为 1,则显示“1”;:如果数值为11,则显示“B”;:我们可以看出,这样做,程序中要使用多条比较、转移指令。程序将比较长,混乱。,16.3 直接定址表,显然,我们希望能够在数值015和字符“0”“F”之间找到一种映射关系。这样我们用015间的任何数值,都可以通过这种映射关系直接得到“0”“F”中对应的字符。,16.3 直接定址表,数值09和字符“0”“9”之间的映射关系是很明显的,即:数值+30h=对应字符的ASCII值:0+30h=“0”的ASCII值 1+30h=“1”的ASCII值 2+30h=“2”的ASCII值:,16.3 直接定址表,但是,1015和“A”“F”之间的映射关系是:数值+37h=对应字符的ASCII值:10+37h=“A”的ASCII值 11+37h=“B”的ASCII值 12+37h=“C”的ASCII值:,16.3 直接定址表,可见,我们可以利用数值和字符之间的这种原本存在的映射关系,通过高 4 位和低4 位值得到对应的字符码。但是由于映射关系的不同,我们在程序中必须进行一些比较,对于大于 9 的数值,我们要用不同的计算方法。,10.7 call 和 ret 的配合使用,子程序的框架:标号:指令 ret,具有子程序的源程序的框架:,