汇编语言子程序程序设计
汇编语言-实验二 循环与子程序程序设计

汇编语言-实验二循环与子程序程序设计
实验目的
本实验旨在通过学习循环和子程序的概念和使用方法,掌握汇
编语言中循环和子程序的程序设计技巧,培养学生的程序设计能力。
实验内容
1. 循环程序设计:编写一个循环程序,实现指定次数的循环操作。
2. 子程序程序设计:编写一个子程序,实现指定功能的模块化
程序设计。
实验步骤
循环程序设计
1. 根据实验要求确定需要循环的次数。
2. 初始化循环计数器,将循环计数器置为0。
3. 判断循环计数器是否达到循环次数的要求,如果达到则跳出
循环,否则继续执行循环体。
4. 执行循环体的操作。
5. 循环计数器自增1。
6. 返回到第3步继续判断循环条件。
子程序程序设计
1. 根据实验要求确定需要实现的功能。
2. 将要实现的功能封装在一个子程序中,确定输入参数和输出结果。
3. 在主程序中调用子程序完成指定的功能。
4. 如果需要,可以在子程序中调用其他子程序实现更复杂的功能。
实验
本次实验通过编写循环和子程序的程序设计,加深了对汇编语言中循环和子程序的理解。
循环程序设计能够实现重复执行指定次数的操作,提高了程序的效率;子程序程序设计能够实现模块化和可重用性,提高了程序的可读性和可维护性。
通过实践,进一步掌握了汇编语言的程序设计技巧,加深了对汇编语言的理解和应用能力。
参考资料
汇编语言程序设计教程
汇编语言程序设计实验指导书。
汇编 子程序设计

实验四子程序设计一、实验目的(1)掌握汇编语言子程序设计方法。
(2)掌握主程序与子程序之间的调用关系及调用方法。
(3)掌握通过寄存器传送参数的方法。
二、实验环境(1) 硬件环境:计算机系统windows;(2) 软件环境:装有MASM、DEBUG、LINK、等应用程序。
三、实验内容(方法步骤):编程实现:十进制到十六进制数转换程序。
程序要求:从键盘取得一个十进制数,然后把该数以十六进制形式在屏幕上显示出来。
四、实验说明(1) 键盘输入的十进制数(ASCII),要将它转换成二进制存放。
⇒子程序:DECIBIN(2) 二进制转换成十六进制数并显示⇒子程序:BINIHEX(3) 为避免屏幕上的重叠,必须有回车和换行功能。
⇒子程序:CRLF用三个子程序联合实现题目要求⇒联合由主程序达到。
将BX寄存器作为过程之间传送转换数据的“交通员”。
五、实验步骤(1)编辑、汇编源程序,生成相应的可执行文件(.EXE)(2)检查程序执行的结果是否正确。
六、流程图主程序流程图如下图:子程序CRLF流程图如下图:子程序DECIBIN流程图如下图:子程序BINIHEX流程图如下图:七、源程序data segmentdata endscode segmentassume cs:code,ds:data main:call DECIBINcall CRLFcall BINIHEXmov ah,4Chint 21hDECIBIN PROCMOV BX,0NEWCHAR:MOV AH,1INT 21HSUB AL,30HJL EXITCBWXCHG AX,BXMOV CX,10DMUL CXXCHG AX,BXADD BX,AXJMP NEWCHAR EXIT:RETDECIBIN ENDPCRLF PROC NEARMOV AH,02HMOV DL,0AHINT 21HMOV AH,02HMOV DL,0DHINT 21HRETCRLF ENDPBINIHEX PROC NEAR START:MOV CH,4NOTATE:MOV CL,4ROL BX,CLMOV AL,BLAND AL,0FHADD AL,30HCMP AL,3AHJL PRINTITADD AL,7HPRINTIT:MOV DL,ALMOV AH,2INT 21HDEC CHJNZ NOTATERETBINIHEX ENDPcode endsend main八、问题思考(1)当输入“#”时,退出主程序,如何修改程序?(2)说明用寄存器传送参数的过程及其具体方法,各子程序的应用。
汇编语言程序设计-子程序

