1.2杨辉三角性质1、每行数字左右对称,由1开始逐渐变大,然后变小,回到1。2、第n行的数字个数为n个。3、第n行数字和为2^(n-1)。(2的(n-1)次方)4、每个数字等于上一行的左右两个数字之和。可用此性质写出整个帕斯卡三角形。5、将第2n+1行第1个数,跟第2n+2行第3个数、第2n+3行第5个数……连成一线,这些数的和是第2n个斐波那契数。将第2n行第2个数,跟第2n+1行第4个数、第2n+2行第6个数……这些数之和是第2n-1个斐波那契数。6、第n行的第1个数为1,第二个数为1×(n-1),第三个数为1×(n-1)×(n-2)/2,第四个数为1×(n-1)×(n-2)/2×(n-3)/3…依此类推。7.两个未知数和的n次方运算后的各项系数依次为杨辉三角的第(n+1)行。图1-2-1杨辉三角图1-2-2杨辉三角数学公式第一章汇编语言简介2.1汇编语言概况根据本次设计要求:通过汇编语言编写汇编程序要求能够在提示信息下,从计算机键盘任意输入一个数据,在输出提示信息后显示相应的杨辉三角。下面对汇编语言作简单的介绍。汇编语言(AssemblyLanguage)是面向机器的程序设计语言。在汇编语合中,用助记符(Memoni)代替操作码,用地址符号(Symbol)或标号(Label)代替地址码。这样用符号代替机器语言的二进制码,就把机器语言变成了汇编语言。于是汇编语言亦称为符号语言。使用汇编语言编写的程序,机器不能直接识别,要由一种程序将汇编语言翻译成机器语言,这种起翻译作用的程序叫汇编程序,汇编程序是系统软件中语言处理系统软件。汇编程序把汇编语言翻译成机器语言的过程称为汇编。汇编语言是一种功能很强的程序设计语言,也是利用计算机所有硬件特性并能直接控制硬件的语言。汇编语言,作为一门语言,对应于高级语言的编译器,需要一个“汇编器”来把汇编语言原文件汇编成机器可执行的代码。高级的汇编器如MASM,TASM等等为我们写汇编程序提供了很多类似于高级语言的特征,比如结构化、抽象等。在这样的环境中编写的汇编程序,有很大一部分是面向汇编器的伪指令,已经类同于高级语言。现在的汇编环境已经如此高级,即使全部用汇编语言来编写windows的应用程序也是可行的,但这不是汇编语言的长处。汇编语言的长处在于编写高效且需要对机器硬件精确控制的程序。汇编语言(AssemblyLanguage)是一种采用助记符表示的程序设计语言,即用助记符来表示指令的操作码和操作数,用符号或标号代表地址、常量或变量。助记符一般都是英文单词的缩写,便于识别和记忆。使用汇编语言编写的程序称为汇编语言源程序。汇编语言源程序不能由机器直接执行,而必须翻译成有机器代码组成的目标程序,这个翻译的过程称为汇编。把汇编语言源程序翻译成目标程序的软件称为汇编程序。汇编语言与机器语言密切相关,它们之间有明显的对应关系。一条汇编语言指令对应一条机器语言代码,所以汇编语言和机器语言一样都是面向机器的语言。使用汇编语言进行程序设计能充分利用机器的硬件功能和结构特点,从而有效地加快程序的执行速度,减少程序占用的存储空间。所以汇编语言大量用于编写计算机系统程序、实时通信程序和实时控制程序等。汇编语言作为最基本的编程语言之一,汇编语言虽然应用的范围不算很广,但重要性却勿庸置疑,因为它能够完成许多其它语言所无法完成的功能。就拿Linux内核来讲,虽然绝大部分代码是用C语言编写的,但仍然不可避免地在某些关键地方使用了汇编代码,其中主要是在Linux的启动部分。由于这部分代码与硬件的关系非常密切,即使是C语言也会有些力不从心,而汇编语言则能够很好扬长避短,最大限度地发挥硬件的性能。2.2汇编语言优点及缺点汇编语言直接同计算机的底层软件甚至硬件进行交互,它具有如下一些优点:(1)能够直接访问与硬件相关的存储器或I/O端口;(2)能够不受编译器的限制,对生成的二进制代码进行完全的控制;(3)能够对关键代码进行更准确的控制,避免因线程共同访问或者硬件设备共享引起的死锁;(4)能够根据特定的应用对代码做最佳的优化,提高运行速度;(5)能够最大限度地发挥硬件的功能。同时还应该认识到,汇编语言是一种层次非常低的语言,它仅仅高于直接手工编写二进制的机器指令码,因此不可避免地存在一些缺点:(1)编写的代码非常难懂,不好维护;(2)很容易产生bug,难于调试;(3)只能针对特定的体系结构和处理器进行优化;(4)开发效率很低,时间长且单调。首先程序开始时在电脑上显示输入提示信息,提醒输入的操作数只能是1到10之间的正整数,超过这个范围或太小则显示提示信息输入的数过大。得到杨辉三角的阶数之后即调用一个算法子程序来求相应阶数的每一个数值,每求出一个数值即将其数压入堆栈中保存起来,方便以后输出数字时直接调用。算完之后,通过外层循环di计数输出每一行,与此同时又通过内层循环si计数输出一行中的每一个数,在输出数字时通过调用show子程序将数字均以十进制输出,在输出数值的时候通过showspace函数来控制数与数之间的空格及行前空格的输出,上半部分的数字输出之后将其所有数值及空格格式都存在一个预制的存储单元内,然后直接实现逆序输出,这样最终能在屏幕中打印出一个菱形的杨辉三角。第二章子程序设计4.1输入子程序输入用int16ah为0这一功能,从键盘读字符,字符存在al中,输入时用cmp判断令其只能输入字符’0’~‘9’每次输入的字符转化为十进制存并阔展为字存入ax中,再将ax与初始为0的bp交换,再将ax乘以十后与bp相加,结果存在bp中,再返回输入,这样就能输入两位数。shurprocpushcxpushbxxorbp,bpmovbx,10movcx,2input:movah,0;键盘输入数据存在al中int16hcmpal,0dh;以回车结束输入jzokcmpal,'0';只允许输入0~9jbinputcmpal,'9'jainputmovah,0eh;显示有效输入int10hsubal,30h;化ASCII为十进制cbw;字节扩展为字xchgax,bpmulbx;扩大10倍addbp,ax;加一位loopinputok:nop;数值结果在BP中popbx;恢复用到的寄存器popcxretshurendp4.2杨辉三角算法子程序求某m行n列的数C(n,m)时采用递归的方法求出该数具体算法是:{C(n,m)=1(nm或m=0){C(n,m)=C(n-1,m-1)+C(n-1,m)(nm)即某位置组合数等于上一行左右两数之和,先算出左肩上的数并压栈保存,再次调用C过程求出右肩上的数并压栈保存,左肩与右肩的数相加从而可以求出下一行的组合数吗,其间存在递归调用,直至求出最大的那个数才返回初始调用的call的下一个语句。Cprocpushbpmovbp,spsubsp,2;预留一个存储位置movbx,[bp+6];保存m到bxcmpbx,[bp+4];如果mn返回1jzL1cmpbx,0;如果m=0返回1jzL1movax,[bp+4];保存n到axdecax;ax=ax-1decbx;bx=bx-1pushbxpushaxcallC;返回上一行左边的那个数mov[bp-2],ax;保存左肩膀上的数movax,[bp+4];以下5句同理,返回上一行右肩膀上的数decaxpush[bp+6]pushaxcallCaddax,[bp-2];和左肩膀上的数相加得出该组合数jmpL2L1:movax,1L2:movsp,bppopbpret4;ax返回组合数Cendp4.3计算输出数字长度子程序将此数不断除以十,每除一次计数加1,当al即商为0时停止返回计数值即长度。例如:计算输出数字最大长度以便分配行间行前空格时,n阶的最大数应该是最后一行中间那个数即C(n,n/2),将此数不断除以十,每除一次计数加1,当al即商为0时停止返回计数值即最大长度。getdigitprocpushdxmovbx,10xordx,dxnext:cmpax,0jleok2divblandax,0ffhincdxjmpnextok2:movax,dxpopdxretgetdigitendp4.4计行前数字间空格子程序先定义一个可以接受输入ax个空格的子程序输出行前空格时,n阶杨辉三角的i行行前空格数=(n-i)*cl,cl是最大长度,某数与下一个数字间空格数=数的最大长度cl+cl-该数的长度。具体程序如下:callshowspace;输出行前空格xorsi,si;内存循环计数si,内层循环输出一行中的每个数jmpcp2up2:incsi;更新dicp2:cmpsi,di;测试循环条件,循环di次jgdone2pushsipushdicallC;获取该行的位于si位置的组合数,调用C(di,si)pushax;保存该组合数pushbxmovbx,dxmov[bx],axincdxincdxpopbxcallshow;输出该数movax,cxsubax,1pushbxmovbx,dxmov[bx],axincdxincdxpopbxcallshowspacepopaxcallgetdigit;获取该组合数长度movbx,axmovax,cxsubax,bx;addax,1pushbxmovbx,dxmov[bx],axincdxincdxpopbxcallshowspacejmpup2;更新内层循环showspace:pushdxmovbx,axmovah,2movdl,''nexts:cmpbx,0jledonesint21hdecbxjmpnextsdones:popdx4.5输出子程序输出分为上半部分和下半部分,上半部分输出利用2号功能将每个数除以10将余数转化为字符倒序输出,下半部分是将算好的数以及行前行间空格数算好然后倒序输出。上半部分:showprocpushdxmovbx,10cmpax,0jzok1divblpushaxandax,00ffhcallshowpopdxmovdl,dhordl,30hmovah,2int21hok1:popdxretshowendp下半部分:movax,daincalmovbl,6mulblsubdx,axdecdxdecdxmovcx,dal11:movax,cxmovbl,6mulblsubdx,axdecdxdecdxmovbx,dxmovax,[bx]callshowspace;输出行前空格pushcxl12:incdxincdxmovbx,dxmovax,[bx]callshow;输出该数incdxincdxmovbx,dxmovax,[bx]callshowspace;输出数字间间隔空格incdxincdxmovbx,dxmovax,[bx]callshowspace;输出填充的空格loopl12popcxmovax,cxmovbl,6mulblincdxincdxsubdx,axdecdxdecdxpushdxmovah,2;以下5句实现换行movdl,13int21hmovdl,10int21hpopdxloopl11附录附录A程序代码:datasegmentorg100hmessagedb'InputN(N=10):$'errordb0ah,0dh,'Dataoutofrange!$'dadw0datdw300dup(?)dataendscodesegmentassumecs:code,ds:datastart:movax,datamovds,axmovdx,offsetmessagemovah,9int21hcallshurcmpbp,10jbegoonmovdx,offseterrormovah,9int21hjmpexitgoon:movah,2;以下5句实现换行movdl,13int21hmovdl,10int21hpushbpcallyhsjmovax,daincalmovbl,6mulblsubdx,axdecdxdecdxmovcx,dal11:movax,cxmovbl,6mu