ZF PF CF OF SF笔记

1.ZF:

算术或逻辑指令(并非全部)执行后,若结果为0,则ZF=1,若不为0,则ZF=0

传送指令不改变ZF

2.PF:

奇偶标志位

相关指令(如add and or等)执行后,如果1的个数为偶数,PF=1,反之PF=0

3.CF(针对无符号数):

进位标志位

记录了无符号运算时,运算结果的最高有效位向更高位的进位值,或从更高位的借位值。

4.OF(针对有符号数):

溢出标志位

记录了有符号数运算的结果是否发生了溢出。若溢出,OF=1,反之为0

判断时看的是符号位的变化

5.SF(针对有符号数):

符号标志位

记录相关指令执行后,结果是否非负。结果为负,SF=1,结果非负,SF=0

其实SF的值=符号位的值

 

注意点:mul指令只影响CF和OF

 

debug中标志位的表示:

 

 

 

链表(完善中。。)

首节点:第一个有效节点

尾节点:最后一个有效节点

头节点:首节点之前的节点。头节点数据类型和首节点一样。头节点并不存放有效数据。头节点的设置是为了方便操作链表

头指针:指向头节点的指针变量

尾指针:指向尾节点的指针变量

要通过一个函数操作一个链表,只需接受一个参数:头指针

链表为空时,只有一个头节点

首节点为第1个节点,若链表长度为n,则有编号1~n的节点,外加一个头节点

下面写出非循环单链表程序:

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct Node{
int data;
struct Node*pNext;
}NODE,*PNODE;
PNODE create_list();
int traverse_list(PNODE pHead);
bool is_empty(PNODE);
int length_list(PNODE);
int sort_list(PNODE);
bool insert_list(PNODE pHead,int pos,int val);
bool delete_list(PNODE pHead,int pos,int *pval);
int main()
{
int len,pos=0;
PNODE pHead=NULL;
pHead=create_list();
traverse_list(pHead);
//    len=length_list(pHead);
//    printf(“链表有%d个元素n”,len);
//    sort_list(pHead);
//    traverse_list(pHead);
while(pos!=-1)
{
printf(“请输入pos:”);
scanf(“%d”,&pos);
insert_list(pHead,pos,100);
traverse_list(pHead);
}
system(“pause”);
return 0;
}
PNODE create_list()
{
int len,i,val;//len是有效节点的个数,不包括头节点
PNODE pHead=(PNODE)malloc(sizeof(NODE));
if (pHead==NULL)
{
printf(“memory errorn”);
exit(-1);
}
PNODE pTail=pHead;
pTail->pNext=NULL;
printf(“please enter the length of the list:”);
scanf(“%d”,&len);
for(i=0;i<len;i++)
{
printf(“请输入第%d个节点的值:”,i+1);
scanf(“%d”,&val);
PNODE pNew=(PNODE)malloc(sizeof(NODE));
if(pNew==NULL)
{
printf(“memory errorn”);
exit(-1);

}
pNew->data=val;
pNew->pNext=NULL;
pTail->pNext=pNew;
pTail=pNew;
}
return pHead;
}
int traverse_list(PNODE pHead)
{
PNODE p=pHead->pNext;
while(p!=NULL)
{
printf(“the val is:%dn”,p->data);
p=p->pNext;
}
printf(“n”);
return 0;
}
bool is_empty(PNODE pHead)
{
PNODE p=pHead->pNext;
if (p==NULL)
return true;
else
return false;
}
int length_list(PNODE pHead)
{
int len=0;
PNODE p=pHead->pNext;
while(p!=NULL)
{
len++;
p=p->pNext;
}
return len;
}
int sort_list(PNODE pHead)//类比数组的简单选择排序算法
{
PNODE p,q;
int i,j,len,t;
len=length_list(pHead);
for(i=0,p=pHead->pNext;i<=len-2;i++,p=p->pNext)
for(j=i+1,q=p->pNext;j<=len-1;j++,q=q->pNext)
{
if((p->data)>(q->data))
{
t=p->data;
p->data=q->data;
q->data=t;
}
}
return 0;
}
bool insert_list(PNODE pHead,int pos,int val)//在pos之前插入,pos从1开始,首节点为第1个节点(pos=1)
{
int i=0;
PNODE p=pHead;
while(p!=NULL&&i<pos-1)
{
p=p->pNext;
i++;
}
if(p==NULL||i>pos-1)
return false;
PNODE q=(PNODE)malloc(sizeof(NODE));
q->data=val;
q->pNext=p->pNext;
p->pNext=q;
return true;
}
bool delete_list(PNODE pHead,int pos,int *pval)
{
int i=0;
PNODE p=pHead;
while(p->pNext!=NULL&&i<pos-1)
{
p=p->pNext;
i++;
}
if(i>pos-1||p->pNext==NULL)
return false;
PNODE q=p->pNext;
*pval=q->data;
p->pNext=p->pNext->pNext;
free(q);
q=NULL;
return true;

}

