汇编语言——子程序的参数.
《IBM PC 80X86汇编语言程序设计》PPT电子课件教案-第六章 子程序设计

《IBM PC 80X86汇编语言程序设计》
冶金工业出版社
第6章
1、子程序的概念和特点
子程序:把在程序中多次出现,具有独立功能 的程序段写成程序模块,该模块可被多次调用, 称之为子程序。
特点:①可重复使用(调用) ②具有通用性(可通过入口参数实现) ③可浮动性(存放位置灵活) ④可递归性和可重入性
第6章
第六章 子程序设计
一、子程序的定义 二、子程序的结构形式
三、子程序的设计和调用 四、子程序的参数传递方法 五、子程序的嵌套和递归调用 六、子程序的设计举例 七、多模块程序设计 八、汇编语言和高级语言的混合编程
《IBM PC 80X86汇编语言程序设计》
冶金工业出版社
第6章
一、子程序的定义
1、子程序的概念和特点 2、子程序的定义 3、子程序的调用和返回
《IBM PC 80X86汇编语言程序设计》
冶金工业出版社
第6章
2、子程序的定义
子程序的定义是由过程定义伪指令PROC和ENDP 来完成的。其格式如下:
过程名 PROC [NEAR/FAR]
┆
过程名 ENDP
其中PROC表示过程定义开始,ENDP表示过程定 义结束。过程名是过程入口地址的符号表示。
一般过程名同标号一样,具有三种属性,即段 属性、偏移地址属性以及类型属性。
《IBM PC 80X86汇编语言程序设计》
冶金工业出版社
第6章
3、子程序的调用和返回
❖ 调用
①段内直接调用
格式:CALL 子程序名
功能:将子程序返回地址(断点)入栈
SP←SP-2
(SP)←IP,
并转到子程序入口地址去执行子程序。
❖ 返回指令
汇编语言程序设计(第四版)第4章【课后答案】

汇编语言程序设计(第四版)第4章【课后答案】汇编语言程序设计第四版【课后习题答案】--囮裑為檤第4章基本汇编语言程序设计〔习题4.1〕例题4.2如果要求算术右移8位,如何修改程序。
〔解答〕思路:首先由最高位字节向次低位字节传送……次低位字节向最低位字节传送(共7次);再判最高位字节符号位,如为0,送00h到最高位字节;如为1,送ffh到最高位字节。
传送可参考例题4.2,不过应从第一号字节送第零号字节,……最高位字节向次低位字节传送;也可以用循环来完成:.model small.stack 256.dataqvar dq 1234567887654321h.code.startupmov cx,7mov si,1again: mov al, byte ptr qvar[si]mov byte ptr qvar[si-1],alinc siloop againtest al,80hjz ezzmov bl,0ffhjmp doneezz: mov bl,0done: mov byte ptr qvar[7],bl.exit 0end〔习题4.2〕例题4.2如果要求算术左移7位,如何用移位指令实现。
〔解答〕思路:可设计外循环体为8个字节左移一次,方法是:最低位字节算术左移一次,次低位字节至最高位字节依次带CF 位循环左移一次(内循环共8次),外循环体控制执行7次即可。
.model small.stack 256.dataqvar dq 1234567887654321h.code.startupmov dx, 7 ;外循环次数mov ax, byte ptr qvar[0] ;最低位字节送axlpp: shl ax, 1 ;最低位字节左移一次,其d7移入CF位mov si, 1mov cx, 7 ;内循环次数again: rcl byte ptr qvar[si], 1 ;高位字节依次左移P50inc siloop againdec dxjnz lpp.exit 0.end〔习题4.3〕将AX寄存器中的16位数连续4位分成一组,共4组,然后把这4组数分别放在AL、BL、CL和DL寄存器中。
汇编语言——子程序