6.1 子程序的设计方法
MOV DL,’B’ MOV AH,2 INT 21H MOV AH,4CH INT 21H CSEG ENDS END START
6.1 子程序的设计方法 ;子程序:NWELINE
;功能:回车和换行(光标移到下一行首) ;入口参数:无 ;出口参数:无 ;说明:通过显示回车符形成回车,通过显示换行符形成换 行 NEWLINE PROC MOV DL,0AH;显示换行符 PUSH AX MOV AH,2 PUSH DX INT 21H MOV DL,0DH;显示回车符 POP DX POP AX MOV AH,2 RET INT 21H
6.1 子程序的设计方法
NEXT:MOV AL,[SI] INC SI OR AL,AL JZ OK;判断是否为0 CALL ISDECM JNC NEXT MOV [DI],AL INC DI JMP NEXT OK:MOV [DI],AL MOV AH,4CH INT 21H CSEG ENDS END START
6.1 子程序的设计方法
MOV AL,0 MADD PROC ADC AL,0 PUSH AX MOV BYTE PTR DATA4+4, PUSH CX AL POP SI PUSH SI POP CX MOV CX,2 POP AX XOR SI,SI RET MADD PTR MADD1:MOV AX,WORD ENDP DATA1[SI] ADC AX,WORD PTR DATA2[SI] MOV WORD PTR DATA3[SI],AX INC SI INC SI LOOP MADD1
6.1 子程序的设计方法
2. 子程序的调用与返回
子程序调用:隐含使用堆栈保存返回地址
汇编语言程序 掌握子程序的设计

汇编语言程序掌握子程序的设计汇编语言程序掌握子程序的设计子程序的定义和使用,我们需要了解子程序的定义和使用。
在汇编语言中,子程序通常由一段带有入口点和出口点的代码块组成。
入口点是子程序被调用的位置,而出口点是子程序执行完毕后返回的位置。
下面是一个简单的子程序的定义示例:; 子程序的说明subroutine:; 子程序的代码逻辑ret在上面的示例中,`subroutine` 是子程序的入口点,`ret` 是子程序的出口点。
当程序执行到 `ret` 指令时,将返回到调用子程序的位置继续执行后续的代码。
调用子程序的方法是使用 `call` 指令,以指令的形式告诉处理器需要调用的子程序入口点的位置。
例如:call subroutine这将会跳转到 `subroutine` 的入口点开始执行子程序的代码,然后在子程序执行完毕后返回到 `call` 指令的下一条指令继续执行后续的代码。
子程序的设计原则设计一个高效和可重用的子程序需要遵循一些设计原则:1. 单一责任原则一个子程序应该只负责一个特定的任务或功能。
这样可以使子程序的设计更加清晰和可重用。
2. 输入和输出参数子程序应该通过参数来接收输入的数据,并将处理后的数据通过参数返回。
这样可以增加子程序的灵活性和可重用性。
3. 注释和文档为子程序添加详细的注释和文档,可以使其他程序员更容易理解和使用子程序。
注释应该清晰地描述子程序的功能、输入和输出参数以及注意事项。
4. 错误处理子程序应该具备良好的错误处理机制,它应该能够在遇到错误时返回错误码或抛出异常。
这样可以提高程序的可靠性和可维护性。
5. 可测试性设计可测试的子程序是很重要的。
你可以为每个子程序编写对应的测试用例,以确保子程序的正确性和稳定性。
子程序的优化技巧除了以上的设计原则,还有一些优化技巧可以提高子程序的性能:1. 寄存器的使用在子程序中尽可能地使用寄存器进行计算和存储临时数据,而不是使用内存。
因为寄存器的读写速度要远快于内存,可以显著提高程序的执行效率。
汇编语言子程序设计