动态数组的实现(顺序表)

已经很久没有写c程序了,结果写的错误连篇。。头文件总是不加中括号,调用函数习惯性地在前面加上invoke或是call,更多的错误是if和else前面总有那么一个点。。。

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
struct array{
	int *pBase;
	int len;
	int cnt;
};
int arr_init(struct array*,int);
bool arr_append(struct array*,int);
bool arr_insert(struct array*,int,int);
bool arr_delete(struct array*,int,int *);
int arr_insersion(struct array*);
int arr_sort(struct array*);
bool is_empty(struct array*);
bool is_full(struct array*);
int arr_show(struct array*);

int main()
{
	int val;
struct array arr;
arr_init(&arr,6);
arr_append(&arr,3);
arr_append(&arr,4);
arr_append(&arr,9);
arr_show(&arr);
arr_insert(&arr,1,7);
arr_show(&arr);
arr_insersion(&arr);
arr_show(&arr);
arr_sort(&arr);
arr_show(&arr);

system("pause");
return 0;
}
int arr_init(struct array *parr,int length){
parr->pBase=(int *)malloc(sizeof(int)*length);
if (parr->pBase==NULL)
{
printf("申请失败");
exit(-1);
}
parr->len=length;
parr->cnt=0;
return 0;
}
bool is_empty(struct array *parr)
{
if (!parr->cnt)
	return true;
else
	return false;
}
int arr_show(struct array *parr)
{
if (is_empty(parr))
	printf("the array is empty\n");
else
	for(int i=0;i<parr->cnt;i++)
	{
		printf("%d ",parr->pBase[i]);
	}
	printf("\n");
return 0;
}
bool is_full(struct array* parr)
{
if (parr->cnt==parr->len)
	return true;
else
	return false;
}
bool arr_append(struct array *parr,int val)
{
if(is_full(parr))
{
	printf("the array is full\n");
	return false;
}
else
	parr->pBase[(parr->cnt)++]=val;
return true;
}
bool arr_insert(struct array*parr,int pos,int val)//pos是要插入的位置,从0开始
{
if (is_full(parr))
	{
		printf("the array is full\n");
		return false;
	}
else if(pos<0||pos>parr->cnt-1)
	{
	printf("illagal pos\n");
	return false;
	}
else
	{
		for (int i=parr->cnt-1;i>=pos;i--)
			{
				parr->pBase[i+1]=parr->pBase[i];
			}
		parr->pBase[pos]=val;
		(parr->cnt)++;
		return true;
	}
}
bool arr_delete(struct array*parr,int pos,int *pval)
{
if(is_empty(parr))
	{
		printf("the array is empty\n");
		return false;
	}
else if(pos<0||pos>(parr->cnt-1))
{
printf("illage pos\n");
return false;
}
else
{
*pval=parr->pBase[pos];
for(int i=pos;i<=parr->cnt-1;i++)
{
	parr->pBase[i]=parr->pBase[i+1];
}

}
return true;
}
int arr_insersion(struct array*parr)
{
int i=0,j=parr->cnt-1;
while(i<j)
{
parr->pBase[i]=parr->pBase[i]^parr->pBase[j];
parr->pBase[j]=parr->pBase[i]^parr->pBase[j];
parr->pBase[i]=parr->pBase[i]^parr->pBase[j];
i++;
j--;
}
return 0;
}
int arr_sort(struct array*parr)
{
int i=0,j=0;
for(i=0;i<=(parr->cnt-2);i++)
	for(j=i+1;j<=(parr->cnt-1);j++)
	{
		if ((parr->pBase[i])>(parr->pBase[j]))
			{
				parr->pBase[i]=parr->pBase[i]^parr->pBase[j];
				parr->pBase[j]=parr->pBase[i]^parr->pBase[j];
				parr->pBase[i]=parr->pBase[i]^parr->pBase[j];
			}
	}
return 0;
}

call、ret(f)、mul

call、ret、ret及其等效指令

call指令:

1.call 标号          (唯一利用位移跳转的call)

push ip

jmp near ptr 标号

2.call far ptr 标号

push cs

push ip

jmp far ptr 标号

3.call reg16

push ip

jmp reg16

4.call word ptr 内存单元地址

push ip

jmp word ptr 内存单元地址

5.call dword ptr 内存单元地址

push cs

push ip

jmp dword ptr 内存单元地址

 

ret、retf指令:

1.ret:

pop ip

2.retf:

pop ip

pop cs

 

mul指令:

1.两个乘数要么都是8位,要么都是16位

2.8位乘法:一个乘数在al中,另一个在reg8中或内存字节单元中,结果在ax中

3.16位乘法:一个乘数在ax中,另一个在reg16中或内存字单元中,结果高16位在dx中,低16位在ax中

 

注意点:

1.call指令没有短转移

2.mul的乘数不能是立即数,div也是如此