6.2.2.2 RET指令 指令 【指令格式】RET 【功能】这是子程序返回指令,必须写在子程序的指令 序列之中。根据所在的子程序的类型不同,RET指令的功能 也分为两种情况: (1)如果RET所在子程序是NEAR类型,则从堆栈中出 栈一个字(当然,SP会加2),送给IP。 (2)如果RET所在子程序是FAR类型,则先从堆栈中出 栈一个字送到IP,再出栈一个字送到CS,栈顶指SP的值加4。
cr
PROC NEAR MOV AH,2 MOV DL,13 INT 21H MOV DL,10 INT 21H RET
cr ENDP main:MOV AX,dseg MOV DS,AX LEA DX,buf MOV AH,10 INT 21H CALL cr MOV AH,1 INT 21H MOV BL,AL ;输入一个字符 ;用BL保存读入的字符 ;输入一个符号串
【解】程序段(a)中,先把AX赋值为102H,再把BX赋 值为304H,然后用ADD指令把两数相加,和为406H,结果 放在ADD指令的目的操作数AX中。 程序段(b)的前两行与(a)完全相同,AX取值102H,BX 取值304H,但在相加之前调用了子程序cr。从例6.3中cr的 具体实现方法可以知道,调用过程中寄存器AH的值被改为 2,因为INT 21H输出功能,使AL的值也被修改,变成0AH, 并且这个值一直保持到调用结束,于是“CALL cr”指令调 用子程序后,AX的值不再是调用前的102H,而变成了 20AH,当ADD指令进行两个寄存器相加时,结果是50EH, 并放到目的操作数AX中。
6.3 应用子程序进行编程
6.3.1 子程序实例
【例6.3】分析下列程序,描述它的功能。 dseg SEGMENT buf DB 80,81 DUP(0) dseg ENDS sseg SEGMENT STACK DW 64 DUP(0) sseg ENDS cseg SEGMENT ASSUME CS:cseg,DS:dseg,SS:sseg
汇编语言习题与答案