汇编语言子程序设计汇编语言子程序设计简介汇编语言是一种低级语言,经常被用来编写底层的软件和嵌入式系统。
在汇编程序中,子程序是一种可重复使用的代码块,用于执行特定的任务。
本文将介绍汇编语言中子程序的设计和实现方法。
我们将以x86架构为例,使用NASM作为汇编器。
子程序的定义与调用子程序是一个独立的代码块,可以接受输入参数并返回结果。
在汇编语言中,子程序的定义通常由标签来表示,调用子程序时可以使用CALL指令。
子程序的定义下面是一个简单的子程序定义的示例:assemblycalculate_sum:; 子程序代码;ret在这个例子中,`calculate_sum`是子程序的标签,子程序代码写在标签后面。
`ret`指令用于返回到调用者。
子程序的调用要调用一个子程序,可以使用CALL指令,将控制权转移到子程序的入口点。
assemblycall calculate_sum在这个示例中,`calculate_sum`是要调用的子程序的标签。
子程序的输入参数子程序常常需要接受输入参数,以执行特定的任务。
在x86汇编语言中,参数可以通过寄存器或栈传递。
寄存器传递参数寄存器传递参数是一种直接将参数存储在寄存器中的方式。
x86架构提供了一些通用寄存器,可以用于传递参数。
通常,EAX、EBX、ECX和EDX寄存器被用作函数调用时的参数传递寄存器。
其他寄存器如ESI和EDI可以用作传递额外参数。
下面是一个使用寄存器传递参数的示例:assemblycalculate_sum:mov eax, [ebp+8] ; 将第一个参数存储到EAX寄存器mov ecx, [ebp+12] ; 将第二个参数存储到ECX寄存器add eax, ecx ; 将两个参数相加ret在这个示例中,我们使用EBP寄存器作为基址指针,通过偏移来访问参数。
栈传递参数栈传递参数是将参数存储在栈中,然后在子程序中使用ESP寄存器来访问这些参数。
栈是一种后进先出(LIFO)数据结构,可以方便地存储和检索参数。
汇编语言程序 掌握子程序的设计

汇编语言程序掌握子程序的设计汇编语言程序:掌握子程序的设计1. 引言编程语言是计算机与人进行交流的桥梁,而汇编语言是一种底层的编程语言,直接与计算机硬件进行交互。
掌握汇编语言的使用对于理解计算机底层原理、优化程序性能以及开发低级系统软件具有重要意义。
在编写汇编语言程序时,合理设计子程序是一项关键任务。
本文将介绍如何掌握子程序的设计,从而提高汇编语言程序的可读性、维护性和性能。
2. 什么是子程序子程序是一个独立且可重复使用的代码块,用于解决特定的任务。
在汇编语言中,子程序通常由一系列指令组成,可以接受输入参数并返回输出结果。
通过将程序分解为多个子程序,可以使代码结构更加清晰,提高代码的可读性和可维护性。
3. 子程序设计的原则在设计子程序时,应遵循以下几个原则:3.1 单一职责原则每个子程序应只负责完成一个特定的任务,避免一个子程序功能过于复杂。
这样可以提高代码的可读性和可维护性,并且方便进行单元和代码重用。
3.2 参数传递原则合理选择参数传递的方式,将必要的信息传递给子程序。
常见的参数传递方式包括将参数保存在寄存器中、使用堆栈传递参数以及通过全局变量传递参数。
根据不同的应用场景,选择合适的方式。
3.3 返回值传递原则子程序执行完成后,通常需要返回一个结果。
可以使用寄存器存储返回值,也可以通过堆栈传递返回值。
在设计子程序时,需要明确返回值的类型和传递方式。
3.4 寄存器保护原则在调用子程序时,需要注意保护寄存器中的数据。
由于子程序可能会改变寄存器的值,在调用子程序之前,需要先将关键寄存器的值保存到栈中,在子程序执行完成后再恢复。
3.5 清理堆栈原则在子程序调用期间,可能会使用堆栈来传递参数和存储临时变量。
在子程序执行完成后,需要及时清理堆栈,确保堆栈恢复到调用子程序之前的状态。
4. 子程序设计示例:计算斐波那契数列为了更好地理解子程序设计的原则,我们以计算斐波那契数列为例进行说明。
assembly; 计算斐波那契数列的子程序; 输入:ECX(求解的斐波那契数列长度); 输出:EAX(斐波那契数列的结果)CalcFibonacci PROCMOV EAX, 0 ; 前一个斐波那契数MOV EBX, 1 ; 当前斐波那契数MOV EDX, ECX ; 计数器DEC EDX ; 减去初始值1LOOP_START:ADD EAX, EBX ; 计算下一个斐波那契数XCHG EAX, EBX ; 更新数列中的前一个数和当前数LOOP LOOP_START ; 重复计算RETCalcFibonacci ENDP在这个示例中,我们设计了一个名为CalcFibonacci的子程序,用于计算斐波那契数列。
汇编语言子程序设计

