第一篇:C语言期末总结
结构体
例10.4 指向结构体数组的指针的应用
#include
printf(″No.Name
sex
agen″);
for(p=stu;p<stu+3;p++)
printf(″%5d %-20s %2c %4dn″,p->num,p->name,p->sex,p->age);
} 运行结果:
No.Name
sex
age
10101
LiLin
M
1010Zhang Fun M
10104
WangMing F
例10.5 有一个结构体变量stu,内含学生学号、姓名和3门课程的成绩。要求在main函数中赋予值,在另一函数print中将它们输出。今用结构体变量作函数参数。#include
char name[20];
float score[3];};
#include
char name[20];
float score[3];};
void main(){ void print(struct student);
struct student stu;
stu.num=12345;
strcpy(stu.name,″LiLin″);
stu.score[0]=67.5;
stu.score[1]=89;
stu.score[2]=78.6;
print(stu);} void print(struct student stu){ printf(FORMAT,stu.num,stu.name,stu.score[0],stu.score[1],stu.score[2]);
printf(″n″);} 运行结果: 12345 Li Li 67.500000 89.000000 78.599998 例10.6 将上题改用指向结构体变量的指针作参数。#include
char name[20];
float score[3];}stu={12345, ″LiLi″,67.5,89,78.6};void main(){ void print(struct student *);
print(&stu);}
void print(struct student *p){ printf(FORMAT,p->num,p->name,p->score[0],p->score[1],p->score[2]);
printf(″\n″); } 运行结果: 12345 Li Li 67.500000 89.000000 78.599998 有10个学生,每个学生的数据包括学号、姓名、3门课的成绩,从键盘输入10个学生数据,要求输出3门课程总平均成绩,以及最高分的学生的数据(包括学号、姓名、3门课程总成绩、平均分数)。 10.1:# include
struct student
{ char num[6];
char name[8];
int score[3];
float avr;
}stu[10];
main()
{ int i,j,max=0,maxi=0,sum=0;
float average=0;
for(i=0;i<10;i++)
{ scanf(“%s%s”,stu[i].num,stu[i].name);
for(j=0;j<3;j++)
scanf(“%d”,&stu[i].score[j]);
}
for(i=0;i<10;i++)
{ sum=0;
for(j=0;j<3;j++)
sum+=stu[i].score[j];
stu[i].avr=sum/3.0;
average+=stu[i].avr;
if(sum>max){ max=sum;maxi=i;}
}
average/=10;
printf(“average=%6.2fn”,average);
printf(“The highest is:%s,%s,%d,%f”,stu[maxi].num,stu[maxi].name,max,stu[maxi].avr); }
指针
例9.4 输入a、b、c3个整数,按大小顺序输出。#include
{void exchange(int *q1,int *q2,int *q3);int a,b,c,*p1,*p2,*p3;
scanf(″%d,%d,%d″,&a, &b, &c);
p1=&a;p2=&b;p3=&c;
exchange(p1,p2,p3);
printf(″%d,%d,%d\n″,a,b,c);
}
void exchange(int *q1,int *q2,int *q3){ void swap(int *pt1,int *pt2);
if(*q1<*q2)swap(q1,q2);
if(*q1<*q3)swap(q1,q3);
if(*q2<*q3)swap(q2,q3);
}
void swap(int *pt1,int *pt2)
{int temp;
temp=*pt1;
*pt1=*pt2;
*pt2=temp;
score 3
}
运行情况如下:
9,0,10↙ 10,9,0
例9.10:有一个班,3个学生,各学4门课,计算总平均分数以及第n个学生的成绩。这个题目是很简单的。只是为了说明用指向数组的指针作函数参数而举的例子。用函数average求总平均成绩,用函数search找出并输出第i个学生的成绩。#include
{ void average(float *p,int n);
void search(float(*p)[4],int n);
float score[3][4]={{65,67,70,60},average(*score,12); /*求12个分数的平均分*/
search(score,2);
/*求序号为2的学生的成绩*/ }
void average(float *p,int n){ float*p_end;
float sum=0,aver;
p_end=p+n-1;
for(;p<=p_end;p++)
sum=sum+(*p);
aver=sum/n;
printf(″average=%5.2f\n″,aver); }
void search(float(*p)[4],int n)
/ * p是指向具有4个元素的一维数组的指针 */ {int i;
printf(″the score of No.%d are:n″,n);
for(i=0;i<4;i++)
printf(″%5.2f″,*(*(p+n)+i));}
程序运行结果如下: average=82.25
The score of No.2 are:
90.00 99.00 100.00 98.00
例9.11: 在上题基础上,查找有一门以上课程不及格的学生,打印出他们的全部课程的成绩。
#include
{void search(float(*p)[4],int n);
float score[3][4]={{65,57,70,60},{58,87,90,81},{90,99,100,98}};
{80,87,90,81},{90,99,100,98}};
search(score,3);
}
void search(float(*p)[4],int n){int i,j,flag;
for(j=0;j<n;j++)
{flag=0;
for(i=0;i<4;i++)
if(*(*(p+j)+i)<60)flag=1;
if(flag==1)
{ printf(“No.%d fails,his scores are: \n”,j+1);
for(i=0;i<4;i++)
printf(″%5.1f″,*(*(p+j)+i));
printf(″\n″);
}
}
}
程序运行结果如下:
No.1 fails, his scores are:
65.0
57.0
70.0
60.0 No.2 fails, his scores are:
58.0 87.0 90.0 81.0 例9.17:求a和b中的最大者。#include
{int max(int,int);int a,b,c;
scanf(″%d,%d″,&a,&b);
c=max(a,b);printf(″a=%d,b=%d,max=%dn″,a,b,c);
}
int max(int x,int y){ int z;
if(x>y)z=x;
else
z=y;
return(z);
}
例9.18:有若干个学生的成绩(每个学生有4门课程),要求在用户输入学生序号以后,能输出该学生的全部成绩。用指针函数来实现。
#include
{float score[][4]={{60,70,80,90},{56,89,67,88},{34,78,90,66}};
float *search(float(*pointer)[4],int n);
float*p;
int i,m;
printf(″enter the number of student:″);
scanf(″%d″,&m);
printf(″The scores of No.%d are:n″,m); p=search(score,m);
for(i=0;i<4;i++)printf(″%5.2ft″,*(p+i));
}
float *search(float(*pointer)[4],int n){ float *pt;
pt=*(pointer+n);
return(pt);
}
运行情况如下:
enter the number of student:1↙ The scores of No.1 are:
56.00
89.00
67.00
88.00 例9.19: 对上例中的学生,找出其中有不及格课程的学生及其学生号。#include
{ float score[][4]={{60,70,80,90},{56,89,67,88},{34,78,90,66}};
float search(float(*pointer)[4]);
float*p;
int i,j;
for(i=0;i<3;i++)
{p=search(score+i);
if(p==*(score+i))
{ printf(″No.%d scores:″,i);
for(j=0;j<4;j++)
printf(″%5.2f″,*(p+j));
printf(″n″);}
}
}
float *search(float(*pointer)[4]){ int i;
float *pt;
pt=*(pointer+1);
for(i=0;i<4;i++)
if(*(*pointer+i)<60)pt=*pointer;
return(pt);
} 运行情况如下:
No.1 scores:56.00 89.00 67.00 88.00
No.2 scores:34.00 78.00 90.00 66.00
例9.20:将若干字符串按字母顺序(由小到大)输出。#include
{void sort(char *name[ ],int n);
void print(char *name[ ],int n);
char *name[ ]={“Follow me”,“BASIC”,“Great Wall″,”FORTRAN“,”Computer design“};int n=5;
sort(name,n);
print(name,n);
}
void sort(char *name[ ],int n){char *temp;
int i,j,k;
for(i=0;i<n-1;i++){k=i;
for(j=i+1;j<n;j++)
if(strcmp(name[k],name[j])>0)k=j;
if(k!=i)
{ temp=name[i];
name[i]=name[k];
name[k]=temp;}
}
}
void print(char *name[ ],int n){ int i;
for(i=0;i<n;i++)
printf(″%sn″,name[i]);
} 运行结果为: BASIC Computer design FORTRAN Follow me Great Wall 作业:(提交上机报告)输入10个整数,将其中最小的数与第一个数对换,把最大的数与最后一个数对换。写3个函数:①输入10个数;②进行处理;③输出10个数。# include
{ void input(int number[10]);
void max_min_value(int array[10]);
void output(int array[10]);
int number[10];input(number);max_min_value(number);output(number);
} void input(int number[10])
{ int i;
for(i=0;i<=9;i++)
scanf(“%d”,&number[i]);} void max_min_value(int array[10])
{ int *max,*min,*p,*array_end;
array_end=array+10;
max=min=array;
for(p=array+1;p if(*p>*max)max=p; else if(*p<*min)min=p; *p=array[0];array[0]=*min;*min=*p; *p=array[9];array[9]=*max;*max=*p; } void output(int array[10]) { int *p; for(p=array;p<=array+9;p++) printf(“%4d”,*p); } 数组和函数的组合 例8.12 有一个一维数组,内放10个学生成绩,写一个函数,求出平均分、最高分和最低分。#include /*全局变量*/ void main() {float average(float array[ ],int n); float ave,score[10]; int i; for(i=0;i<10;i++) scanf(″%f″,&score[i]); ave= average(score,10); printf(″max=%6.2f\nmin=%6.2f\n average=%6.2f\n″,Max,Min,ave); } float average(float array[ ],int n) /*定义函数,形参为数组*/ { int i; float aver,sum=array[0]; Max=Min=array[0]; for(i=1;i<n;i++) {if(array[i]>Max)Max=array[i]; else if(array[i] sum=sum+array[i]; } aver=sum/n; return(aver); } 例8.18 有一个含若干字符的字符串,今输入一个字符,要求程序将字符串中该字符删去。用外部函数实现。file1.c(文件1)#include { extern void enter_string(char str[]); extern void detele_string(char str[],char ch); extern void print_string(char str[]); char c; char str[80];enter_string(str); scanf(”%c“,&c); detele_string(str,c); print_string(str); } file2.c(文件2)#include gets(str);} file3.c(文件3) void delete_string(char str[],char ch){ int i,j; for(i=j=0;str[i]!=' ';i++) if(str[i]!=ch) str[j++]=str[i]; str[i]=' ';} file4.c(文件4)#include printf(”%sn",str);} 运行情况如下: abcdefgc↙ (输入str) c↙ (输入要删去的字符)abdefg (输出已删去指定字符的字符串) 8.1:判断m是否是素数。(用函数实现)#include { int f(int m); int m,n; scanf(“%d”,&m); n=f(m); if(n)printf(“%d is a prime numbern”,m); else printf(“%d is not a prime numbern”,m); } int f(int m) { int i,k,p; k=sqrt(m); for(i=2;i<=k;i++) if(m%i==0)break; if(i>=k+1)p=1; else p=0; return p; } 8.2:用起泡法对10个数排序。(用函数实现) #include { void sort(int array[],int n); int a[10],i; for(i=0;i<10;i++) scanf(“%d”,&a[i]); sort(a,10); for(i=0;i<10;i++) printf(“%4d”,a[i]);} void sort(int array[],int n) { int i,j,t; for(i=0;i for(j=0;j<9-i;j++) if(a[j]>a[j+1]) { t=a[j];a[j]=a[j+1];a[j+1]=t;} } 8.3:用选择法对10个数排序。(用函数实现)#include { void sort(int array[],int n); int a[10],i; for(i=0;i<10;i++) scanf(“%d”,&a[i]); sort(a,10); for(i=0;i<10;i++) printf(“%4d”,a[i]);} void sort(int array[],int n) { int i,j,k,t; for(i=0;i { k=i; for(j=i+1;j if(array[j] t=array[k];array[k]=array[i];array[i]=t; } } 学前班语言期末总结 本人任教学前班的拼音、识字、美术、社会、科学课。本人能认真备课、上课、听课,能及时批改作业、讲评作业,使学生学有所得,从而不断提高自己的教学水平和思想觉悟,并顺利完成教育教学任务,并且取得了较好成绩,这一学期来本人的教学经验和体会如下: 1、要学好拼音应该注意以下两点 ①要充分利用每一课拼音教学的情景图。②要准确地把握汉语拼音教学的“标高”。应在语境中学习拼音,在发现中学习拼音。体验自主、合作、探究学习的乐趣,指导学生用自己的双眼去发现图中与字母相近的地方,发现与相拼两点省略的规律,发现j,q,x复韵母ǚ、鼻韵的组合规律。同时,激发学生的情感,使他们产生愉悦的心境,创造良好的课堂气氛,课堂语言简洁明了,克服了以前重复的毛病,课堂提问要面向全体学生,注意引发学生学习的兴趣,课堂上讲练结合,作业少而精,减轻学生的负担。 2、要提高教学质量,还要做好课后辅导工作。小学生爱做小动作、好玩,自控能力差,常不能按时完成作业,对于这种情况,我注意做好学生的思想工作,做学生的学习辅导工作,注意后进生的转化,多表扬他们,多鼓励他们。比如,发现他们在学习中的一小点进步,即使在课堂外的一点优点,也加以表扬。尽量少批评每位学生,万一要批评也要先找学生谈心,指出他的不足。 3、培养学生的兴趣和爱好,课后不断扩宽自己的知识面,为教学工作打下结实的基础 严格要求自己,努力工作,发扬优点,克服不足,求实进取,为教育教学事业贡献应有的力量。 我本学期的任教内容是:拼音、识字、美术、社会、科学课。从备课到上课,以及去听课,我都是非常严谨、认真,并及时批改作业、讲评作业,希望学生学有所得,同时能够提高自己的教学水平和思想觉悟。我对这学期的总结如下: 1、学习拼音应该注意以下两点: ①充分利用每一课拼音教学的情景图。②准确地把握汉语拼音教学的“标高”。 应在语境中学习拼音,在发现中学习拼音。体验自主、合作、探究学习的乐趣,指导学生用自己的双眼去发现图中与字母相近的地方,发现与相拼两点省略的规律,发现j,q,x复韵母ǚ、鼻韵的组合规律。同时,激发学生的情感,使他们产生愉悦的心境,创造良好的课堂气氛,课堂语言简洁明了,克服了以前重复的毛病,课堂提问要面向全体学生,注意引发学生学习的兴趣,课堂上讲练结合,作业少而精,减轻学生的负担。 2、要提高教学质量,还要做好课后辅导工作。幼儿爱做小动作、好玩,自控能力差,常不能按时完成作业,对于这种情况,我注意做好学生的思想工作,做学生的学习辅导工作,注意后进生的转化,多表扬他们,多鼓励他们。比如,发现他们在学习中的一小点进步,即使在课堂外的一点优点,也加以表扬。尽量少批评每位学生,万一要批评也要先找学生谈心,指出他的不足。 3、培养学生的兴趣和爱好,课后不断扩宽自己的知识面,为教学工作打下结实的基础;严格要求自己,努力工作,发扬优点,克服不足,求实进取,为教育教学事业贡献应有的力量。 杨春玲 汇编语言学习笔记 《汇编语言》--王爽 前言 学习汇编目的:充分获得底层编程体验;深刻理解机器运行程序的机理。原则:没有通过监测点不要向下学习;没有完成当前实验不要向下学习。第一章 基础知识 有三类指令组成汇编语言:汇编指令;伪指令;其他符号。8bit = 1byte = 一个存储单元有n根地址线,则可以寻址2的n次方个内存单元。1.1节--1.10节 小结 (1)汇编指令是机器指令的助记符,同机器指令一一对应。(2)每一种cpu都有自己的汇编指令集。(3)cpu可以直接使用的信息在存储器中存放。 (4)在存储器中指令和数据没有任何区别,都是二进制信息。(5)存储单元从零开始顺序编号。 (6)一个存储单元可以存储8个bit,即八位二进制数。 (7)每一个cpu芯片都有许多管脚,这些管脚和总线相连。也可以说,这些管脚引出总线。一个cpu可以引出的三种总线的宽度标志了这个cpu不同方面的性能。地址总线的宽度决定了cpu的寻址能力;数据总线的宽度决定了cpu与其他器件进行数据传送时的一次数据传送量;控制总线的宽度决定了cpu对系统中其他器件的控制能力。监测点:1KB的存储器有1024个存储单元?存储单元的编号从0到1023.内存地址空间: 最终运行程序的是cpu,我们用汇编编程时,必须要从cpu的角度思考问题。对cpu来讲,系统中的所有存储器中的存储单元都处于一个统一的逻辑存储器中,它的容量受cpu寻址能力的限制。这个逻辑存储器即是我们所说的内存地址空间。第二章 寄存器(cpu的工作原理)mov ax, 2 add ax, ax add ax, ax add ax, ax(1)cpu中的相关部件提供两个16位的地址,一个称为段地址,另一个称为偏移地址;(2)段地址和偏移地址通过内部总线送人一个称为地址加法器的部件;(3)地址加法器将两个16位地址合成为一个20位的物理地址;(4)地址加法器通过内部总线将20位物理地址送人输入输出控制电路;(5)输入输出控制电路将20位物理地址送上地址总线;(6)20位物理地址被地址总线传送到存储器; 段地址*16+偏移地址 = 物理地址 的本质含义 内存并没有分段,段的划分来自cpu。 以后编程时可以根据需要,将若干地址连续的内存单元看做一个段,用段地址*16定位段的起始地址,用偏移地址定位段的内存单元。 一个段的起始地址一定是16的倍数,一个段的最大长度为64kB。当然也没有办法定义一个起始地址不是16的倍数的段。 cpu可以用不同的段地址和偏移地址形成同一物理地址。 在8086cpu加电启动或复位后cs和ip被设置为cs = f000h,ip = ffffh,即ffff0h单元中的指令是8086pc机开机后执行的第一条指令。(??应该是fffffh吧??)cpu将cs:ip指向的内存单元看做指令。 在cpu中,程序员能够用指令读写的部件只有寄存器,程序员可以通过改变寄存器中的内容实现对cpu的控制。 mov指令称为传送指令,cpu中大部分寄存器的值都可以通过mov指令改变。除了cs:ip 8086没给他这样的功能。cs:ip可以用转移指令来改变。jmp jmp cs:ip 用指令给出的段地址修改cs,偏移地址修改ip jmp 某一寄存器 的功能为:用寄存器中的值修改ip jmp ax 含义类似于mov ip,ax 段地址在8086pc机的段寄存器存放。当8086cpu要访问内存时,由段寄存器提供内存单元的段地址。8086cpu有四个段寄存器,其中cs用来存放指令的段地址。cs存放指令的段地址,ip存放指令的偏移地址。 8086机中,任意时刻,cpu将cs:ip指向的内容当作指令执行。8086cpu的工作过程: 1.从cs:ip指向内存单元读取指令,读取的指令进入指令缓冲器; 2.ip指向下一条指令 3.执行 8086提供转移指令修改cs:ip的内容 debug的使用 查看,修改cpu中寄存器的内容:r命令 查看内存中的命令:d命令 修改内存中的内容:e命令(可以写入数据,指令,在内存中,它们实际上没有区别)将内存中的命令解释为机器指令和相应的汇编指令:u命令 执行cs:ip指向的内存单元处的命令:t命令 以汇编指令的形式向内存中写入指令:a命令 第三章 寄存器(内存访问)3.1内存中字的存储 高八位存放在高字节中,低八位存放在低字节中 3.2DS和【address】 3.3字传送 3.4MOV ADD SUB 3.5数据段 3.6栈 栈是一种具有特殊的访问方式的存储空间。它的特殊性就在于,最后进入这个空间的数据,最先出去。 栈有两个基本的操作:入栈和出栈。 栈的这种操作规则被称为:lifo(last in first out,后进先出)。cpu如何知道10000H--1000fH这段空间被当作栈使用? push pop指令在执行时必须知道哪个单元是栈顶单元,可是如何知道呢? 栈顶的段地址存放在ss中,偏移地址存放在sp中。任意时刻,ss:sp指向栈顶单元。push和pop指令执行时,cpu从ss和sp中得到栈顶的地址。入栈时,栈顶从高地址向低地址方向增长。如何定义一个栈的大小? mov ax, 1000h mov ss, ax mov sp, 0010h;则栈顶为1000f 栈底为 10000 ****************************************** mov ax, 1000h mov ds, ax mov ax, 2266h mov [0], ax ************************ mov ax,1000h mov ss, ax mov sp, 0002h mov ax, 2266h push ax 栈顶的变化范围最大为:0--ffffh 栈的综述 (1)8086cpu提供了栈操作机制,方案如下: 在ss、sp中存放栈顶的段地址和偏移地址; 提供入栈和出栈指令,他们根据ss、sp指示的地址,按照栈的方式访问内存单元。(2)push指令的执行步骤:1)sp=sp-2;2)向ss:sp指向的字单元送人数据;(3)pop指令的执行步骤:1)从ss:sp指向的字单元中读取数据;2)sp=sp+2(4)任意时刻,ss:sp指向栈顶元素。 (5)8086cpu只记录栈顶,栈空间的大小我们要自己管理。 (6)用栈来暂存以后需要恢复的寄存器的内容时,寄存器出栈的顺序要和入栈的顺序相反。(7)push、pop指令实质上是一种内存传送指令,注意他们的灵活运用。一个栈段最大可以设为64k 段的综述 我们可以将一段内存定义为一个段,用一个段地址指示段,用偏移地址访问段内的单元。这完全是我们的安排。用一个段存放代码,即代码段 用一个段存放数据,即数据段 用一个段当栈,即栈段 对于数据段,把段地址放在ds中,用mov,add,sub等访问内存单元的指令时,cpu就将我们定义的数据段内容当做数据来访问; 对于代码段,把段地址放在cs:ip中,用mov,add,sub等访问内存单元的指令时,cpu就将执行我们定义的代码段的指令; 对于栈段,把段地址放在ss:sp中,用push pop 等访问内存单元的指令时,cpu就将其当作堆栈来访问; debug的t命令在执行修改器ss的指令时,下一条指令也紧接着被执行了。3.7栈超界问题 8086cpu不保证我们对栈的操作不会超界。也就是说,8086cpu只知道栈顶在何处而不知道我们安排的栈空间有多大,这点就好像,cpu只知道当前要执行的指令在何处,而不知道要执行的指令有多少。从这两点我们可以看出cpu的工作机理,它只考虑当前情况:当前的栈在何处,当前要执行的指令是哪一条。对于超界问题我们可以做到就是小心。第五章【bx】和loop指令 我们完整的描述一个内存单元,需要两种信息:(1)内存单元的地址;(2)内存单元存放数据的类型; inc bx的含义是bx中的内容加一 [bx]寄存器bx中所包含的地址中存放的内容 [bx]表示一个内存单元,他的偏移地址在bx中。loop指令执行的时候,要进行两步操作: 1;(cx)=(cx)-1; 2;判断cx中的值,不为零则转至标号处执行。 “通常”我们用loop实现循环功能,cx中存放循环次数。用cx和loop指令相配合实现循环功能的三个要点:(1)再cx中存放循环次数; (2)loop指令中的标号所标识地址要在前面; (3)要循环执行的程序段,要写在标号和loop指令的中间。在汇编源程序中,数据不能以字母开头。所以对于大于9fffh的数,均在前面加上0。mov cx,11 s: add ax,ax loop s assume cs:code code segment..mov ax,4c00h int 21h code ends end ffff:6单元是一个字节单元,ax是一个十六位寄存器,数据长度不一样,如何赋值? 注意我们说的是“赋值”,就是说,让ax中的数据的值(数据的大小)和ffff:0006单元中的数据的值(数据的大小)相等。八位数据01h和16位数据0001h的数据长度不一样,但他们的值是相等的。 设ffff:0006单元中的的数据是xxh,若要ax中的值和ffff:0006单元中的值相等,ax中的数据应为00xxh。所以,若实现ffff:0006单元向ax赋值,我们应该令(ah)=0,(al)=(ffff6H).若希望程序能从cs:0012处执行,可以用g命令。“g 0012”。他表示程序执行到0012处。 若希望程序能跳出循环,用p命令 5.4 debug和汇编编译器masm对指令的不同处理。 在汇编源程序中,mov al,[0]会被编译器解释成为:mov al,0 所以要这样表达:mov bx,0 mov al,[bx] 或者 mov al,ds:[0] 第一,我们在汇编源程序中,如果用指令访问一个内存单元,则在指令中必须用[...]来表示内存单元,如果在[]里用一个常量idata直接给出内存单元的偏移地址,就要在[]的前面显示地给出段地址所在的段寄存器。 第二,如果在[]里用寄存器,比如bx,间接给出内存单元的偏移地址,则段寄存器默认在ds中。 第六章 包含多个段的程序 程序取得所需段的方法有两种: 一是在加载程序的时候为程序分配,再就是程序在执行的过程中向系统申请。dw的含义是定义字型数据即define word 字型数据间以逗号隔开。 程序运行的时候cs存放代码段的段地址,所以我们可以从cs中得到它们的段地址。dw定义的数据处于代码段的最开始,所以偏移地址为零。dw 0123h,5604h,1234h start :指令 end start 我们在程序的第一条指令的前面加了一个标号start:并在end的后面再次加入。end除了通知编译器程序结束外,还可以通知编译器程序的入口在什么地方。在单任务系统中,可执行文件中的程序执行如下: (1)由其他的程序(debug、command或其他程序)将可执行文件中的程序加载入内存;(2)设置cs:ip指向程序的第一条要执行的指令(即程序的入口),从而使程序得以运行;(3)程序运行结束后,返回到加载者; 描述信息 可执行文件由描述信息和程序组成,程序来源于源程序中的汇编指令和定义的数据;描述信息则主要是编译连接程序对原程序中相关伪指令进行处理所得到的信息。6.2 在代码中使用栈 在程序中通过定义数据来取得一段空间,然后将这段空间当作栈空间来使用。 例如将cs:16--cs:31的内存空间当作栈来用,初始状态下栈为空,所以ss:sp要指向栈底,则设置ss:sp指向cs:32.6.3将数据代码栈放入不同的段 用assume将定义的具有一定用途的段跟寄存器联系起来 第七章 更灵活的定位内存地址的方法 7.1 and 和 or 指令(1)and指令:逻辑与指令,按位进行与运算。mov al ,01100011B and al ,00111011B 执行后:al=00100011B 通过该运算可将操作对象的相应位设为0,其他位不变。(2)or指令:逻辑或指令,按位进行或运算。 通过该运算可将操作对象的相应位设为1,其他位不变。7.2 关于ASCII码 所谓编码方案,就是一套规则,它约定了用什么样的信息来表示现实对象。小写字母的ASCII码值,比大写字母的ASCII码值大20H。 就ASCII码的二进制形式来看,除第五位外,大写字母和小写字母的ASCII码值都一样。大写字母第五位为0,小写字母第五位为1.运用and和or指令的给特定位赋值功能即可实现大小写字母之间的转换。7.5 [bx+idata] 类似于[bx]的一种更灵活的指明内存单元的方式。 [bx+idata]表示一个内存单元,它的偏移地址为(bx)+idata(bx中的数值加上idata。也可以写成 mov ax,[200+bx] mov ax,200[bx] mov ax,[bx].200 7.6 用[bx+idata]的方式进行数组的处理 7.7 SI和DI SI和DI是8086cpu中和bx功能相近的寄存器。区别是SI和DI不能够分成两个八位寄存器来使用。codesg segment start: mov ax,datasg mov ds,ax mov si,0 mov di,16 mov cx,8;di si 为16位寄存器只需循环 s: mov ax,[si] mov [di],ax;八次即可将16个字节传送完毕 add si,2 add di,2 loop s mov ax,4c00h int 21h codesg ends end start si = dijmp指令后的第一个字节的地址(2)short指明此处的位移为八位位移。(3)八位位移的范围为-128 127,用补码表示;(4)八位位移由编译程序在编译时算出。 还有一种jmp near ptr 标号 实现段内近转移(ip)=(ip)+16位位移(1)16位位移 = “标号”处的地址1(DI)=(DI)-1 MOVSW 可以传送一个字 MOVSB和MOVSW进行的是串传送操作中的一个步骤,一般都要和rep配合使用,格式如下: rep movsb 相当于: s:movsb loop s rep的作用是根据cx的值,重复执行后面的串传送指令。8086cpu提供了下面两条指令对DF位进行设置: CLD:将DF位置0 STD:将DF位置1 1.传送的原始地址 2.传送的目的地址 3.传送的长度 4.传送的方向 11.11 pushf和popf 压入/弹出标志寄存器中的数据 为访问标志寄存器提供了一种方法。11.12 标志寄存器在DEBUG中的表示 第十二章 内中断 12.1 内中断的产生 cpu内部发生下面情况时,将产生相应的中断信息: (1)除法错误(2)单步执行(3)执行int0命令(4)执行int命令 中断类型码0 1 4 n 为一个字节型数据 12.2 中断处理程序 cpu如何通过八位的中断类型码得到中断处理程序的段地址和偏移地址? 12.3 中断向量表 答:通过中断向量表 中断向量表就是中断处理程序入口地址的列表。保存在内存中。cpu如何找到中断向量表? 对于8086中断向量表指定存在内存地址0处。从0000:0000到0000:03e8单元。共1000个字节。中断向量表中一个表项存放一个中断向量,占两个字。分别存放段地址和偏移地址。12.4 中断过程 (1)从中断信息中取得中断类型码(2)标志寄存器的值入栈 (3)设置标志寄存器的第八位TF和第九位IF的值为0(4)CS的内容入栈(5)IP的值入栈 (6)从内存地址为中断类型码*4和中断类型码*4 + 2 的两个字单元中读取中断处理程序的入口地址设置IP和CS 12.5 中断处理程序(1)保存用到的寄存器(2)处理中断。(3)恢复用到的寄存器(4)用IRET指令返回。12.6 除法错误中断的处理 12.7 编程处理0号中断 12.8 安装 第十三章 int指令 13.1 int指令 int指令的最终功能和call指令相似,都是调用一段程序。13.2 编写供应用程序调用的中断例程 编写、安装中断7ch的中断例程,功能:求一word型数据的平方。(AX)= 要计算的数据。 DX,AX存放结果的高十六位和低十六位。MOV WORD PTR ES:[7CH*4],200H MOV WORD PTR ES:[7CH*4+2],0 MOV CX,OFFSET SQREND-OFFSET SQR CLD REP MOVSB int指令和iret指令配合使用与call指令和ret指令配合使用具有相似的思路。13.3 对int、iret和栈的深入理解 ********************************* 13.4 BIOS和DOS所提供的中断例程 BIOS主要包含以下内容: 1、硬件系统的检测和初始化程序 2、外部中断和内部中断的中断例程 3、用于对硬件设备进行I/O操作的中断例程 4、其他和硬件系统相关的中断例程 13.5 BIOS和DOS中断例程的安装过程 1.开机后,cpu一加点,初始化(cs)= 0FFFFH,(IP)= 0,自动从FFFF:0单元开始执行程序。FFFF:0处有一条跳转指令,cpu执行该程序后,转去执行BIOS中的硬件检测和初始化程序。 2.初始化程序将建立BIOS所支持的中断向量,即将BIOS提供的中断例程的入口登记在中断向量表中。注意,对于BIOS所提供的中断例程,只需将入口地址登记在中断向量表中即可,因为它们是固化到ROM中的内容,一直在内存中存在。 3.硬件系统检测和初始化完成后,调用int 19h进行操作系统的引导。从此将计算机交给操作系统控制。 4.DOS启动后,除完成其他工作外,还将它提供的中断例程装入内存,并建立相应的中断向量。 13.6 BIOS中断例程应用 int 10h 中断例程是BIOS提供的中断例程,其中包含多个和屏幕输出有关的子程序。一个供程序员调用的中断例程往往包含多个子程序,中断例程内部用传递进来的参数来决定执行那一个子程序。BIOS和DOS提供的中断例程,都用AH来传递内部参数 13.7 DOS中断例程应用 例如 我们一直在使用的4ch号子程序,即程序返回功能。mov ah 4ch mov al 0 int 21h ========================== DOS功能调用 int 21h(1)键盘输入 1)1号调用——从键盘输入单个字符 调用格式: MOV AH,1 INT 21H 功能: 等待从键盘输入一个字符并送入AL。 执行时系统将扫描键盘,等待有健按下,一旦有健按下,就将其字符的ASCII码读 入,先检查是否Ctrl-Break,若是,退出命令执行;否则将ASCII码送AL,同时将 该字符送显示器显示。2)10号调用——从键盘输入字符串 功能: 从键盘接收字符串送入内存的输入缓冲区,同时送显示器显示。调用前要求: 先定义一个输入缓冲区 MAXLEN DB 100 ;第1个字节指出缓冲区能容纳的字符个数,即缓冲区长度,不能为0 ACLEN DB ? ;第2个字节保留,以存放实际输入的字符个数 STRING DB 100 DUP(?);第3个字节开始存放从键盘输入的字符串。 调用格式: LEA DX,MAXLEN(缓冲区首偏移地址)MOV AH,10 INT 21H(2)显示输出 1)2号调用——在显示器上显示输出单个字符 调用格式: MOV DL,待显示字符的ASCII码 MOV AH,2 INT 21H 功能:将DL中的字符送显示器显示。【例】显示输出大写字母A MOV DL,41H ;或写为 MOV DL,'A' MOV AH,2 INT 21H 2)9号调用——在显示器上显示输出字符串 调用格式: LEA DX,字符串首偏移地址 MOV AH,9 INT 21H 功能:将当前数据区中DS:DX所指向的以'$'结尾的字符串送显示器显示。【例】在显示器上显示字符串“YOU ARE SUCESSFUL!” DATA SEGMENT STRING DB ' YOU ARE SUCESSFUL!$ ' DATA ENDS CODE SEGMENT „ „ MOV AX,DATA MOV DS,AX LEA DX,STRING MOV AH,9 INT 21H „ „ CODE ENDS 说明:若希望显示字符串后,光标可自动回车换行,可在定义字符串时作如下更改: STRING DB ' YOU ARE SUCESSFUL!',0AH,0DH,' $ ' ;在字符串结束前加回车换行的ASCII码0AH,0DH 学前班语言期末教学反馈 姓名 成绩 二、按顺序填写。 ai ____ ui ao ____ iu ____ _____ er ____ en ____ un ____ ____ eng ____ _____ 六、写出下列字的笔顺并填空 元 _____________;共 画 拍 _____________ ;共 画 泪 __________________ ;共 _ 画 打 _______________________________ _;共 _画 机 ________________________________;共 画_ 七、写出下列字的反义词。 高——() 多——() 远——() 前——() 左——() 轻——() 上——() 大——() 长——() 进——() 薄——() 冷——() 八、填空。 1、“亲”字共有 _____ 画,第 画是“、” 组词:()() 2、“米”字共有_____________画,第________画是“ 一 ” 组词:()() 3、“布”字共有_____________画,第________画是“ 丿” 组词:()() 学前班语言期末测试卷 姓名:____ 一、按要求写字母。(14分) 单韵母:________________________ 声 母:________________________ ________________________ 二、填空。(27分) b p()f d ()n l ɡ ()h j q() zh()sh() z()s y() 三、拼一拼,把音节写下来。(20分)b-à→() t-e→() d-ī→() m-ā→() 四、把音节补充完整。(15分)Ai () ui () ou 五、听写生字。(24分) Hua duo bai tian xiao he() () ()Ri yue ba ma shu bao() () ()第二篇:学前班语言期末总结
第三篇:期末复习-语言各章总结
第四篇:学前班语言期末反馈
第五篇:学前班语言期末测试卷