汇编语言习题与答案一、填空题:把答案填在题中横线上。
1. 8位无符号整数的表示范围为0~255,写成16进制形式为00H~__________;8位有符号整数的表示范围为-128~+127,写成16进制形式为__________~__________。
2. 8086/8088分段管理存储空间,但每段容量最大不超过__________。
3. 逻辑地址为F000:100的存储单元,其物理地址是__________。
4. 用来指示堆栈栈顶的偏移地址的是__________寄存器。
5. 若要测试AL寄存器D4、D2、D0位是否都为0,则可使用__________指令语句(含操作数),以产生转移条件。
这条指令执行后将利用标志位__________实现转移。
6. 若定义:bdata db 2 dup(1,2,2dup(3),4),则dbata变量前5个单元从低地址到高地址的数据依次是__________。
7. 假设varw是一个16位变量,则指令“mov varw,ax”的目的操作数的寻址方式是__________。
(二、选择题:在每小题给出的四个选项中,只有一项是符合题目要求的,请把所选项前的字母填在题后的括号内。
1.对汇编语言源程序进行翻译,形成OBJ文件的是A.汇编程序B.连接程序C.编辑程序D.调试程序[]2.下列各个8位二进制数的补码中,真值最大的是A. B.[]语句中,表达常数不正确的形式是B. A346H`C.’A’D. 5600 []4.如果SS=600H,则说明堆栈段物理地址起始于[]50 dup()预留了存储空间的字节数是[]6.下列指令中有操作数在代码段中的是ax,34h ax,bxword ptr [34h] ax,[34h] []@7.假设AL=5,要使得AL=0FAH,应执行的指令是A. not al al,0fhal,0f0h al,0fh []8.设置逻辑段应该采用的一对伪指令是ends end startendp endm []9.条件转移指令JNE条件是=0 =1=0 =1 []10.逻辑移位指令SHL可用于!A.有符号数乘以2B.有符号数除以2C.无符号数乘以2D.无符号数除以2 []11.执行“in al, dx”指令后,进入AL寄存器的数据来自A.寄存器B.存储器C.立即数D.外设端口[]12.将十进制数75以压缩BCD码送入AX,正确的指令是ax,0075 B. mov ax,0705ax,0075h D. mov ax,0705h []13.如下指令可将AX寄存器内容改变的是A. cmp ax,bxB. test ax,bx?C. and ax,bxD. xchg ax,bx []14.设AH=10H,执行“neg ah”指令后,正确的结果是A. AH=10H、CF=1B. AH=F0H、CF=0C. AH=10H、CF=0D. AH=F0H、CF=1 []15.如下程序段:again: mov es:[di],alinc diloop again可用指令__________完成相同的功能。
汇编语言参数传递

汇编语言参数传递在计算机科学领域中,汇编语言是一种低级语言,被用于指令的编写和处理器的控制。
汇编语言的特点之一是参数传递的使用,它允许将数据或信息传递给子程序或函数。
本文将探讨汇编语言中参数传递的不同方式和相关技术。
1. 立即数传递立即数传递是指直接将数值嵌入指令中作为参数传递的方式。
在汇编语言中,可以使用"mov"(move)指令来将立即数传递给寄存器或存储器。
例如,下面的代码将数值10传递给寄存器ax:```mov ax, 10```2. 寄存器传递寄存器传递是指将数据存储在寄存器中,并通过寄存器传递给子程序或函数。
汇编语言中的寄存器具有特定的名称和功能,如ax、bx、cx和dx等。
下面的示例代码演示了如何使用寄存器传递参数:```mov ax, 10mov bx, 20add ax, bx ; 将bx寄存器中的值加到ax中```3. 存储器传递存储器传递是指将数据存储在内存中,并通过内存地址传递给子程序或函数。
在汇编语言中,可以使用存储器地址作为参数传递给指令。
下面的代码演示了如何使用存储器传递参数:```mov bx, [var] ; 将存储在var地址处的值传递给bx寄存器```4. 栈传递栈传递是指使用栈(堆栈)数据结构来传递参数。
在汇编语言中,栈是一种用于存储和管理函数调用的数据结构。
通过将参数压入栈中,然后在子程序内部弹出,可以实现参数传递的目的。
下面的示例代码演示了如何使用栈传递参数:```push 10 ; 将数值10推入栈中push 20 ; 将数值20推入栈中call myFunction ; 调用名为myFunction的子程序```总结:在汇编语言中,参数传递可以通过立即数传递、寄存器传递、存储器传递和栈传递等多种方式来实现。
不同的传递方式适用于不同的场景和需求。
对于复杂的程序,通常会结合使用多种传递方式来实现参数传递的目的。
正确理解和使用参数传递方式对于开发高效、可靠的汇编语言程序非常重要。
汇编语言之子程序

汇编语言之子程序汇编语言是一种底层编程语言,是计算机指令的集合表示形式。
在汇编语言中,子程序是一段独立的、可重复使用的代码片段,可以在程序中被多次调用。
子程序可以帮助我们实现代码的模块化,提高代码的可读性和可维护性。
本文将介绍如何在汇编语言中使用子程序以及其工作原理。
一、子程序的定义和使用在汇编语言中,子程序由一系列指令组成,这些指令可以完成特定的功能。
子程序可以通过call指令被调用,执行完子程序后会返回到调用子程序的指令处,继续执行程序的下一条指令。
在使用子程序前,我们需要先定义子程序。
定义子程序的语法如下:```subroutine_name:; 子程序代码ret```其中,subroutine_name是子程序的名称,可以根据实际需求自定义。
ret指令用于返回到调用子程序的指令处,继续执行程序的下一条指令。
调用子程序的语法如下:```call subroutine_name```其中,subroutine_name是要调用的子程序的名称。
二、传递参数和返回值子程序可以接收参数,并且可以有返回值。
在调用子程序时,可以通过寄存器或栈来传递参数。
在子程序内部,可以通过相应的寄存器或栈地址来获取参数的值。
例如,我们定义一个计算两个数之和的子程序add:```add:mov ax, [bp+4] ; 获取第一个参数的值add ax, [bp+6] ; 获取第二个参数的值ret```在主程序中调用add子程序:```mov ax, 5 ; 第一个参数mov bx, 10 ; 第二个参数call add ; 调用add子程序; 此时ax寄存器中的值为15,即5+10的结果```在子程序add中,我们通过寻址方式获取传递的参数,并将计算结果存入ax寄存器中,供主程序使用。
三、保存和恢复寄存器在汇编语言中,调用子程序时需要保存和恢复寄存器的值,以保证程序的正确执行。
在调用子程序前,我们可以使用push指令将需要保存的寄存器值压栈,然后在子程序的开头使用相应的pop指令将值弹出并恢复。
汇编语言课后习题答案

2.1已知DS=2000H、BX=0100H、SI=0002H,存储单元[20100H]~[20103H]依次存放12 34 56 78H,[21200H]~[21203H]依次存放2A 4C B7 65H,说明下列每条指令执行完后AX寄存器的内容。
(1)mov ax,1200h(2)mov ax,bx(3)mov ax,[1200h](4)mov ax,[bx](5)mov ax,[bx+1100h](6)mov ax,[bx+si](7)mov ax,[bx][si+1100h]〔解答〕(1)AX=1200H(2)AX=0100H(3)AX=4C2AH ;偏移地址=bx=0100h(4)AX=3412H ;偏移地址=bx=0100h(5)AX=4C2AH ;偏移地址=bx+1100h=1200h(6)AX=7856H ;偏移地址=bx+si=0100h+0002h=0102h(7)AX=65B7H ;偏移地址=bx+si+1100h=0100h+0002h+1100h=1202h〔习题2.2〕指出下列指令的错误(1)mov cx,dl(2)mov ip,ax(3)mov es,1234h(4)mov es,ds(5)mov al,300(6)mov [sp],ax(7)mov ax,bx+di(8)mov 20h,ah〔解答〕(1)两操作数类型不匹配(2)IP指令指针禁止用户访问(3)立即数不允许传给段寄存器(4)段寄存器之间不允许传送(5)两操作数类型不匹配(6)目的操作数应为[ SI ](7)源操作数应为[BX+DI](8)立即数不能作目的操作数〔习题2.5〕已知SS = 2200H、SP = 00B0H,画图说明执行下面指令序列时,堆栈区和SP的内容如何变化?mov ax,8057hpush axmov ax,0f79hpush axpop bxpop [bx]〔解答〕mov ax,8057hpush axmov ax,0f79hpush axpop bx ;bx=0f79hpop [bx] ;DS:[0f79h]=8057h〔习题2.6〕给出下列各条指令执行后AL值,以及CF、ZF、SF、OF和PF的状态:mov al,89hadd al,aladd al,9dhcmp al,0bchsub al,aldec alinc al〔解答〕mov al,89h ; AL=89h CF ZF SF OF PFadd al,al ; AL=12h 1 0 0 1 1; 1000 1001+1000 100110001 0010add al,9dh ; AL=0afh 0 0 1 0 1; 0001 0010+ 1001 11011010 1111cmp al,0bch ; AL=0afh 1 0 1 0 1; 1010 1111-1011 1100* 0100 0011sub al,al ; AL=00h 0 1 0 0 1dec al ; AL=0ffh 0 0 1 0 1 ; 0000 0000- 0000 0001*1111 1111inc al ; AL=00h 0 1 0 0 1 ;1111 1111+0000 0001*1111 1111必考:〔习题2.10〕指出下列指令的错误:(1)xchg [si],30h (2)pop cs(3)sub [si],[di](4)push ah(5)adc ax,ds(6)add [si],80h(7)in al,3fch(8)out dx,ah〔解答〕(1)xchg的操作数不能是立即数(2)不应对CS直接赋值(3)两个操作数不能都是存储单元(4)堆栈的操作数不能是字节量(5)adc的操作数不能是段寄存器(6)没有确定是字节还是字操作(7)in不支持超过FFH的直接寻址(8)out只能以AL/AX为源操作数〔习题2.11〕给出下列各条指令执行后的结果,以及状态标志CF、OF、SF、ZF、PF的状态。
浅谈汇编语言中子程序的设计

r 。+ ”+ +
“+ + ” + + ‘+ + “+ “+ 。
。+ ’+ + ’
‘ ’ +
“+ ’+ ’
“+
+
浅谈汇编 中子 语言
■+ . . . .+ ” + . + 一 + . . + 一 + . . + - + 一 + + 一 + ” + 一 + ・ ・ 一 + + 一 + ・ ・
一
是 否按 “ 进 先 出” 后 的原 则 组 织 的 。 () 2堆栈保 护。子程 序是利用调用 C I AL 指令 和返 回 R T 指令来 实现正确 的调用 和返 回 的。因 E
为C Au 命令执 行 时压 入堆栈 的断 点地 址就 是供 子程序返 回主程序 时的地址 , 编程 时一定 要注 意子
程 序 的类 型 属 性 , 是 段 内 调 用 还 是 段 间 调 用 。段 即 内调 用 和 返 回为 N A 属 性 , 问 调 用 和 返 回 为 E R 段 F R 属性 。8 8 / 0 8的 汇编 程 序用 子 程序 定 义 A 0 68 8 P ( 的 类 型 属 性 来 确 定 C L和 R T 指令 的 属 R) C AL E 性 。如 果 所 定 义 的 子 程 序 是 F AR 属 性 , 么 对 它 那 的调用和返 回一定都是 F R A 属性 ; 如果所定义的子 程 序 是 NE R A 属性 , 么 对 它 的 调 用 和 返 回 也 一 定 那 是 NE R A 属 性 。这 样 用 户 只 是 在 定 义 子 程 序 时 考 虑它的属性 , C I 而 AL 和 R T指 令 的 属 性 就 可 以 E 由 汇 编 程 序 来 确 定 了 。另 外 , 入 子 程 序 后 再 使 用 进 堆 栈 时 也 必 须 保 证 压 人 和 弹 出 字 节 数 一 致 , 果 在 如 这 里 堆 栈 存 取 出错 , 然 会 导 致 返 回地 址 的 错 误 。 必 2 参 数传 递 . 主程序在调用子程序 时 , 经常要 向子程 序传递 些参数或控 制信息 , 子程序执行后 , 也常需要把运 行的结果返 回调用程序 。这种信息传递称 为参数传 递, 其常用 的方 法有 寄存 器传 递 、 内存 固定单 元传 递 、 栈传递 。 堆 ( ) 存 器 传 递 。 由 主 程 序 将 要 传 递 的参 数 装 1寄 入事先 约定 的寄存 器 中, 转入子 程序后 再取 出进行 处 理 , 种 方 法 受 C U 内 部 寄 存 器 数 量 限 制 , 此 这 P 因 只适 于传 递 少 量 参 数 的 场 合 , 一 些 常 见 的 软 件 延 如 时子程序 , 均是利用某寄存器传递循环计数 器初值 。 ( ) 过 内存 固 定 单 元 的 传 递 。此 方 法 适 于 大 2通 量传递参数时使用 , 它是在 内存 中开辟特 定 的一片 区域用于传递参数 。主程序和子程序都按事先约定 在指定 的存储单元 中进行数据 交换 , 这种 方法要 占
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
;不能整除100则是闰年,转
;除以400
DIV BX
CMP DX,0 JZ lab2
;除以400
lab2:INC BYTE PTR [day] ;是闰年,把天数加1,设置出 口参数 lab1 : POP DX POP CX POP BX
POP AX
RET Jud1: ENDP
5.用堆栈传递 参数传递不仅要在传递者之间约定数据的类型,还要
【解】子程序清单如下:
;功能:判断一个年份是否为闰年 ;入口:AX = 公元年份
;出口:CF,1表示是闰年,0表示非闰年
;破坏寄存器:AX jud PROC NEAR PUSH BX PUSH CX PUSH DX MOV CX,AX MOV DX,0 ;临时保存年份值
MOV BX,4
DIV BX CMP DX,0 JNZ lab1 MOV AX,CX MOV BX,100 DIV BX CMP DX,0 JNZ lab2 MOV AX,CX MOV BX,400 DIV BX CMP DX,0 JZ lab2
对于DX中存放的年份值,需要先放到AX中,才能调用 子程序jud,然后以调用返回后的CF值决定是否把t数组中表 示2月份天数的[t+1]加1。程序段如下: MOV AX,DX CALL jud ADC BYTE PTR [t+1],0 ;原值+0+CF
4.用数据段中已定义的变量存放参数 用数据段中定义的变量作为参数传递的载体也是一种 常用方法。这种方法要求子程序与调用者之间约定好以哪 个变量或哪几个变量进行参数传递。具体做法是:对于用 作入口参数的变量,调用者在调用子程序的CALL指令之前, 先把变量赋以一定的值,然后以CALL指令转到子程序执行, 子程序则取出该变量中的数据进行处理;对用作出口参数
lab: POP BP
RET _max ENDP
;恢复寄存器BP的原值
6.3.3 带参数的子程序
【例6.5】编写一个子程序,对一个无符号的字型数组的
各元素求和。在调用子程序之前,已把数组的段地址放在
DS中,起始偏移地址放在寄存器SI中,数组元素个数(>0)放 在CX中。要求子程序把计算结果以双字的形式存放,高位
放在DX中,低位放在AX中。
【解】 sum PROC NEAR
1.通用寄存器传值
2.通用寄存器传地址
3.标志寄存器传递逻辑型数据 【例6.6】编写一个子程序,以放在 AX中的公元年份为 入口参数,判断该年是否为闰年。 另有一个应用程序,它已定义了一个字节型数组 t,依 次存放着12个月的每月天数,其中2月份的天数是 28。应用 程序已经在 DX中存放了年份值,利用前面编写的子程序, 编写程序段调整数组t中2月份的天数。
RET
sum ENDP
子程序说明应该包含如下4个部分:
(1)子程序的功能。用来指明该子程序完成什么样的 操作。 (2)入口参数。说明调用子程序前应该把什么样的数 据放在什么地方。
(3)出口参数。说明调用后从什么地方取得处理结果。
(4)破坏的寄存器。指出子程序中哪些寄存器没有被
保护。
6.3.4 参数传递的方法
约定参数存放地。如果约定用通用寄存器放参数,有可
能会出现寄存器不够使用的情况。而约定用变量存放参 数又要求在子程序和调用程序之外再写出变量定义,灵
活性较差。用堆栈传递参数就可以克服这些缺点。对于
调用者来说,传递给子程序的数据可以按字型(如果不 是字型,先要转换成字型)用PUSH指令压入堆栈中;对
于子程序来说,如何准确地取到栈中数据就是关键性问
_max PROC NEAR
PUSH BP MOV BP,SP MOV AX,WORD PTR [BP+6] ;取第1个参数到AX CMP AX,WORD PTR [BP+4] ;与第2个参数比较 JGE lab MOV AX,WORD PTR [BP+4] ;取第2个参数到AX ;暂时保存寄存器BP的值
MOV DX,0 MOV BX,4
DIV BX CMP DX,0 JNZ lab1 MOV AX,[year] MOV BX,100 DIV BX CMP DX,0 ;除以4 ;不能整除4则不是闰年,转 ;取回年份值 ;除以100
JNZ lab2 MOV AX,[year] MOV BX,400 DIV BX
的变量,也有赋值与取值两个阶段,子程序进行数据处理
后,把处理结果放到约定好的变量中,然后以RET指令返 回调用者,调用者可以从变量中取出处理结果使用。
【例6.7】用变量传递参数,编写例6.6要求的子程序。 【解】 ;功能:根据一个年份是否为闰年,设置该年2月份的天数 ;入口:DS段中的字型变量year = 公元年份 ;出口:DS段中的字节型变量day = 该年2月份天数 ;破坏寄存器:无 jud1 PROC NEAR PUSH AX PUSH BX PUSH CX PUSH DX MOV BYTE PTR [day],28 MOV AX,[year]
题。下面的例6.8用一个实际例子说明在子程序中取得参 数值的具体方法。
【例 6.8 】用堆栈传递入口参数,编写子程序,把接收
的两个带符号整数中大的一个作为结果,出口参数放在AX 中。 【解】 ;功能:求两个带符号整数中大的一个 ;入口参数:调用前把两个带符号整数入栈 ;出口参数X
AX,AX DX,AX
;保护用到的寄存器BX
;求和前先把存放结果的DX,AX清0
MOV s1: ADD ADC INC INC LOOP POP
BX,AX AX,[BX+SI] ;把一个元素加到AX中 DX,0 BX BX s1 BX ;恢复寄存器BX的值 ;BX加2,指向数组的下一元素 ;若有进位,DX加1
;除以4,为预防溢出,用双字除以字
;不能整除4则不是闰年,转 ;取回年份值 ;除以100 ;不能整除100则是闰年,转
;除以400
lab1:CLC JMP lab3 lab2:STC lab3:POP DX POP CX POP BX RET jud ENDP
;把CF清0表示非闰年,设置出口参数 ;把CF置1表示是闰年,设置出口参数