汇编语言子程序设计汇编语言子程序设计一、介绍在计算机编程中,汇编语言是一种低级语言,它与机器语言非常接近。
汇编语言使用助记符来表示计算机指令,可以直接操作计算机硬件。
而子程序是一种独立的代码块,可以重复使用,实现功能模块化和代码的复用。
二、子程序的定义与声明1:定义子程序:子程序可以通过标签来定义,使用关键字PROC表示开始,使用关键字ENDP表示结束。
例如:```MySubproc PROC:::MySubproc ENDP```2:声明子程序:可以使用EXTERN关键字声明一个外部子程序,以便在代码中调用。
例如:```EXTERN MyExternalSubproc:PROC```三、子程序的参数传递1:寄存器传递:参数可以通过寄存器来传递,常用的寄存器包括AX、BX、CX、DX等。
例如:```MOV AX, 5 ; 将参数5传递给AX寄存器CALL MySubproc ; 调用子程序```2:堆栈传递:参数也可以通过堆栈来传递,使用PUSH指令将参数压入堆栈,使用POP指令将参数从堆栈中取出。
例如:```PUSH 5 ; 将参数5压入堆栈CALL MySubproc ; 调用子程序```四、子程序返回值1:使用寄存器返回值:子程序的返回值可以通过寄存器来传递,常用的寄存器包括AX、BX、CX、DX等。
例如:```MOV AX, 10 ; 子程序返回值为10,存储在AX寄存器中RET ; 返回至调用处```2:使用堆栈返回值:子程序的返回值也可以通过堆栈来传递,使用PUSH指令将返回值压入堆栈,使用RET指令返回至调用处。
例如:```PUSH 10 ; 将子程序返回值10压入堆栈RET ; 返回至调用处```五、子程序的调用1:使用CALL指令调用子程序:使用CALL指令可以调用子程序,调用子程序之前需要将参数准备好,并将返回值保存在适当的寄存器或堆栈中。
例如:```MOV AX, 5 ; 将参数5传递给AX寄存器CALL MySubproc ; 调用子程序```2:使用CALL FAR指令调用外部子程序:如果需要调用位于其他模块或库中的子程序,可以使用CALL FAR指令。
汇编语言程序设计 第9章 子程序设计

2015-1-2
第9章 子程序的设计
4
安徽工业大学
9.1 9.1.1 子程序设计方法 子程序的定义
《汇编语言程序设计》
子程序可以放在代码段主程序开始执行之前的位置,也可放在 代码段的末尾主程序执行终止后的位置。 为了便于其他程序员能正确使用子程序,在编写子程序 时,还要养成书写子程序说明信息的良好习惯。子程序说明 信息一般包括以下内容: (1)子程序名 (2)功能描述 (3)入口和出口参数 (4)调用注意事项和说明等
第9章 子程序的设计
《汇编语言程序设计》
9.1.2 子程序调用与返回
当子程序和主程序不在同一个代码段中,子程序的定义和调用如下图:
2015-1-2
9
安徽工业大学
9.1 子程序设计方法
《汇编语言程序设计》
9.1.3寄存器内容的保护与恢复
为什么寄存器的保护与恢复? 通常主程序和子程序是分别编制的,所以它们可能会 使用同一个寄存器。如果主程序中某个寄存器的内容在调 用子程序后还要用,而子程序又恰好使用了同一个寄存器, 当子程序修改了寄存器的内容后,返回到主程序时,该寄 存器的内容也就不会是调用子程序前的内容,这样,常常 会导致调用程序的出错。为此,编写子程序时,在一进入 子程序后,就把它所用到的寄存器内容压进栈,在返回前, 再把它们弹出栈。
2015-1-2
第9章 子程序的设计
20
安徽工业大学
《汇编语言程序设计》
堆栈法
• 例:z=x+y,假定x和y为字数据 • 版本1: 函数原型形如void myadd(int *z,int *y,int *x); • 程序清单
2015-1-2
第9章 子程序的设计
21
安徽工业大学
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
汇编语言程序设计实验报告
学院:计算机科学与技术专业:计算机科学与技术班级:计科131
MOV AX,4C00H
INT 21H
MAIN ENDP
PROADD PROC NEAR
PUSH AX
PUSH CX
PUSH SI
PUSH DI
MOV SI,[BX]
MOV DI,[BX+2]
MOV CX,[DI]
MOV DI,[BX+4]
XOR AX,AX
NEXT:ADD AX,[SI]
ADD SI,2
LOOP NEXT
MOV [DI],AX
POP DI
POP SI
POP CX
POP AX
RET
PROADD ENDP
ARY DW 1,2,3,4,5,6,7,8,9,10
COUNT DW 10
SUM DW ?
TABLE DW 3 DUP(?)
CODE ENDS
END MAIN
使用相应的文本编辑器建立文件LAB5.asm,内容如上所示。
二. 生成可执行文件:
1.汇编:
C:\masm> masm lab5;
2.连接:
C:\masm> link lab5;
三. 请写出此程序中的变量ary,count,sum 的EA,并判断此程序的功能:
四. 用debug 调试此程序时,第一条指令的段内EA 是多少?此程序数据段内偏移地址为
0 的字单
元数据为多少?其对应的机器指令是什么?
-L ;加载程序文件lab5.exe
-R ;查看IP 与CS 寄存器的内容
-D DS:0 ;查看当前数据段内偏移地址为0 的字单元数据
-U ;查看机器指令
实验二:编写一个子程序,实现在屏幕的指定位置,用指定颜色,显示一个用0 结尾的字符串
源程序如下
data segment
str db 'display string',0
data ends
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
mov dh,8
mov dl,21
mov cl,3
mov si,offset str
call show_str
mov ax,4c00h
int 21h
;----------------------------
show_str proc near
push ax
push cx
push dx
push es
push si
mov es:[bx], cl
jcxz ok
mov es:[bx+1], dl
inc si
add bx, 2
jmp short s
ok:
pop si
pop es
pop dx
pop cx
pop bx
pop ax
ret
; 子程序:divdw
; 要求:进行不会除法溢出的除法运算,被除数为dword,除数为word,结果为dword ; 参数:(ax) = 被除数dword型的低16位
; (dx) = 被除数dword型的高16位
; (cx) = 除数
; 返回:(dx) = 结果的高16位
; (ax) = 结果的低16位
; (cx) = 余数
divdw:
mov bx, ax ; 缓存ax——被除数的低16位
mov ax, dx ; ax = H,被除数的高16位
mov dx, 0
div cx ; ax 为商,dx为余数 = rem(H/N) * 65536
push ax ; 结果的商,也就是最后要放在dx中的
mov ax, bx ; dx为 rem(H/N) * 65536, 为高16位,ax为低16位,再进行一次除法运算
div cx ; ax 为商——最后结果的低16位,dx为余数——为最后结果,应赋给cx
mov cx, dx
pop dx
ret
code ends
end start
实验结果实验一:变量ary,count,sum 的EA分别是00140,00154,00156此程序的功能是数列求和
实验二:
实验三:
实
验
总
结
这次实验,感觉难度最大的就是做2个子程序的设计,在网上向好友请教了N回!
还犯了一些低级的错误,如将16位的寄存器的内容传送到字符型数字串里去,这很明显是不对的,在逆序时寄存器的高16位会直接把正常的数字字符冲掉,还有就是将当我直接将字型单元的内容传送字型单元时,编译器会报错,不过提示是它后面的指令错误。
转换后的数字串的末尾如果不是0的话,在调用输出子程序时会出现BUG,于是又在转换子程序里加了条指令,在第一次转换出来后,在数字串的末尾添加一个终止标志0。
指
导
教
师
意
见签名:年月日。